source: josm/trunk/src/org/openstreetmap/josm/gui/util/GuiHelper.java@ 7004

Last change on this file since 7004 was 7004, checked in by Don-vip, 10 years ago

see #8465 - use multi-catch where applicable

  • Property svn:eol-style set to native
File size: 9.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.util;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.BasicStroke;
7import java.awt.Component;
8import java.awt.Container;
9import java.awt.Dialog;
10import java.awt.Dimension;
11import java.awt.Font;
12import java.awt.GraphicsEnvironment;
13import java.awt.Image;
14import java.awt.Stroke;
15import java.awt.Toolkit;
16import java.awt.Window;
17import java.awt.event.ActionListener;
18import java.awt.event.HierarchyEvent;
19import java.awt.event.HierarchyListener;
20import java.awt.image.FilteredImageSource;
21import java.lang.reflect.InvocationTargetException;
22import java.util.Arrays;
23import java.util.List;
24
25import javax.swing.GrayFilter;
26import javax.swing.Icon;
27import javax.swing.ImageIcon;
28import javax.swing.JOptionPane;
29import javax.swing.JScrollPane;
30import javax.swing.SwingUtilities;
31import javax.swing.Timer;
32
33import org.openstreetmap.josm.Main;
34import org.openstreetmap.josm.gui.ExtendedDialog;
35import org.openstreetmap.josm.tools.ImageProvider;
36
37/**
38 * basic gui utils
39 */
40public final class GuiHelper {
41
42 private GuiHelper() {
43 // Hide default constructor for utils classes
44 }
45
46 /**
47 * disable / enable a component and all its child components
48 */
49 public static void setEnabledRec(Container root, boolean enabled) {
50 root.setEnabled(enabled);
51 Component[] children = root.getComponents();
52 for (Component child : children) {
53 if(child instanceof Container) {
54 setEnabledRec((Container) child, enabled);
55 } else {
56 child.setEnabled(enabled);
57 }
58 }
59 }
60
61 public static void executeByMainWorkerInEDT(final Runnable task) {
62 Main.worker.submit(new Runnable() {
63 @Override
64 public void run() {
65 runInEDTAndWait(task);
66 }
67 });
68 }
69
70 public static void runInEDT(Runnable task) {
71 if (SwingUtilities.isEventDispatchThread()) {
72 task.run();
73 } else {
74 SwingUtilities.invokeLater(task);
75 }
76 }
77
78 public static void runInEDTAndWait(Runnable task) {
79 if (SwingUtilities.isEventDispatchThread()) {
80 task.run();
81 } else {
82 try {
83 SwingUtilities.invokeAndWait(task);
84 } catch (InterruptedException | InvocationTargetException e) {
85 Main.error(e);
86 }
87 }
88 }
89
90 /**
91 * @return true if the user wants to cancel, false if they want to continue
92 */
93 public static final boolean warnUser(String title, String content, ImageIcon baseActionIcon, String continueToolTip) {
94 ExtendedDialog dlg = new ExtendedDialog(Main.parent,
95 title, new String[] {tr("Cancel"), tr("Continue")});
96 dlg.setContent(content);
97 dlg.setButtonIcons(new Icon[] {
98 ImageProvider.get("cancel"),
99 ImageProvider.overlay(
100 ImageProvider.get("upload"),
101 new ImageIcon(ImageProvider.get("warning-small").getImage().getScaledInstance(10 , 10, Image.SCALE_SMOOTH)),
102 ImageProvider.OverlayPosition.SOUTHEAST)});
103 dlg.setToolTipTexts(new String[] {
104 tr("Cancel"),
105 continueToolTip});
106 dlg.setIcon(JOptionPane.WARNING_MESSAGE);
107 dlg.setCancelButton(1);
108 return dlg.showDialog().getValue() != 2;
109 }
110
111 /**
112 * Replies the disabled (grayed) version of the specified image.
113 * @param image The image to disable
114 * @return The disabled (grayed) version of the specified image, brightened by 20%.
115 * @since 5484
116 */
117 public static final Image getDisabledImage(Image image) {
118 return Toolkit.getDefaultToolkit().createImage(
119 new FilteredImageSource(image.getSource(), new GrayFilter(true, 20)));
120 }
121
122 /**
123 * Replies the disabled (grayed) version of the specified icon.
124 * @param icon The icon to disable
125 * @return The disabled (grayed) version of the specified icon, brightened by 20%.
126 * @since 5484
127 */
128 public static final ImageIcon getDisabledIcon(ImageIcon icon) {
129 return new ImageIcon(getDisabledImage(icon.getImage()));
130 }
131
132 /**
133 * Attaches a {@code HierarchyListener} to the specified {@code Component} that
134 * will set its parent dialog resizeable. Use it before a call to JOptionPane#showXXXXDialog
135 * to make it resizeable.
136 * @param pane The component that will be displayed
137 * @param minDimension The minimum dimension that will be set for the dialog. Ignored if null
138 * @return {@code pane}
139 * @since 5493
140 */
141 public static final Component prepareResizeableOptionPane(final Component pane, final Dimension minDimension) {
142 if (pane != null) {
143 pane.addHierarchyListener(new HierarchyListener() {
144 @Override
145 public void hierarchyChanged(HierarchyEvent e) {
146 Window window = SwingUtilities.getWindowAncestor(pane);
147 if (window instanceof Dialog) {
148 Dialog dialog = (Dialog)window;
149 if (!dialog.isResizable()) {
150 dialog.setResizable(true);
151 if (minDimension != null) {
152 dialog.setMinimumSize(minDimension);
153 }
154 }
155 }
156 }
157 });
158 }
159 return pane;
160 }
161
162 /**
163 * Schedules a new Timer to be run in the future (once or several times).
164 * @param initialDelay milliseconds for the initial and between-event delay if repeatable
165 * @param actionListener an initial listener; can be null
166 * @param repeats specify false to make the timer stop after sending its first action event
167 * @return The (started) timer.
168 * @since 5735
169 */
170 public static final Timer scheduleTimer(int initialDelay, ActionListener actionListener, boolean repeats) {
171 Timer timer = new Timer(initialDelay, actionListener);
172 timer.setRepeats(repeats);
173 timer.start();
174 return timer;
175 }
176
177 /**
178 * Return s new BasicStroke object with given thickness and style
179 * @param code = 3.5 -> thickness=3.5px; 3.5 10 5 -> thickness=3.5px, dashed: 10px filled + 5px empty
180 * @return stroke for drawing
181 */
182 public static Stroke getCustomizedStroke(String code) {
183 String[] s = code.trim().split("[^\\.0-9]+");
184
185 if (s.length==0) return new BasicStroke();
186 float w;
187 try {
188 w = Float.parseFloat(s[0]);
189 } catch (NumberFormatException ex) {
190 w = 1.0f;
191 }
192 if (s.length>1) {
193 float[] dash= new float[s.length-1];
194 float sumAbs = 0;
195 try {
196 for (int i=0; i<s.length-1; i++) {
197 dash[i] = Float.parseFloat(s[i+1]);
198 sumAbs += Math.abs(dash[i]);
199 }
200 } catch (NumberFormatException ex) {
201 Main.error("Error in stroke preference format: "+code);
202 dash = new float[]{5.0f};
203 }
204 if (sumAbs < 1e-1) {
205 Main.error("Error in stroke dash fomat (all zeros): "+code);
206 return new BasicStroke(w);
207 }
208 // dashed stroke
209 return new BasicStroke(w, BasicStroke.CAP_BUTT,
210 BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f);
211 } else {
212 if (w>1) {
213 // thick stroke
214 return new BasicStroke(w, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
215 } else {
216 // thin stroke
217 return new BasicStroke(w);
218 }
219 }
220 }
221
222 /**
223 * Gets the font used to display JOSM title in about dialog and splash screen.
224 * @return By order or priority, the first font available in local fonts:
225 * 1. Helvetica Bold 20
226 * 2. Calibri Bold 23
227 * 3. Arial Bold 20
228 * 4. SansSerif Bold 20
229 * @since 5797
230 */
231 public static Font getTitleFont() {
232 List<String> fonts = Arrays.asList(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames());
233 // Helvetica is the preferred choice but is not available by default on Windows
234 // (https://www.microsoft.com/typography/fonts/product.aspx?pid=161)
235 if (fonts.contains("Helvetica")) {
236 return new Font("Helvetica", Font.BOLD, 20);
237 // Calibri is the default Windows font since Windows Vista but is not available on older versions of Windows, where Arial is preferred
238 } else if (fonts.contains("Calibri")) {
239 return new Font("Calibri", Font.BOLD, 23);
240 } else if (fonts.contains("Arial")) {
241 return new Font("Arial", Font.BOLD, 20);
242 // No luck, nothing found, fallback to one of the 5 fonts provided with Java (Serif, SansSerif, Monospaced, Dialog, and DialogInput)
243 } else {
244 return new Font("SansSerif", Font.BOLD, 20);
245 }
246 }
247
248 /**
249 * Embeds the given component into a new vertical-only scrollable {@code JScrollPane}.
250 * @param panel The component to embed
251 * @return the vertical scrollable {@code JScrollPane}
252 * @since 6666
253 */
254 public static JScrollPane embedInVerticalScrollPane(Component panel) {
255 return new JScrollPane(panel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
256 }
257}
Note: See TracBrowser for help on using the repository browser.