1 package fr.ifremer.quadrige2.ui.swing.common;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 import jaxx.runtime.JAXXBinding;
28 import jaxx.runtime.JAXXObject;
29 import jaxx.runtime.JAXXUtil;
30 import jaxx.runtime.SwingUtil;
31 import org.apache.commons.collections4.CollectionUtils;
32 import org.apache.commons.io.IOUtils;
33 import org.apache.commons.lang3.StringEscapeUtils;
34 import org.apache.commons.lang3.StringUtils;
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 import org.jdesktop.beans.AbstractBean;
38 import org.nuiton.jaxx.application.ApplicationBusinessException;
39
40 import javax.swing.*;
41 import javax.swing.text.JTextComponent;
42 import java.awt.*;
43 import java.awt.image.BufferedImage;
44 import java.beans.PropertyChangeListener;
45 import java.io.BufferedReader;
46 import java.io.IOException;
47 import java.io.InputStream;
48 import java.io.StringReader;
49 import java.net.MalformedURLException;
50 import java.net.URL;
51 import java.net.URLConnection;
52 import java.text.DecimalFormat;
53 import java.text.DecimalFormatSymbols;
54 import java.util.Calendar;
55 import java.util.Collection;
56 import java.util.Date;
57 import java.util.List;
58
59 import static org.nuiton.i18n.I18n.t;
60
61
62
63
64 public class ApplicationUIUtil extends org.nuiton.jaxx.application.swing.util.ApplicationUIUtil {
65
66 private static final DecimalFormatSymbols SYMBOLS = new DecimalFormatSymbols();
67
68 private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat();
69
70 private static final Date DEFAULT_TWO_DIGIT_YEAR_START;
71
72 static {
73 SYMBOLS.setDecimalSeparator('.');
74 SYMBOLS.setGroupingSeparator(' ');
75
76 DECIMAL_FORMAT.setDecimalFormatSymbols(SYMBOLS);
77 DECIMAL_FORMAT.setGroupingUsed(false);
78
79 Calendar calendar = Calendar.getInstance();
80 calendar.set(2000, Calendar.JANUARY, 1, 0, 0);
81
82 DEFAULT_TWO_DIGIT_YEAR_START = calendar.getTime();
83 }
84
85
86
87
88 private static final Log LOG = LogFactory.getLog(ApplicationUIUtil.class);
89
90
91
92
93 protected ApplicationUIUtil() {
94 }
95
96
97
98
99
100
101
102 public static void setParentUI(JAXXObject ui, ApplicationUI<?, ?> parentUI) {
103 JAXXUtil.initContext(ui, parentUI);
104 setApplicationContext(ui, parentUI.getHandler() != null ? parentUI.getHandler().getContext() : ApplicationUIContext.getInstance());
105 }
106
107
108
109
110
111
112
113 public static ApplicationUI<?, ?> getParentUI(ApplicationUI<?, ?> ui) {
114 return ui.getContextValue(ApplicationUI.class, JAXXUtil.PARENT);
115 }
116
117
118
119
120
121
122
123
124
125 public static void tryToConnectToUpdateUrl(String urlAsString,
126 String badUrlFormatI18nKey,
127 String notReachI18nKey,
128 String notFoundI18nKey) {
129 URL url;
130
131 try {
132 url = new URL(urlAsString);
133 } catch (MalformedURLException e) {
134 if (LOG.isDebugEnabled()) {
135 LOG.debug("Bad url syntax at " + urlAsString, e);
136 }
137 throw new ApplicationBusinessException(t(badUrlFormatI18nKey, urlAsString));
138 }
139
140 URLConnection urlConnection;
141
142 try {
143 urlConnection = url.openConnection();
144 urlConnection.setConnectTimeout(10000);
145 urlConnection.connect();
146 } catch (Exception e) {
147 if (LOG.isDebugEnabled()) {
148 LOG.debug("Could not connect to " + urlAsString, e);
149 }
150 throw new ApplicationBusinessException(t(notReachI18nKey, urlAsString));
151 }
152
153
154 try {
155 urlConnection.setReadTimeout(1000);
156 InputStream inputStream = null;
157 try {
158 inputStream = urlConnection.getInputStream();
159 } finally {
160 IOUtils.closeQuietly(inputStream);
161 }
162 } catch (Exception e) {
163 if (LOG.isDebugEnabled()) {
164 LOG.debug("Could not found file at to " + urlAsString, e);
165 }
166 throw new ApplicationBusinessException(t(notFoundI18nKey, urlAsString));
167 }
168 }
169
170
171
172
173
174
175 public static DecimalFormatSymbols getDecimalFormatSymbols() {
176 return SYMBOLS;
177 }
178
179
180
181
182
183
184
185
186 public static DecimalFormat getDecimalFormat(int minDecimal, int maxDecimal) {
187 DECIMAL_FORMAT.setMinimumFractionDigits(minDecimal);
188 DECIMAL_FORMAT.setMaximumFractionDigits(maxDecimal);
189 return DECIMAL_FORMAT;
190 }
191
192 private static final String HTML_BEGIN = "<html>";
193 private static final String HTML_END = "</html>";
194 private static final String HTML_PATTERN = HTML_BEGIN + "%s" + HTML_END;
195 private static final String HTML_BR = "<br>";
196 private static final String HTML_BR2 = "<br/>";
197 private static final String HTML_LIST_PATTERN = "<ul>%s</ul>";
198 private static final String HTML_LIST_ITEM_PATTERN = "<li>%s</li>";
199 private static final String HTML_ITALIC_PATTERN = HTML_BEGIN + "<i>%s</i>" + HTML_END;
200
201
202
203
204
205
206
207 public static boolean isHtmlString(String text) {
208 if (StringUtils.isBlank(text)) {
209 return false;
210 }
211 String s = StringUtils.deleteWhitespace(text);
212 return s.startsWith(HTML_BEGIN) && s.endsWith(HTML_END);
213 }
214
215
216
217
218
219
220
221 public static String getHtmlString(String text) {
222
223 if (StringUtils.isBlank(text)) {
224 return HTML_BEGIN + HTML_END;
225 } else if (isHtmlString(text)) {
226 return text;
227 }
228
229 return String.format(HTML_PATTERN, formatHtmlText(text));
230 }
231
232 public static String getHtmlItalicText(String text) {
233
234 if (StringUtils.isBlank(text)) {
235 return HTML_BEGIN + HTML_END;
236 } else if (isHtmlString(text)) {
237 return getHtmlItalicText(removeHtmlTags(text));
238 }
239
240 return String.format(HTML_ITALIC_PATTERN, text);
241 }
242
243 private static String formatHtmlText(String text) {
244
245 BufferedReader st = new BufferedReader(new StringReader(text));
246 StringBuilder buf = new StringBuilder();
247
248 try {
249 String str;
250 while ((str = st.readLine()) != null) {
251
252 if (str.equalsIgnoreCase(HTML_BR2)) {
253 str = HTML_BR;
254 buf.append(str);
255 } else {
256 buf.append(escapeHtmlString(str));
257 }
258
259 if (!str.equalsIgnoreCase(HTML_BR)) {
260 buf.append(HTML_BR);
261 }
262
263 }
264 } catch (IOException e) {
265
266 }
267
268 return buf.toString();
269 }
270
271 private static String escapeHtmlString(String str) {
272 boolean containsHTML = str.matches(".*<[^>]+>.*");
273 return containsHTML ? str : StringEscapeUtils.escapeHtml4(str);
274 }
275
276
277
278
279
280
281
282 public static String getHtmlString(Collection<String> strings) {
283 if (CollectionUtils.isEmpty(strings)) {
284 return getHtmlString("");
285 }
286 return String.format(HTML_PATTERN, formatHtmlList(strings));
287 }
288
289
290
291
292
293
294
295 public static String formatHtmlList(Collection<String> strings) {
296 String result = "";
297 for (String string : strings) {
298 result += String.format(HTML_LIST_ITEM_PATTERN, string);
299 }
300 return String.format(HTML_LIST_PATTERN, result);
301 }
302
303
304
305
306
307
308
309
310 public static String getHtmlString(String text, Collection<String> strings) {
311 if (CollectionUtils.isEmpty(strings)) {
312 return getHtmlString(text);
313 }
314 String result = "";
315 for (String string : strings) {
316 if (StringUtils.isNotBlank(string)) {
317 result += String.format(HTML_LIST_ITEM_PATTERN, formatHtmlText(string));
318 }
319 }
320 result = (text != null ? formatHtmlText(text) : "") + String.format(HTML_LIST_PATTERN, result);
321 return String.format(HTML_PATTERN, result);
322 }
323
324
325
326
327
328
329
330 public static String removeHtmlTags(String htmlString) {
331 String result = htmlString;
332
333 if (result.startsWith(HTML_BEGIN)) {
334 result = result.substring(HTML_BEGIN.length());
335 }
336 if (result.endsWith(HTML_END)) {
337 result = result.substring(0, result.length() - HTML_BEGIN.length() - 1);
338 }
339
340
341 result = result.replaceAll(HTML_BR, "").replaceAll(HTML_BR2, "");
342
343
344 result = result.replaceAll("<strong>", "").replaceAll("<.strong>", "");
345 result = result.replaceAll("<li>", "").replaceAll("<.li>", "");
346 result = result.replaceAll("<ul>", "").replaceAll("<.ul>", "");
347
348 return StringEscapeUtils.unescapeHtml4(result);
349 }
350
351
352
353
354
355
356
357 public static void setComponentLocationOnScreen(Component component, Point point) {
358
359 if (component == null || point == null) {
360 return;
361 }
362
363 Rectangle screenBounds = new Rectangle();
364 GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices();
365 for (GraphicsDevice device : devices) {
366 screenBounds = screenBounds.union(device.getDefaultConfiguration().getBounds());
367 }
368
369 if (point.x < screenBounds.x) {
370 point.x = 0;
371 } else if (point.x + component.getWidth() > screenBounds.width) {
372 point.x = screenBounds.width - component.getWidth();
373 }
374
375 if (point.y < screenBounds.y) {
376 point.y = 0;
377 } else if (point.y + component.getHeight() > screenBounds.height) {
378 point.y = screenBounds.height - component.getHeight();
379 }
380
381 component.setLocation(point);
382 }
383
384
385
386
387
388
389
390 public static void setComponentTreeBackground(Component component, Color color) {
391
392 if (component instanceof JTable
393 || component instanceof JTextComponent
394 || component instanceof JComboBox
395 || component instanceof JButton
396 ) {
397 return;
398 }
399
400 if (component instanceof JList && component.isEnabled()) {
401 return;
402 }
403
404 component.setBackground(color);
405
406 if (component instanceof Container) {
407 Container container = (Container) component;
408 if (container.getComponents() != null) {
409 for (Component child : container.getComponents()) {
410 setComponentTreeBackground(child, color);
411 }
412 }
413 }
414 }
415
416
417
418
419
420
421
422 public static void setChildrenLabelForeground(Container container, Color color) {
423
424 if (container.getComponents() != null) {
425 for (Component child : container.getComponents()) {
426
427 if (child instanceof JLabel) {
428 child.setForeground(color);
429 } else if (child instanceof Container) {
430 setChildrenLabelForeground((Container) child, color);
431 }
432 }
433 }
434 }
435
436
437
438
439
440
441 public static void destroy(ApplicationUI ui) {
442
443 removeBindings(ui);
444
445 if (ui.getModel() instanceof AbstractBean && !(ui.getModel() instanceof ApplicationUIContext)) {
446 removeListeners((AbstractBean) ui.getModel());
447 }
448 if (ui instanceof Component) {
449 removeListeners((Component) ui);
450 }
451 if (ui instanceof Container) {
452 destroyChildren((Container) ui);
453 }
454 }
455
456 private static void destroyChildren(Container container) {
457
458 for (Component child : container.getComponents()) {
459 if (child instanceof Container) {
460 destroyChildren((Container) child);
461 }
462 if (child instanceof ApplicationUI) {
463 ApplicationUI childUI = (ApplicationUI) child;
464 childUI.getHandler().onCloseUI();
465 destroy(childUI);
466 }
467 }
468 }
469
470
471
472
473
474
475 public static void removeListeners(AbstractBean bean) {
476 PropertyChangeListener[] listeners = bean.getPropertyChangeListeners();
477 for (PropertyChangeListener l : listeners) {
478 bean.removePropertyChangeListener(l);
479 }
480 }
481
482
483
484
485
486
487 public static void removeListeners(Component component) {
488 PropertyChangeListener[] listeners = component.getPropertyChangeListeners();
489 for (PropertyChangeListener l : listeners) {
490 component.removePropertyChangeListener(l);
491 }
492 }
493
494
495
496
497
498
499 public static void removeBindings(JAXXObject jaxxObject) {
500 JAXXBinding[] bindings = jaxxObject.getDataBindings();
501 for (JAXXBinding binding : bindings) {
502 SwingUtil.removeDataBinding(jaxxObject, binding.getId());
503 }
504 }
505
506
507
508
509
510
511 public static Date getDefault2DigitYearStart() {
512 return DEFAULT_TWO_DIGIT_YEAR_START;
513 }
514
515 public static Cursor getCustomCursor(String actionIconName) {
516
517 Toolkit toolkit = Toolkit.getDefaultToolkit();
518
519 ImageIcon imageIcon = SwingUtil.createActionIcon(actionIconName);
520
521 Dimension bestDimension = toolkit.getBestCursorSize(imageIcon.getIconWidth(), imageIcon.getIconHeight());
522 if (bestDimension.getWidth() == 0) {
523 return Cursor.getDefaultCursor();
524 }
525
526 BufferedImage cursorImage = new BufferedImage(bestDimension.width, bestDimension.height, BufferedImage.TYPE_INT_ARGB);
527 Graphics2D graphics2D = cursorImage.createGraphics();
528 graphics2D.drawImage(imageIcon.getImage(),
529 (bestDimension.width - imageIcon.getIconWidth()) / 2,
530 (bestDimension.height - imageIcon.getIconHeight()) / 2,
531 imageIcon.getIconWidth(),
532 imageIcon.getIconHeight(),
533 null);
534
535 return toolkit.createCustomCursor(
536 cursorImage,
537 new Point(bestDimension.width / 2, bestDimension.height / 2),
538 actionIconName);
539 }
540
541 }