View Javadoc
1   package fr.ifremer.quadrige3.ui.swing;
2   
3   /*
4    * #%L
5    * Reef DB :: UI
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2014 - 2015 Ifremer
10   * %%
11   * This program is free software: you can redistribute it and/or modify
12   * it under the terms of the GNU Affero General Public License as published by
13   * the Free Software Foundation, either version 3 of the License, or
14   * (at your option) any later version.
15   * 
16   * This program is distributed in the hope that it will be useful,
17   * but WITHOUT ANY WARRANTY; without even the implied warranty of
18   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19   * GNU General Public License for more details.
20   * 
21   * You should have received a copy of the GNU Affero General Public License
22   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23   * #L%
24   */
25  
26  import com.google.common.collect.Lists;
27  import fr.ifremer.quadrige3.core.dao.technical.Assert;
28  import fr.ifremer.quadrige3.core.exception.QuadrigeBusinessException;
29  import org.apache.commons.lang3.ArrayUtils;
30  import org.apache.commons.lang3.StringUtils;
31  import org.jdesktop.swingx.JXErrorPane;
32  import org.jdesktop.swingx.error.ErrorInfo;
33  import org.jdesktop.swingx.plaf.basic.BasicErrorPaneUI;
34  import org.nuiton.jaxx.application.ApplicationBusinessException;
35  import org.nuiton.jaxx.application.swing.ApplicationUIContext;
36  import org.nuiton.jaxx.application.swing.util.ApplicationErrorHelper;
37  
38  import javax.swing.*;
39  import javax.swing.text.html.HTMLEditorKit;
40  import java.awt.Component;
41  import java.awt.Dialog;
42  import java.awt.Dimension;
43  import java.util.List;
44  
45  import static org.nuiton.i18n.I18n.t;
46  
47  /**
48   * Helper to display errors, warnings and questions
49   * <p/>
50   * used as ErrorReporter
51   *
52   * @author Ludovic Pecquot <ludovic.pecquot@e-is.pro>
53   */
54  public class DialogHelper extends ApplicationErrorHelper {
55  
56      /*
57       * Custom dialog option types
58       */
59      public static final int SAVE_NO_SAVE_CANCEL_OPTION = 10;
60      public static final int NO_SAVE_CANCEL_OPTION = 11;
61      public static final int DELETE_CANCEL_OPTION = 12;
62      public static final int DELETE_INVALID_CANCEL_OPTION = 13;
63      public static final int RESET_CANCEL_OPTION = 14;
64      public static final int OVERWRITE_FILE_CANCEL_OPTION = 15;
65      public static final int UPDATE_DB_OPTION = 16;
66      public static final int LOAD_DB_CANCEL_OPTION = 17;
67      public static final int CUSTOM_OPTION = 100;
68  
69      public static final int QUESTION_MESSAGE_WITH_LARGE_TEXT = 10;
70  
71      /**
72       * <p>Constructor for DialogHelper.</p>
73       *
74       * @param context a {@link ApplicationUIContext} object.
75       */
76      public DialogHelper(ApplicationUIContext context) {
77          super(context);
78      }
79  
80      /**
81       * {@inheritDoc}
82       */
83      @Override
84      public void reportError(ErrorInfo info) throws NullPointerException {
85          showErrorDialog(info.getBasicErrorMessage(), info.getErrorException());
86      }
87  
88      /**
89       * {@inheritDoc}
90       */
91      @Override
92      public void showErrorDialog(String message) {
93          showErrorDialog(message, null, null);
94      }
95  
96      /**
97       * <p>showErrorDialog.</p>
98       *
99       * @param message a {@link java.lang.String} object.
100      * @param title   a {@link java.lang.String} object.
101      */
102     public void showErrorDialog(String message, String title) {
103         showErrorDialog(message, null, null, title);
104     }
105 
106     /**
107      * <p>showErrorDialog.</p>
108      *
109      * @param parent  a {@link java.awt.Component} object.
110      * @param message a {@link java.lang.String} object.
111      * @param title   a {@link java.lang.String} object.
112      */
113     public void showErrorDialog(Component parent, String message, String title) {
114         showErrorDialog(parent, message, null, null, title);
115     }
116 
117     /**
118      * {@inheritDoc}
119      * <p>
120      * Display a user friendly error frame.
121      */
122     @Override
123     public void showErrorDialog(String message, Throwable cause) {
124 
125         if (cause == null) {
126             showErrorDialog(message, null, null);
127         } else if (cause instanceof ApplicationBusinessException || cause instanceof QuadrigeBusinessException) {
128             showErrorDialog(cause.getMessage(), null, null);
129         } else {
130 
131             JXErrorPane pane = new JXErrorPane();
132             pane.setUI(new ModalErrorPanelUI());
133             ErrorInfo info = new ErrorInfo(t("quadrige3.error.technical.error"),
134                     t("quadrige3.error.technical.error.htmlMessage", message), null, null,
135                     cause, null, null);
136             pane.setErrorInfo(info);
137             pane.setErrorReporter(this);
138             JXErrorPane.showDialog(context.getMainUI(), pane);
139         }
140     }
141 
142     /**
143      * <p>showErrorDialog.</p>
144      *
145      * @param topMessage    a {@link java.lang.String} object.
146      * @param longMessage   a {@link java.lang.String} object.
147      * @param bottomMessage a {@link java.lang.String} object.
148      */
149     public void showErrorDialog(String topMessage, String longMessage, String bottomMessage) {
150         showErrorDialog(topMessage, longMessage, bottomMessage, t("quadrige3.error.business.error"));
151     }
152 
153     /**
154      * <p>showErrorDialog.</p>
155      *
156      * @param topMessage    a {@link java.lang.String} object.
157      * @param longMessage   a {@link java.lang.String} object.
158      * @param bottomMessage a {@link java.lang.String} object.
159      * @param title         a {@link java.lang.String} object.
160      */
161     public void showErrorDialog(String topMessage, String longMessage, String bottomMessage, String title) {
162         showOptionDialog(null, topMessage, longMessage, bottomMessage, title, JOptionPane.ERROR_MESSAGE, JOptionPane.DEFAULT_OPTION);
163     }
164 
165     /**
166      * <p>showErrorDialog.</p>
167      *
168      * @param parent        a {@link java.awt.Component} object.
169      * @param topMessage    a {@link java.lang.String} object.
170      * @param longMessage   a {@link java.lang.String} object.
171      * @param bottomMessage a {@link java.lang.String} object.
172      * @param title         a {@link java.lang.String} object.
173      */
174     public void showErrorDialog(Component parent, String topMessage, String longMessage, String bottomMessage, String title) {
175         showOptionDialog(parent, topMessage, longMessage, bottomMessage, title, JOptionPane.ERROR_MESSAGE, JOptionPane.DEFAULT_OPTION);
176     }
177 
178     /**
179      * {@inheritDoc}
180      */
181     @Override
182     public void showWarningDialog(String message) {
183         showWarningDialog(message, t("quadrige3.error.business.warning"));
184     }
185 
186     /**
187      * <p>showWarningDialog.</p>
188      *
189      * @param message a {@link java.lang.String} object.
190      * @param title   a {@link java.lang.String} object.
191      */
192     public void showWarningDialog(String message, String title) {
193         showWarningDialog(message, null, null, title);
194     }
195 
196     /**
197      * <p>showWarningDialog.</p>
198      *
199      * @param topMessage    a {@link java.lang.String} object.
200      * @param longMessage   a {@link java.lang.String} object.
201      * @param bottomMessage a {@link java.lang.String} object.
202      */
203     public void showWarningDialog(String topMessage, String longMessage, String bottomMessage) {
204         showWarningDialog(topMessage, longMessage, bottomMessage, t("quadrige3.error.business.warning"));
205     }
206 
207     /**
208      * <p>showWarningDialog.</p>
209      *
210      * @param topMessage    a {@link java.lang.String} object.
211      * @param longMessage   a {@link java.lang.String} object.
212      * @param bottomMessage a {@link java.lang.String} object.
213      * @param title         a {@link java.lang.String} object.
214      */
215     public void showWarningDialog(String topMessage, String longMessage, String bottomMessage, String title) {
216         showOptionDialog(null, topMessage, longMessage, bottomMessage, title, JOptionPane.WARNING_MESSAGE, JOptionPane.DEFAULT_OPTION);
217     }
218 
219     /**
220      * <p>showMessageDialog.</p>
221      *
222      * @param message a {@link java.lang.String} object.
223      */
224     public void showMessageDialog(String message) {
225         showMessageDialog(message, null, null, "");
226     }
227 
228     /**
229      * <p>showMessageDialog.</p>
230      *
231      * @param message a {@link java.lang.String} object.
232      * @param title   a {@link java.lang.String} object.
233      */
234     public void showMessageDialog(String message, String title) {
235         showMessageDialog(message, null, null, title);
236     }
237 
238     /**
239      * <p>showMessageDialog.</p>
240      *
241      * @param message a {@link java.lang.String} object.
242      * @param title   a {@link java.lang.String} object.
243      * @param optionType a int
244      */
245     public void showMessageDialog(String message, String title, int optionType) {
246         showMessageDialog(message, null, null, title, optionType);
247     }
248 
249     /**
250      * <p>showMessageDialog.</p>
251      *
252      * @param topMessage    a {@link java.lang.String} object.
253      * @param longMessage   a {@link java.lang.String} object.
254      * @param bottomMessage a {@link java.lang.String} object.
255      * @param title         a {@link java.lang.String} object.
256      */
257     public void showMessageDialog(String topMessage, String longMessage, String bottomMessage, String title) {
258         showMessageDialog(topMessage, longMessage, bottomMessage, title, JOptionPane.DEFAULT_OPTION);
259     }
260 
261     /**
262      * <p>showMessageDialog.</p>
263      *
264      * @param topMessage    a {@link java.lang.String} object.
265      * @param longMessage   a {@link java.lang.String} object.
266      * @param bottomMessage a {@link java.lang.String} object.
267      * @param title         a {@link java.lang.String} object.
268      * @param optionType    a int.
269      */
270     public void showMessageDialog(String topMessage, String longMessage, String bottomMessage, String title, int optionType) {
271         showOptionDialog(null, topMessage, longMessage, bottomMessage, title, JOptionPane.INFORMATION_MESSAGE, optionType);
272     }
273 
274     /**
275      * <p>showConfirmDialog.</p>
276      *
277      * @param message    a {@link java.lang.String} object.
278      * @param optionType a int.
279      * @return a int.
280      */
281     public int showConfirmDialog(String message, int optionType) {
282         return showConfirmDialog(message, t("quadrige3.error.business.warning"), optionType);
283     }
284 
285     /**
286      * <p>showConfirmDialog.</p>
287      *
288      * @param parent     a {@link java.awt.Component} object.
289      * @param message    a {@link java.lang.String} object.
290      * @param optionType a int.
291      * @return a int.
292      */
293     public int showConfirmDialog(Component parent, String message, int optionType) {
294         return showConfirmDialog(parent, message, t("quadrige3.error.business.warning"), optionType);
295     }
296 
297     /**
298      * <p>showConfirmDialog.</p>
299      *
300      * @param message    a {@link java.lang.String} object.
301      * @param title      a {@link java.lang.String} object.
302      * @param optionType a int.
303      * @return a int.
304      */
305     public int showConfirmDialog(String message, String title, int optionType) {
306         return showConfirmDialog(message, null, null, title, optionType);
307     }
308 
309     /**
310      * <p>showConfirmDialog.</p>
311      *
312      * @param parent     a {@link java.awt.Component} object.
313      * @param message    a {@link java.lang.String} object.
314      * @param title      a {@link java.lang.String} object.
315      * @param optionType a int.
316      * @return a int.
317      */
318     public int showConfirmDialog(Component parent, String message, String title, int optionType) {
319         return showConfirmDialog(parent, message, null, null, title, optionType);
320     }
321 
322     /**
323      * <p>showConfirmDialog.</p>
324      *
325      * @param topMessage    a {@link java.lang.String} object.
326      * @param longMessage   a {@link java.lang.String} object.
327      * @param bottomMessage a {@link java.lang.String} object.
328      * @param optionType    a int.
329      * @return a int.
330      */
331     public int showConfirmDialog(String topMessage, String longMessage, String bottomMessage, int optionType) {
332         return showConfirmDialog(topMessage, longMessage, bottomMessage, t("quadrige3.error.business.question"), optionType);
333     }
334 
335     /**
336      * <p>showConfirmDialog.</p>
337      *
338      * @param topMessage    a {@link java.lang.String} object.
339      * @param longMessage   a {@link java.lang.String} object.
340      * @param bottomMessage a {@link java.lang.String} object.
341      * @param title         a {@link java.lang.String} object.
342      * @param optionType    a int.
343      * @return a int.
344      */
345     public int showConfirmDialog(String topMessage, String longMessage, String bottomMessage, String title, int optionType) {
346         return showOptionDialog(null, topMessage, longMessage, bottomMessage, title, JOptionPane.QUESTION_MESSAGE, optionType);
347     }
348 
349     /**
350      * <p>showConfirmDialog.</p>
351      *
352      * @param parent        a {@link java.awt.Component} object.
353      * @param topMessage    a {@link java.lang.String} object.
354      * @param longMessage   a {@link java.lang.String} object.
355      * @param bottomMessage a {@link java.lang.String} object.
356      * @param title         a {@link java.lang.String} object.
357      * @param optionType    a int.
358      * @return a int.
359      */
360     public int showConfirmDialog(Component parent, String topMessage, String longMessage, String bottomMessage, String title, int optionType) {
361         return showOptionDialog(parent, topMessage, longMessage, bottomMessage, title, JOptionPane.QUESTION_MESSAGE, optionType);
362     }
363 
364     /**
365      * <p>showOptionDialog.</p>
366      *
367      * @param parent        a {@link Component} object.
368      * @param topMessage    a {@link String} object.
369      * @param longMessage   a {@link String} object.
370      * @param bottomMessage a {@link String} object.
371      * @param title         a {@link String} object.
372      * @param messageType   a int.
373      * @param optionType    a int.
374      * @param customOptions custom options
375      * @return a int.
376      */
377     public int showOptionDialog(Component parent, String topMessage, String longMessage, String bottomMessage, String title, int messageType, int optionType, String... customOptions) {
378 
379         List<Object> messageElements = Lists.newArrayList();
380         if (StringUtils.isNotBlank(topMessage)) {
381             messageElements.add(ApplicationUIUtil.getHtmlString(topMessage));
382         }
383         if (StringUtils.isNotBlank(longMessage)) {
384             if (ApplicationUIUtil.isHtmlString(longMessage)) {
385                 JTextPane textPane = new JTextPane();
386                 textPane.setEditorKit(new HTMLEditorKit());
387                 textPane.setText(longMessage);
388 //                if (messageType == QUESTION_MESSAGE_WITH_LARGE_TEXT) {
389 //                    textPane.setPreferredSize(new Dimension(500, 800));
390 //                } else {
391                     textPane.setPreferredSize(new Dimension(200, 200));
392 //                }
393                 JScrollPane scrollPane = new JScrollPane(textPane);
394                 scrollPane.setBorder(null);
395                 messageElements.add(scrollPane);
396             } else {
397                 JTextArea textArea = new JTextArea(6, 25);
398                 textArea.setEditable(false);
399                 textArea.setText(longMessage);
400                 JScrollPane scrollPane = new JScrollPane(textArea);
401                 messageElements.add(scrollPane);
402             }
403         }
404         if (StringUtils.isNotBlank(bottomMessage)) {
405             messageElements.add(ApplicationUIUtil.getHtmlString(bottomMessage));
406         }
407         Object messageObject[] = messageElements.toArray();
408 
409         Dimension size = null;
410         if (messageType == QUESTION_MESSAGE_WITH_LARGE_TEXT) {
411             messageType = JOptionPane.QUESTION_MESSAGE;
412             size = new Dimension(800, 800);
413         }
414 
415         return showOptionDialog(parent, messageObject, title, messageType, optionType, size, customOptions);
416     }
417 
418     /**
419      * <p>showOptionDialog.</p>
420      *
421      * @param parent        a {@link Component} object.
422      * @param messageObject a {@link Object} object.
423      * @param title         a {@link String} object.
424      * @param messageType   a int.
425      * @param optionType    a int.
426      * @param customOptions custom options
427      * @return a int.
428      */
429     public int showOptionDialog(Component parent, Object messageObject, String title, int messageType, int optionType, String... customOptions) {
430         return showOptionDialog(parent, messageObject, title, messageType, optionType, (Dimension) null, customOptions);
431     }
432 
433     /**
434      * <p>showOptionDialog.</p>
435      *
436      * @param parent        a {@link Component} object.
437      * @param messageObject a {@link Object} object.
438      * @param title         a {@link String} object.
439      * @param messageType   a int.
440      * @param optionType    a int.
441      * @param size the desired size of the dialog
442      * @param customOptions custom options
443      * @return a int.
444      */
445     public int showOptionDialog(Component parent, Object messageObject, String title, int messageType, int optionType, Dimension size, String... customOptions) {
446 
447         Object[] options = null;
448         Object defaultOption = null;
449         switch (optionType) {
450             case SAVE_NO_SAVE_CANCEL_OPTION:
451                 optionType = JOptionPane.YES_NO_CANCEL_OPTION;
452                 options = new Object[]{t("quadrige3.common.save.quit"), t("quadrige3.common.no.save.quit"), t("quadrige3.common.cancel")};
453                 defaultOption = options[2];
454                 break;
455             case NO_SAVE_CANCEL_OPTION:
456                 optionType = JOptionPane.OK_CANCEL_OPTION;
457                 options = new Object[]{t("quadrige3.common.no.save.quit"), t("quadrige3.common.cancel")};
458                 defaultOption = options[1];
459                 break;
460             case DELETE_CANCEL_OPTION:
461                 optionType = JOptionPane.OK_CANCEL_OPTION;
462                 options = new Object[]{t("quadrige3.common.delete"), t("quadrige3.common.cancel")};
463                 defaultOption = options[1];
464                 break;
465             case RESET_CANCEL_OPTION:
466                 optionType = JOptionPane.OK_CANCEL_OPTION;
467                 options = new Object[]{t("quadrige3.common.reset"), t("quadrige3.common.cancel")};
468                 defaultOption = options[1];
469                 break;
470             case DELETE_INVALID_CANCEL_OPTION:
471                 optionType = JOptionPane.OK_CANCEL_OPTION;
472                 options = new Object[]{t("quadrige3.common.delete.invalid.quit"), t("quadrige3.common.cancel")};
473                 defaultOption = options[1];
474                 break;
475             case OVERWRITE_FILE_CANCEL_OPTION:
476                 optionType = JOptionPane.OK_CANCEL_OPTION;
477                 options = new Object[]{t("quadrige3.common.file.overwrite"), t("quadrige3.common.cancel")};
478                 defaultOption = options[1];
479                 break;
480             case UPDATE_DB_OPTION:
481                 optionType = JOptionPane.OK_OPTION;
482                 options = new Object[]{t("quadrige3.common.db.update")};
483                 defaultOption = options[0];
484                 break;
485             case LOAD_DB_CANCEL_OPTION:
486                 optionType = JOptionPane.OK_CANCEL_OPTION;
487                 options = new Object[]{t("quadrige3.common.db.load"), t("quadrige3.common.cancel")};
488                 defaultOption = options[1];
489                 break;
490             case CUSTOM_OPTION:
491                 Assert.isTrue(ArrayUtils.getLength(customOptions) > 0 && ArrayUtils.getLength(customOptions) <= 3);
492                 int optionsSize = customOptions.length;
493                 optionType = optionsSize == 1 ? JOptionPane.OK_OPTION : optionsSize == 2 ? JOptionPane.OK_CANCEL_OPTION : JOptionPane.YES_NO_CANCEL_OPTION;
494                 options = customOptions;
495                 defaultOption = options[optionsSize - 1];
496                 break;
497         }
498 
499         JOptionPane pane = new JOptionPane(messageObject, messageType, optionType, null, options, defaultOption);
500         if (parent == null) {
501             parent = context.getMainUI();
502         }
503         JDialog dialog = pane.createDialog(parent, title);
504         dialog.setModalityType(Dialog.ModalityType.TOOLKIT_MODAL);
505 
506         if (size != null) {
507             dialog.setMinimumSize(size);
508             dialog.pack();
509             dialog.setLocationRelativeTo(parent);
510         }
511 
512         dialog.setVisible(true);
513         dialog.dispose();
514 
515         Object selectedValue = pane.getValue();
516         if (selectedValue instanceof Integer) {
517             return ((Integer) selectedValue);
518         } else if (options != null) {
519             return ArrayUtils.indexOf(options, selectedValue);
520         }
521         return JOptionPane.CLOSED_OPTION;
522     }
523 
524     /**
525      * <p>showOptionDialog.</p>
526      *
527      * @param parent       a {@link Component} object.
528      * @param message      a {@link Object} object.
529      * @param title        a {@link String} object.
530      * @param messageType  a int.
531      * @param optionType   a int.
532      * @param options      an array of {@link Object} objects.
533      * @param initialValue a {@link Object} object.
534      * @return a int.
535      */
536     public int showOptionDialog(Component parent, Object message, String title, int messageType, int optionType, Object[] options, Object initialValue) {
537 
538         JOptionPane pane = new JOptionPane(message, messageType,
539                 optionType, null,
540                 options, initialValue);
541 
542         pane.setInitialValue(initialValue);
543 
544         if (parent == null) {
545             parent = context.getMainUI();
546         }
547         JDialog dialog = pane.createDialog(parent, title);
548         dialog.setModalityType(Dialog.ModalityType.TOOLKIT_MODAL);
549 
550         pane.selectInitialValue();
551         dialog.setVisible(true);
552         dialog.dispose();
553 
554         Object selectedValue = pane.getValue();
555 
556         if (selectedValue == null)
557             return JOptionPane.CLOSED_OPTION;
558         if (options == null) {
559             if (selectedValue instanceof Integer)
560                 return (Integer) selectedValue;
561             return JOptionPane.CLOSED_OPTION;
562         }
563         for (int counter = 0, maxCounter = options.length;
564              counter < maxCounter; counter++) {
565             if (options[counter].equals(selectedValue))
566                 return counter;
567         }
568         return JOptionPane.CLOSED_OPTION;
569     }
570 
571     /**
572      * <p>showInputDialog.</p>
573      *
574      * @param parent  a {@link java.awt.Component} object.
575      * @param message a {@link java.lang.String} object.
576      * @param title   a {@link java.lang.String} object.
577      * @return a {@link java.lang.Object} object.
578      */
579     public Object showInputDialog(Component parent, String message, String title) {
580 
581         return showInputDialog(parent, message, title, null, null);
582     }
583 
584     /**
585      * <p>showInputDialog.</p>
586      *
587      * @param parent                a {@link java.awt.Component} object.
588      * @param message               a {@link java.lang.String} object.
589      * @param title                 a {@link java.lang.String} object.
590      * @param selectionValues       an array of {@link java.lang.Object} objects.
591      * @param initialSelectionValue a {@link java.lang.Object} object.
592      * @return a {@link java.lang.Object} object.
593      */
594     public Object showInputDialog(Component parent, String message, String title, Object[] selectionValues, Object initialSelectionValue) {
595 
596         JOptionPane pane = new JOptionPane(message, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, null, null);
597 
598         pane.setWantsInput(true);
599         pane.setSelectionValues(selectionValues);
600         pane.setInitialSelectionValue(initialSelectionValue);
601 
602         if (parent == null) {
603             parent = context.getMainUI();
604         }
605         JDialog dialog = pane.createDialog(parent, title);
606 
607         // Raise the width of the dialog
608         dialog.setSize((int) (dialog.getSize().width * 1.25), dialog.getSize().height);
609 
610         dialog.setModalityType(Dialog.ModalityType.TOOLKIT_MODAL);
611 
612         pane.selectInitialValue();
613         dialog.setVisible(true);
614         dialog.dispose();
615 
616         Object value = pane.getInputValue();
617 
618         if (value == JOptionPane.UNINITIALIZED_VALUE) {
619             return null;
620         }
621         return value;
622 
623     }
624 
625     private class ModalErrorPanelUI extends BasicErrorPaneUI {
626 
627         @Override
628         public JDialog getErrorDialog(Component owner) {
629             JDialog dialog = super.getErrorDialog(owner);
630             dialog.setModalityType(Dialog.ModalityType.TOOLKIT_MODAL);
631             return dialog;
632         }
633 
634     }
635 }