View Javadoc
1   package fr.ifremer.quadrige2.ui.swing.common;
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.base.Preconditions;
27  import com.google.common.collect.Lists;
28  import fr.ifremer.quadrige2.core.exception.Quadrige2BusinessException;
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_CANCEL_OPTION = 16;
66      public static final int LOAD_DB_CANCEL_OPTION = 17;
67      public static final int CUSTOM_OPTION = 100;
68  
69      /**
70       * <p>Constructor for DialogHelper.</p>
71       *
72       * @param context a {@link ApplicationUIContext} object.
73       */
74      public DialogHelper(ApplicationUIContext context) {
75          super(context);
76      }
77  
78      /**
79       * {@inheritDoc}
80       */
81      @Override
82      public void reportError(ErrorInfo info) throws NullPointerException {
83          showErrorDialog(info.getBasicErrorMessage(), info.getErrorException());
84      }
85  
86      /**
87       * {@inheritDoc}
88       */
89      @Override
90      public void showErrorDialog(String message) {
91          showErrorDialog(message, null, null);
92      }
93  
94      /**
95       * <p>showErrorDialog.</p>
96       *
97       * @param message a {@link java.lang.String} object.
98       * @param title   a {@link java.lang.String} object.
99       */
100     public void showErrorDialog(String message, String title) {
101         showErrorDialog(message, null, null, title);
102     }
103 
104     /**
105      * <p>showErrorDialog.</p>
106      *
107      * @param parent  a {@link java.awt.Component} object.
108      * @param message a {@link java.lang.String} object.
109      * @param title   a {@link java.lang.String} object.
110      */
111     public void showErrorDialog(Component parent, String message, String title) {
112         showErrorDialog(parent, message, null, null, title);
113     }
114 
115     /**
116      * {@inheritDoc}
117      * <p>
118      * Display a user friendly error frame.
119      */
120     @Override
121     public void showErrorDialog(String message, Throwable cause) {
122 
123         if (cause == null) {
124             showErrorDialog(message, null, null);
125         } else if (cause instanceof ApplicationBusinessException || cause instanceof Quadrige2BusinessException) {
126             showErrorDialog(cause.getMessage(), null, null);
127         } else {
128 
129             JXErrorPane pane = new JXErrorPane();
130             pane.setUI(new ModalErrorPanelUI());
131             ErrorInfo info = new ErrorInfo(t("quadrige2.error.technical.error"),
132                     t("quadrige2.error.technical.error.htmlMessage", message), null, null,
133                     cause, null, null);
134             pane.setErrorInfo(info);
135             pane.setErrorReporter(this);
136             JXErrorPane.showDialog(context.getMainUI(), pane);
137         }
138     }
139 
140     /**
141      * <p>showErrorDialog.</p>
142      *
143      * @param topMessage    a {@link java.lang.String} object.
144      * @param longMessage   a {@link java.lang.String} object.
145      * @param bottomMessage a {@link java.lang.String} object.
146      */
147     public void showErrorDialog(String topMessage, String longMessage, String bottomMessage) {
148         showErrorDialog(topMessage, longMessage, bottomMessage, t("quadrige2.error.business.error"));
149     }
150 
151     /**
152      * <p>showErrorDialog.</p>
153      *
154      * @param topMessage    a {@link java.lang.String} object.
155      * @param longMessage   a {@link java.lang.String} object.
156      * @param bottomMessage a {@link java.lang.String} object.
157      * @param title         a {@link java.lang.String} object.
158      */
159     public void showErrorDialog(String topMessage, String longMessage, String bottomMessage, String title) {
160         showOptionDialog(null, topMessage, longMessage, bottomMessage, title, JOptionPane.ERROR_MESSAGE, JOptionPane.DEFAULT_OPTION);
161     }
162 
163     /**
164      * <p>showErrorDialog.</p>
165      *
166      * @param parent        a {@link java.awt.Component} object.
167      * @param topMessage    a {@link java.lang.String} object.
168      * @param longMessage   a {@link java.lang.String} object.
169      * @param bottomMessage a {@link java.lang.String} object.
170      * @param title         a {@link java.lang.String} object.
171      */
172     public void showErrorDialog(Component parent, String topMessage, String longMessage, String bottomMessage, String title) {
173         showOptionDialog(parent, topMessage, longMessage, bottomMessage, title, JOptionPane.ERROR_MESSAGE, JOptionPane.DEFAULT_OPTION);
174     }
175 
176     /**
177      * {@inheritDoc}
178      */
179     @Override
180     public void showWarningDialog(String message) {
181         showWarningDialog(message, t("quadrige2.error.business.warning"));
182     }
183 
184     /**
185      * <p>showWarningDialog.</p>
186      *
187      * @param message a {@link java.lang.String} object.
188      * @param title   a {@link java.lang.String} object.
189      */
190     public void showWarningDialog(String message, String title) {
191         showWarningDialog(message, null, null, title);
192     }
193 
194     /**
195      * <p>showWarningDialog.</p>
196      *
197      * @param topMessage    a {@link java.lang.String} object.
198      * @param longMessage   a {@link java.lang.String} object.
199      * @param bottomMessage a {@link java.lang.String} object.
200      */
201     public void showWarningDialog(String topMessage, String longMessage, String bottomMessage) {
202         showWarningDialog(topMessage, longMessage, bottomMessage, t("quadrige2.error.business.warning"));
203     }
204 
205     /**
206      * <p>showWarningDialog.</p>
207      *
208      * @param topMessage    a {@link java.lang.String} object.
209      * @param longMessage   a {@link java.lang.String} object.
210      * @param bottomMessage a {@link java.lang.String} object.
211      * @param title         a {@link java.lang.String} object.
212      */
213     public void showWarningDialog(String topMessage, String longMessage, String bottomMessage, String title) {
214         showOptionDialog(null, topMessage, longMessage, bottomMessage, title, JOptionPane.WARNING_MESSAGE, JOptionPane.DEFAULT_OPTION);
215     }
216 
217     /**
218      * <p>showMessageDialog.</p>
219      *
220      * @param message a {@link java.lang.String} object.
221      */
222     public void showMessageDialog(String message) {
223         showMessageDialog(message, null, null, "");
224     }
225 
226     /**
227      * <p>showMessageDialog.</p>
228      *
229      * @param message a {@link java.lang.String} object.
230      * @param title   a {@link java.lang.String} object.
231      */
232     public void showMessageDialog(String message, String title) {
233         showMessageDialog(message, null, null, title);
234     }
235 
236     /**
237      * <p>showMessageDialog.</p>
238      *
239      * @param topMessage    a {@link java.lang.String} object.
240      * @param longMessage   a {@link java.lang.String} object.
241      * @param bottomMessage a {@link java.lang.String} object.
242      * @param title         a {@link java.lang.String} object.
243      */
244     public void showMessageDialog(String topMessage, String longMessage, String bottomMessage, String title) {
245         showOptionDialog(null, topMessage, longMessage, bottomMessage, title, JOptionPane.INFORMATION_MESSAGE, JOptionPane.DEFAULT_OPTION);
246     }
247 
248     /**
249      * <p>showConfirmDialog.</p>
250      *
251      * @param message    a {@link java.lang.String} object.
252      * @param optionType a int.
253      * @return a int.
254      */
255     public int showConfirmDialog(String message, int optionType) {
256         return showConfirmDialog(message, t("quadrige2.error.business.warning"), optionType);
257     }
258 
259     /**
260      * <p>showConfirmDialog.</p>
261      *
262      * @param parent     a {@link java.awt.Component} object.
263      * @param message    a {@link java.lang.String} object.
264      * @param optionType a int.
265      * @return a int.
266      */
267     public int showConfirmDialog(Component parent, String message, int optionType) {
268         return showConfirmDialog(parent, message, t("quadrige2.error.business.warning"), optionType);
269     }
270 
271     /**
272      * <p>showConfirmDialog.</p>
273      *
274      * @param message    a {@link java.lang.String} object.
275      * @param title      a {@link java.lang.String} object.
276      * @param optionType a int.
277      * @return a int.
278      */
279     public int showConfirmDialog(String message, String title, int optionType) {
280         return showConfirmDialog(message, null, null, title, optionType);
281     }
282 
283     /**
284      * <p>showConfirmDialog.</p>
285      *
286      * @param parent     a {@link java.awt.Component} object.
287      * @param message    a {@link java.lang.String} object.
288      * @param title      a {@link java.lang.String} object.
289      * @param optionType a int.
290      * @return a int.
291      */
292     public int showConfirmDialog(Component parent, String message, String title, int optionType) {
293         return showConfirmDialog(parent, message, null, null, title, optionType);
294     }
295 
296     /**
297      * <p>showConfirmDialog.</p>
298      *
299      * @param topMessage    a {@link java.lang.String} object.
300      * @param longMessage   a {@link java.lang.String} object.
301      * @param bottomMessage a {@link java.lang.String} object.
302      * @param optionType    a int.
303      * @return a int.
304      */
305     public int showConfirmDialog(String topMessage, String longMessage, String bottomMessage, int optionType) {
306         return showConfirmDialog(topMessage, longMessage, bottomMessage, t("quadrige2.error.business.question"), optionType);
307     }
308 
309     /**
310      * <p>showConfirmDialog.</p>
311      *
312      * @param topMessage    a {@link java.lang.String} object.
313      * @param longMessage   a {@link java.lang.String} object.
314      * @param bottomMessage a {@link java.lang.String} object.
315      * @param title         a {@link java.lang.String} object.
316      * @param optionType    a int.
317      * @return a int.
318      */
319     public int showConfirmDialog(String topMessage, String longMessage, String bottomMessage, String title, int optionType) {
320         return showOptionDialog(null, topMessage, longMessage, bottomMessage, title, JOptionPane.QUESTION_MESSAGE, optionType);
321     }
322 
323     /**
324      * <p>showConfirmDialog.</p>
325      *
326      * @param parent        a {@link java.awt.Component} object.
327      * @param topMessage    a {@link java.lang.String} object.
328      * @param longMessage   a {@link java.lang.String} object.
329      * @param bottomMessage a {@link java.lang.String} object.
330      * @param title         a {@link java.lang.String} object.
331      * @param optionType    a int.
332      * @return a int.
333      */
334     public int showConfirmDialog(Component parent, String topMessage, String longMessage, String bottomMessage, String title, int optionType) {
335         return showOptionDialog(parent, topMessage, longMessage, bottomMessage, title, JOptionPane.QUESTION_MESSAGE, optionType);
336     }
337 
338     /**
339      * <p>showOptionDialog.</p>
340      *
341      * @param parent        a {@link Component} object.
342      * @param topMessage    a {@link String} object.
343      * @param longMessage   a {@link String} object.
344      * @param bottomMessage a {@link String} object.
345      * @param title         a {@link String} object.
346      * @param messageType   a int.
347      * @param optionType    a int.
348      * @param customOptions custom options
349      * @return a int.
350      */
351     public int showOptionDialog(Component parent, String topMessage, String longMessage, String bottomMessage, String title, int messageType, int optionType, String... customOptions) {
352 
353         List<Object> messageElements = Lists.newArrayList();
354         if (StringUtils.isNotBlank(topMessage)) {
355             messageElements.add(ApplicationUIUtil.getHtmlString(topMessage));
356         }
357         if (StringUtils.isNotBlank(longMessage)) {
358             if (ApplicationUIUtil.isHtmlString(longMessage)) {
359                 JTextPane textPane = new JTextPane();
360                 textPane.setEditorKit(new HTMLEditorKit());
361                 textPane.setText(longMessage);
362                 textPane.setPreferredSize(new Dimension(200, 200));
363                 JScrollPane scrollPane = new JScrollPane(textPane);
364                 scrollPane.setBorder(null);
365                 messageElements.add(scrollPane);
366             } else {
367                 JTextArea textArea = new JTextArea(6, 25);
368                 textArea.setEditable(false);
369                 textArea.setText(longMessage);
370                 JScrollPane scrollPane = new JScrollPane(textArea);
371                 messageElements.add(scrollPane);
372             }
373         }
374         if (StringUtils.isNotBlank(bottomMessage)) {
375             messageElements.add(ApplicationUIUtil.getHtmlString(bottomMessage));
376         }
377         Object messageObject[] = messageElements.toArray();
378 
379         return showOptionDialog(parent, messageObject, title, messageType, optionType);
380     }
381 
382     /**
383      * <p>showOptionDialog.</p>
384      *
385      * @param parent        a {@link Component} object.
386      * @param messageObject a {@link Object} object.
387      * @param title         a {@link String} object.
388      * @param messageType   a int.
389      * @param optionType    a int.
390      * @param customOptions custom options
391      * @return a int.
392      */
393     public int showOptionDialog(Component parent, Object messageObject, String title, int messageType, int optionType, String... customOptions) {
394 
395         Object[] options = null;
396         Object defaultOption = null;
397         switch (optionType) {
398             case SAVE_NO_SAVE_CANCEL_OPTION:
399                 optionType = JOptionPane.YES_NO_CANCEL_OPTION;
400                 options = new Object[]{t("quadrige2.common.save.quit"), t("quadrige2.common.no.save.quit"), t("quadrige2.common.cancel")};
401                 defaultOption = options[2];
402                 break;
403             case NO_SAVE_CANCEL_OPTION:
404                 optionType = JOptionPane.OK_CANCEL_OPTION;
405                 options = new Object[]{t("quadrige2.common.no.save.quit"), t("quadrige2.common.cancel")};
406                 defaultOption = options[1];
407                 break;
408             case DELETE_CANCEL_OPTION:
409                 optionType = JOptionPane.OK_CANCEL_OPTION;
410                 options = new Object[]{t("quadrige2.common.delete"), t("quadrige2.common.cancel")};
411                 defaultOption = options[1];
412                 break;
413             case RESET_CANCEL_OPTION:
414                 optionType = JOptionPane.OK_CANCEL_OPTION;
415                 options = new Object[]{t("quadrige2.common.reset"), t("quadrige2.common.cancel")};
416                 defaultOption = options[1];
417                 break;
418             case DELETE_INVALID_CANCEL_OPTION:
419                 optionType = JOptionPane.OK_CANCEL_OPTION;
420                 options = new Object[]{t("quadrige2.common.delete.invalid.quit"), t("quadrige2.common.cancel")};
421                 defaultOption = options[1];
422                 break;
423             case OVERWRITE_FILE_CANCEL_OPTION:
424                 optionType = JOptionPane.OK_CANCEL_OPTION;
425                 options = new Object[]{t("quadrige2.common.file.overwrite"), t("quadrige2.common.cancel")};
426                 defaultOption = options[1];
427                 break;
428             case UPDATE_DB_CANCEL_OPTION:
429                 optionType = JOptionPane.OK_CANCEL_OPTION;
430                 options = new Object[]{t("quadrige2.common.db.update"), t("quadrige2.common.cancel")};
431                 defaultOption = options[1];
432                 break;
433             case LOAD_DB_CANCEL_OPTION:
434                 optionType = JOptionPane.OK_CANCEL_OPTION;
435                 options = new Object[]{t("quadrige2.common.db.load"), t("quadrige2.common.cancel")};
436                 defaultOption = options[1];
437                 break;
438             case CUSTOM_OPTION:
439                 Preconditions.checkArgument(ArrayUtils.getLength(customOptions) > 0 && ArrayUtils.getLength(customOptions) <= 3);
440                 int size = customOptions.length;
441                 optionType = size == 1 ? JOptionPane.OK_OPTION : size == 2 ? JOptionPane.OK_CANCEL_OPTION : JOptionPane.YES_NO_CANCEL_OPTION;
442                 options = customOptions;
443                 defaultOption = options[size - 1];
444                 break;
445         }
446 
447         JOptionPane pane = new JOptionPane(messageObject, messageType, optionType, null, options, defaultOption);
448         if (parent == null) {
449             parent = context.getMainUI();
450         }
451         JDialog dialog = pane.createDialog(parent, title);
452         dialog.setModalityType(Dialog.ModalityType.TOOLKIT_MODAL);
453 
454         dialog.setVisible(true);
455         dialog.dispose();
456 
457         Object selectedValue = pane.getValue();
458         if (selectedValue instanceof Integer) {
459             return ((Integer) selectedValue);
460         } else if (options != null) {
461             return ArrayUtils.indexOf(options, selectedValue);
462         }
463         return JOptionPane.CLOSED_OPTION;
464     }
465 
466     /**
467      * <p>showOptionDialog.</p>
468      *
469      * @param parent       a {@link java.awt.Component} object.
470      * @param message      a {@link java.lang.Object} object.
471      * @param title        a {@link java.lang.String} object.
472      * @param optionType   a int.
473      * @param messageType  a int.
474      * @param options      an array of {@link java.lang.Object} objects.
475      * @param initialValue a {@link java.lang.Object} object.
476      * @return a int.
477      */
478     public int showOptionDialog(Component parent, Object message, String title, int optionType, int messageType, Object[] options, Object initialValue) {
479 
480         JOptionPane pane = new JOptionPane(message, messageType,
481                 optionType, null,
482                 options, initialValue);
483 
484         pane.setInitialValue(initialValue);
485 
486         if (parent == null) {
487             parent = context.getMainUI();
488         }
489         JDialog dialog = pane.createDialog(parent, title);
490         dialog.setModalityType(Dialog.ModalityType.TOOLKIT_MODAL);
491 
492         pane.selectInitialValue();
493         dialog.setVisible(true);
494         dialog.dispose();
495 
496         Object selectedValue = pane.getValue();
497 
498         if (selectedValue == null)
499             return JOptionPane.CLOSED_OPTION;
500         if (options == null) {
501             if (selectedValue instanceof Integer)
502                 return (Integer) selectedValue;
503             return JOptionPane.CLOSED_OPTION;
504         }
505         for (int counter = 0, maxCounter = options.length;
506              counter < maxCounter; counter++) {
507             if (options[counter].equals(selectedValue))
508                 return counter;
509         }
510         return JOptionPane.CLOSED_OPTION;
511     }
512 
513     /**
514      * <p>showInputDialog.</p>
515      *
516      * @param parent  a {@link java.awt.Component} object.
517      * @param message a {@link java.lang.String} object.
518      * @param title   a {@link java.lang.String} object.
519      * @return a {@link java.lang.Object} object.
520      */
521     public Object showInputDialog(Component parent, String message, String title) {
522 
523         return showInputDialog(parent, message, title, null, null);
524     }
525 
526     /**
527      * <p>showInputDialog.</p>
528      *
529      * @param parent                a {@link java.awt.Component} object.
530      * @param message               a {@link java.lang.String} object.
531      * @param title                 a {@link java.lang.String} object.
532      * @param selectionValues       an array of {@link java.lang.Object} objects.
533      * @param initialSelectionValue a {@link java.lang.Object} object.
534      * @return a {@link java.lang.Object} object.
535      */
536     public Object showInputDialog(Component parent, String message, String title, Object[] selectionValues, Object initialSelectionValue) {
537 
538         JOptionPane pane = new JOptionPane(message, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, null, null);
539 
540         pane.setWantsInput(true);
541         pane.setSelectionValues(selectionValues);
542         pane.setInitialSelectionValue(initialSelectionValue);
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 value = pane.getInputValue();
555 
556         if (value == JOptionPane.UNINITIALIZED_VALUE) {
557             return null;
558         }
559         return value;
560 
561     }
562 
563     private class ModalErrorPanelUI extends BasicErrorPaneUI {
564 
565         @Override
566         public JDialog getErrorDialog(Component owner) {
567             JDialog dialog = super.getErrorDialog(owner);
568             dialog.setModalityType(Dialog.ModalityType.TOOLKIT_MODAL);
569             return dialog;
570         }
571 
572     }
573 }