001 // License: GPL. For details, see LICENSE file. 002 package org.openstreetmap.josm.gui.util; 003 004 import static org.openstreetmap.josm.tools.I18n.tr; 005 006 import java.awt.Component; 007 import java.awt.Container; 008 import java.awt.Dialog; 009 import java.awt.Dimension; 010 import java.awt.Image; 011 import java.awt.Toolkit; 012 import java.awt.Window; 013 import java.awt.event.HierarchyEvent; 014 import java.awt.event.HierarchyListener; 015 import java.awt.image.FilteredImageSource; 016 import java.lang.reflect.InvocationTargetException; 017 018 import javax.swing.GrayFilter; 019 import javax.swing.Icon; 020 import javax.swing.ImageIcon; 021 import javax.swing.JOptionPane; 022 import javax.swing.SwingUtilities; 023 024 import org.openstreetmap.josm.Main; 025 import org.openstreetmap.josm.gui.ExtendedDialog; 026 import org.openstreetmap.josm.tools.ImageProvider; 027 028 /** 029 * basic gui utils 030 */ 031 public class GuiHelper { 032 /** 033 * disable / enable a component and all its child components 034 */ 035 public static void setEnabledRec(Container root, boolean enabled) { 036 root.setEnabled(enabled); 037 Component[] children = root.getComponents(); 038 for (Component child : children) { 039 if(child instanceof Container) { 040 setEnabledRec((Container) child, enabled); 041 } else { 042 child.setEnabled(enabled); 043 } 044 } 045 } 046 047 public static void runInEDT(Runnable task) { 048 if (SwingUtilities.isEventDispatchThread()) { 049 task.run(); 050 } else { 051 SwingUtilities.invokeLater(task); 052 } 053 } 054 055 public static void runInEDTAndWait(Runnable task) { 056 if (SwingUtilities.isEventDispatchThread()) { 057 task.run(); 058 } else { 059 try { 060 SwingUtilities.invokeAndWait(task); 061 } catch (InterruptedException e) { 062 e.printStackTrace(); 063 } catch (InvocationTargetException e) { 064 e.printStackTrace(); 065 } 066 } 067 } 068 069 /** 070 * returns true if the user wants to cancel, false if they 071 * want to continue 072 */ 073 public static final boolean warnUser(String title, String content, ImageIcon baseActionIcon, String continueToolTip) { 074 ExtendedDialog dlg = new ExtendedDialog(Main.parent, 075 title, new String[] {tr("Cancel"), tr("Continue")}); 076 dlg.setContent(content); 077 dlg.setButtonIcons(new Icon[] { 078 ImageProvider.get("cancel"), 079 ImageProvider.overlay( 080 ImageProvider.get("upload"), 081 new ImageIcon(ImageProvider.get("warning-small").getImage().getScaledInstance(10 , 10, Image.SCALE_SMOOTH)), 082 ImageProvider.OverlayPosition.SOUTHEAST)}); 083 dlg.setToolTipTexts(new String[] { 084 tr("Cancel"), 085 continueToolTip}); 086 dlg.setIcon(JOptionPane.WARNING_MESSAGE); 087 dlg.setCancelButton(1); 088 return dlg.showDialog().getValue() != 2; 089 } 090 091 /** 092 * Replies the disabled (grayed) version of the specified image. 093 * @param image The image to disable 094 * @return The disabled (grayed) version of the specified image, brightened by 20%. 095 * @since 5484 096 */ 097 public static final Image getDisabledImage(Image image) { 098 return Toolkit.getDefaultToolkit().createImage( 099 new FilteredImageSource(image.getSource(), new GrayFilter(true, 20))); 100 } 101 102 /** 103 * Replies the disabled (grayed) version of the specified icon. 104 * @param icon The icon to disable 105 * @return The disabled (grayed) version of the specified icon, brightened by 20%. 106 * @since 5484 107 */ 108 public static final ImageIcon getDisabledIcon(ImageIcon icon) { 109 return new ImageIcon(getDisabledImage(icon.getImage())); 110 } 111 112 /** 113 * Attaches a {@code HierarchyListener} to the specified {@code Component} that 114 * will set its parent dialog resizeable. Use it before a call to JOptionPane#showXXXXDialog 115 * to make it resizeable. 116 * @param pane The component that will be displayed 117 * @param minDimension The minimum dimension that will be set for the dialog. Ignored if null 118 * @return {@code pane} 119 * @since 5493 120 */ 121 public static final Component prepareResizeableOptionPane(final Component pane, final Dimension minDimension) { 122 if (pane != null) { 123 pane.addHierarchyListener(new HierarchyListener() { 124 public void hierarchyChanged(HierarchyEvent e) { 125 Window window = SwingUtilities.getWindowAncestor(pane); 126 if (window instanceof Dialog) { 127 Dialog dialog = (Dialog)window; 128 if (!dialog.isResizable()) { 129 dialog.setResizable(true); 130 if (minDimension != null) { 131 dialog.setMinimumSize(minDimension); 132 } 133 } 134 } 135 } 136 }); 137 } 138 return pane; 139 } 140 }