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 import com.google.common.base.Preconditions;
27 import com.google.common.collect.Lists;
28 import com.google.common.collect.Maps;
29 import com.google.common.collect.Sets;
30 import fr.ifremer.quadrige2.core.config.Quadrige2CoreConfiguration;
31 import fr.ifremer.quadrige2.core.dao.technical.decorator.DecoratorComparator;
32 import fr.ifremer.quadrige2.core.service.ClientServiceLocator;
33 import fr.ifremer.quadrige2.core.service.decorator.DecoratorService;
34 import fr.ifremer.quadrige2.ui.swing.common.action.AbstractChangeScreenAction;
35 import fr.ifremer.quadrige2.ui.swing.common.action.ActionUI;
36 import fr.ifremer.quadrige2.ui.swing.common.component.ActionComboBoxModel;
37 import fr.ifremer.quadrige2.ui.swing.common.component.ActionListCellRenderer;
38 import fr.ifremer.quadrige2.ui.swing.common.component.ColoredFilteredListCellRenderer;
39 import fr.ifremer.quadrige2.ui.swing.common.component.ExtendedDecoratorListCellRenderer;
40 import fr.ifremer.quadrige2.ui.swing.common.component.bean.ExtendedBeanDoubleList;
41 import fr.ifremer.quadrige2.ui.swing.common.component.bean.ExtendedComboBox;
42 import fr.ifremer.quadrige2.ui.swing.common.component.coordinate.CoordinateEditor;
43 import fr.ifremer.quadrige2.ui.swing.common.content.AbstractMainUIHandler;
44 import fr.ifremer.quadrige2.ui.swing.common.content.MainUI;
45 import fr.ifremer.quadrige2.ui.swing.common.model.AbstractBeanUIModel;
46 import fr.ifremer.quadrige2.ui.swing.common.plaf.HintSynthTextFieldUI;
47 import fr.ifremer.quadrige2.ui.swing.common.table.AbstractRowUIModel;
48 import fr.ifremer.quadrige2.ui.swing.common.table.ColumnIdentifier;
49 import fr.ifremer.quadrige2.ui.swing.common.table.editor.CoordinateCellEditor;
50 import fr.ifremer.quadrige2.ui.swing.common.table.editor.ExtendedComboBoxCellEditor;
51 import fr.ifremer.quadrige2.ui.swing.common.table.editor.FilterableComboBoxCellEditor;
52 import fr.ifremer.quadrige2.ui.swing.common.table.editor.NumberCellEditor;
53 import fr.ifremer.quadrige2.ui.swing.common.table.renderer.ExtendedDecoratorCellRenderer;
54 import fr.ifremer.quadrige2.ui.swing.common.table.renderer.NumberCellRenderer;
55 import jaxx.runtime.SwingUtil;
56 import jaxx.runtime.swing.editor.bean.BeanDoubleList;
57 import jaxx.runtime.swing.editor.bean.BeanFilterableComboBox;
58 import jaxx.runtime.swing.model.JaxxFilterableListModel;
59 import jaxx.runtime.validator.swing.SwingValidator;
60 import org.apache.commons.collections4.CollectionUtils;
61 import org.apache.commons.lang3.ArrayUtils;
62 import org.apache.commons.lang3.StringUtils;
63 import org.apache.commons.lang3.time.DateUtils;
64 import org.apache.commons.logging.Log;
65 import org.apache.commons.logging.LogFactory;
66 import org.jdatepicker.AbstractComponentColor;
67 import org.jdatepicker.JDatePanel;
68 import org.jdatepicker.JDatePicker;
69 import org.jdesktop.swingx.JXDatePicker;
70 import org.jdesktop.swingx.JXPanel;
71 import org.jdesktop.swingx.JXTable;
72 import org.jdesktop.swingx.decorator.AbstractHighlighter;
73 import org.jdesktop.swingx.decorator.ComponentAdapter;
74 import org.jdesktop.swingx.decorator.HighlightPredicate;
75 import org.jdesktop.swingx.renderer.DefaultTableRenderer;
76 import org.jdesktop.swingx.renderer.StringValue;
77 import org.jdesktop.swingx.table.TableColumnExt;
78 import org.nuiton.decorator.Decorator;
79 import org.nuiton.decorator.JXPathDecorator;
80 import org.nuiton.jaxx.application.bean.JavaBeanObjectUtil;
81 import org.nuiton.jaxx.application.swing.AbstractApplicationUIHandler;
82 import org.nuiton.jaxx.application.swing.action.ApplicationActionUIHandler;
83 import org.nuiton.jaxx.application.swing.action.ApplicationUIAction;
84 import org.nuiton.jaxx.application.swing.util.Cancelable;
85 import org.nuiton.jaxx.widgets.number.NumberEditor;
86 import org.nuiton.validator.bean.simple.SimpleBeanValidator;
87
88 import javax.swing.*;
89 import javax.swing.event.*;
90 import javax.swing.plaf.nimbus.NimbusLookAndFeel;
91 import javax.swing.table.TableCellEditor;
92 import javax.swing.table.TableCellRenderer;
93 import javax.swing.table.TableColumnModel;
94 import javax.swing.text.AbstractDocument;
95 import java.awt.*;
96 import java.awt.event.*;
97 import java.beans.PropertyChangeEvent;
98 import java.beans.PropertyChangeListener;
99 import java.io.File;
100 import java.io.Serializable;
101 import java.math.BigDecimal;
102 import java.text.DecimalFormat;
103 import java.util.*;
104 import java.util.List;
105
106 import static org.nuiton.i18n.I18n.t;
107
108
109
110
111
112
113
114
115
116 public abstract class AbstractUIHandler<M, UI extends ApplicationUI<M, ?>>
117 extends AbstractApplicationUIHandler<M, UI>
118 implements UIMessageNotifier {
119
120
121
122
123 private static final Log LOG = LogFactory.getLog(AbstractUIHandler.class);
124
125 private final Map<AbstractBeanUIModel, PropertyChangeListener> modelModifyListenerMap = Maps.newHashMap();
126 private final Map<SimpleBeanValidator, PropertyChangeListener> validatorValidListenerMap = Maps.newHashMap();
127
128
129
130
131
132
133
134
135
136
137 public void changeScreenAction(Class<? extends AbstractChangeScreenAction> screenActionClass) {
138 ApplicationUIAction<? extends AbstractChangeScreenAction> screenAction;
139 screenAction = getContext().getActionFactory().createUIAction(getContext().getMainUI().getHandler(), screenActionClass);
140 getContext().getActionEngine().runAction(screenAction.getLogicAction());
141 }
142
143
144
145
146 @Override
147 public void showInformationMessage(String message) {
148 getContext().showInformationMessage(message);
149 }
150
151
152
153
154 public void showNotImplementedFunctionnality() {
155 getContext().getDialogHelper().showMessageDialog("Fonctionnalité à venir ...");
156 }
157
158
159
160
161 @Override
162 public ApplicationUIContext getContext() {
163 return (ApplicationUIContext) super.getContext();
164 }
165
166
167
168
169
170
171 public String getTitle() {
172 return t(getUI().getClass().getSimpleName() + ".title");
173 }
174
175
176
177
178
179
180 public Quadrige2CoreConfiguration getConfig() {
181 return getContext().getConfiguration();
182 }
183
184
185
186
187 @Override
188 public Component getTopestUI() {
189 return getContext().getActionUI();
190 }
191
192
193
194
195 @Override
196 public void onCloseUI() {
197
198 if (LOG.isDebugEnabled()) {
199 LOG.debug("closing: " + getUI());
200 }
201
202 ApplicationUIUtil.destroy(getUI());
203 clearValidators();
204
205 if (getUI() instanceof Window) {
206 ((Window) getUI()).dispose();
207 }
208 }
209
210
211
212
213 public void clearValidators() {
214 MainUI main = getContext().getMainUI();
215 Preconditions.checkNotNull(main, "No mainUI registered in application context");
216 AbstractMainUIHandler handler = (AbstractMainUIHandler) main.getHandler();
217 handler.clearValidators();
218 }
219
220
221
222
223 @Override
224 protected JComponent getComponentToFocus() {
225 return null;
226 }
227
228
229
230
231 @Override
232 public SwingValidator<M> getValidator() {
233 return null;
234 }
235
236
237
238
239 public void forceRevalidateModel() {
240
241 if (getValidator() != null) {
242 getValidator().doValidate();
243 }
244 if (getModel() instanceof AbstractBeanUIModel) {
245 ((AbstractBeanUIModel) getModel()).firePropertyChanged(AbstractBeanUIModel.PROPERTY_VALID, null, null);
246 }
247 }
248
249
250
251
252 @Override
253 public <O> Decorator<O> getDecorator(Class<O> type, String name) {
254 DecoratorService decoratorService = ClientServiceLocator.instance().getDecoratorService();
255
256 Preconditions.checkNotNull(type);
257
258 return decoratorService.getDecoratorByType(type, name);
259 }
260
261
262
263
264 @Override
265 public String decorate(Serializable object, String context) {
266 return super.decorate(object, context);
267 }
268
269
270
271
272 @Override
273 public String decorate(Serializable object) {
274 return super.decorate(object);
275 }
276
277
278
279
280
281
282 public TableCellRenderer newBigDecimalRenderer() {
283 DefaultTableRenderer defaultRenderer = new DefaultTableRenderer(new StringValue() {
284
285 @Override
286 public String getString(Object value) {
287
288
289 if (value instanceof BigDecimal) {
290 BigDecimal bigDecimal = (BigDecimal) value;
291 return bigDecimal.toString();
292 }
293
294 return "";
295 }
296
297 }, JLabel.RIGHT);
298 return new NumberCellRenderer(defaultRenderer);
299 }
300
301
302
303
304
305
306
307 public TableCellRenderer newNumberCellRenderer(final int nbDecimal) {
308 DefaultTableRenderer defaultRenderer = new DefaultTableRenderer(new StringValue() {
309
310 @Override
311 public String getString(Object value) {
312 if (value == null) {
313 return "";
314 }
315
316 int minDecimal = (value instanceof Integer) ? 0 : 1;
317 int maxDecimal = (value instanceof Integer) ? 0 : nbDecimal;
318
319 DecimalFormat decimalFormat = ApplicationUIUtil.getDecimalFormat(minDecimal, maxDecimal);
320 return decimalFormat.format(value);
321 }
322
323 }, JLabel.RIGHT);
324 return new NumberCellRenderer(defaultRenderer);
325 }
326
327
328
329
330
331
332
333
334
335
336
337
338 public <N extends Number> TableCellEditor newNumberCellEditor(Class<N> numberClass, boolean useSign, String numberPattern, N minValue, N maxValue) {
339 return new NumberCellEditor<>(numberClass, useSign, numberPattern, minValue, maxValue);
340 }
341
342
343
344
345
346
347
348
349
350
351 public <N extends Number> TableCellEditor newNumberCellEditor(Class<N> numberClass, boolean useSign, String numberPattern) {
352 return newNumberCellEditor(numberClass, useSign, numberPattern, null, null);
353 }
354
355
356
357
358
359
360
361
362
363
364
365 protected TableColumnExt addCoordinateColumnToModel(
366 TableColumnModel model,
367 CoordinateEditor.CoordinateType coordinateType,
368 ColumnIdentifier<?> identifier) {
369
370 TableCellEditor editor = new CoordinateCellEditor(coordinateType);
371
372 TableCellRenderer renderer = newNumberCellRenderer(6);
373
374 return addColumnToModel(model, editor, renderer, identifier);
375 }
376
377
378
379
380
381
382 @Override
383 protected <R> TableColumnExt addColumnToModel(
384 TableColumnModel model,
385 TableCellEditor editor,
386 TableCellRenderer renderer,
387 org.nuiton.jaxx.application.swing.table.ColumnIdentifier<R> identifier) {
388
389 TableColumnExt column = null;
390
391 if (identifier instanceof ColumnIdentifier) {
392 final ColumnIdentifier<?> columnIdentifier = (ColumnIdentifier<?>) identifier;
393
394
395 if (renderer == null) {
396 Decorator decorator = getDecorator(columnIdentifier.getPropertyType(), columnIdentifier.getDecoratorName());
397 if (decorator != null) {
398 renderer = new ExtendedDecoratorCellRenderer(decorator);
399 } else {
400 renderer = new TableCellRenderer() {
401
402 @Override
403 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
404 int column) {
405 TableCellRenderer defaultRenderer = table.getDefaultRenderer(columnIdentifier.getPropertyType());
406 JComponent component = (JComponent) defaultRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
407
408
409 if (value != null) {
410 component.setToolTipText(value.toString());
411 }
412
413 return component;
414 }
415 };
416 }
417 }
418
419
420 column = new TableColumnExt(model.getColumnCount());
421 model.addColumn(column);
422 column.setIdentifier(columnIdentifier);
423 column.setCellEditor(editor);
424 column.setCellRenderer(renderer);
425
426
427 if (columnIdentifier.isMandatory()) {
428 column.setHeaderValue(t("quadrige2.table.mandatoryColumn.header", t(columnIdentifier.getHeaderI18nKey())));
429 column.setToolTipText(t("quadrige2.table.mandatoryColumn.tip", t(columnIdentifier.getHeaderTipI18nKey())));
430
431 column.setHideable(false);
432 } else {
433
434 column.setHeaderValue(ApplicationUIUtil.getHtmlString(t(columnIdentifier.getHeaderI18nKey())));
435 column.setToolTipText(ApplicationUIUtil.getHtmlString(t(columnIdentifier.getHeaderTipI18nKey())));
436 }
437
438 column.setSortable(false);
439 }
440
441 return column;
442 }
443
444
445
446
447
448
449
450
451
452
453 protected <R extends AbstractRowUIModel, B> TableColumnExt addFilterableComboDataColumnToModel(TableColumnModel model, ColumnIdentifier<R> identifier,
454 List<B> data, boolean resettable) {
455 @SuppressWarnings("unchecked")
456 Class<B> beanType = (Class<B>) identifier.getPropertyType();
457 String decoratorName = identifier.getDecoratorName();
458 FilterableComboBoxCellEditor<B> editor = newFilterableComboBoxCellEditor(data, beanType, decoratorName, resettable);
459 return addColumnToModel(model, editor, newTableCellRender(beanType, decoratorName), identifier);
460 }
461
462
463
464
465
466
467
468
469
470
471
472
473 protected <R extends AbstractRowUIModel, B> TableColumnExt addExtendedComboDataColumnToModel(TableColumnModel model, ColumnIdentifier<R> identifier,
474 List<B> data, boolean resettable) {
475 @SuppressWarnings("unchecked")
476 Class<B> beanType = (Class<B>) identifier.getPropertyType();
477 String decoratorName = identifier.getDecoratorName();
478 FilterableComboBoxCellEditor<B> editor = newExtendedComboBoxCellEditor(data, beanType, decoratorName, resettable);
479 return addColumnToModel(model, editor, newTableCellRender(beanType, decoratorName), identifier);
480 }
481
482
483
484
485
486
487
488
489
490
491 protected <B> FilterableComboBoxCellEditor<B> newFilterableComboBoxCellEditor(List<B> data, Class<B> beanType,
492 boolean resettable) {
493 return newFilterableComboBoxCellEditor(data, beanType, null, resettable);
494 }
495
496
497
498
499
500
501
502
503
504
505
506 protected <B> FilterableComboBoxCellEditor<B> newFilterableComboBoxCellEditor(List<B> data, Class<B> beanType,
507 String decoratorName, boolean resettable) {
508
509 BeanFilterableComboBox<B> comboBox = new BeanFilterableComboBox<>(getUI());
510 preInitBeanFilterableComboBox(comboBox, beanType, resettable);
511 initBeanFilterableComboBox(comboBox, data, null, decoratorName);
512 return new FilterableComboBoxCellEditor<>(comboBox);
513 }
514
515
516
517
518
519
520
521
522
523
524 protected <B> ExtendedComboBoxCellEditor<B> newExtendedComboBoxCellEditor(List<B> data, Class<B> beanType, boolean resettable) {
525 return newExtendedComboBoxCellEditor(data, beanType, null, resettable);
526 }
527
528
529
530
531
532
533
534
535
536
537 @SuppressWarnings("unchecked")
538 protected <B> ExtendedComboBoxCellEditor<B> newExtendedComboBoxCellEditor(List<B> data, ColumnIdentifier identifier, boolean resettable) {
539 Class<B> beanType = identifier.getPropertyType();
540 return newExtendedComboBoxCellEditor(data, beanType, identifier.getDecoratorName(), resettable);
541 }
542
543
544
545
546
547
548
549
550
551
552
553 protected <B> ExtendedComboBoxCellEditor<B> newExtendedComboBoxCellEditor(List<B> data, Class<B> beanType,
554 String decoratorName, boolean resettable) {
555
556 ExtendedComboBox<B> comboBox = new ExtendedComboBox<>(getUI());
557 preInitBeanFilterableComboBox(comboBox, beanType, resettable);
558 initBeanFilterableComboBox(comboBox, data, null, decoratorName);
559 return new ExtendedComboBoxCellEditor<>(comboBox);
560 }
561
562 private <B> void preInitBeanFilterableComboBox(BeanFilterableComboBox<B> comboBox, Class<B> beanType, boolean resettable) {
563 comboBox.setFilterable(true);
564 comboBox.setShowReset(resettable);
565 comboBox.setShowDecorator(false);
566 comboBox.setBeanType(beanType);
567 comboBox.setAutoFocus(false);
568 }
569
570
571
572
573
574
575
576 @Override
577 public void autoSelectRowInTable(MouseEvent e, JPopupMenu popup) {
578 boolean rightClick = SwingUtilities.isRightMouseButton(e);
579
580 if (e.getSource() instanceof JXTable && (rightClick || SwingUtilities.isLeftMouseButton(e))) {
581
582
583 Point p = e.getPoint();
584
585 JXTable source = (JXTable) e.getSource();
586
587 int[] selectedRows = source.getSelectedRows();
588 int[] selectedColumns = source.getSelectedColumns();
589
590
591 int rowIndex = source.rowAtPoint(p);
592
593
594 int columnIndex = source.columnAtPoint(p);
595
596 if (LOG.isDebugEnabled()) {
597 LOG.debug("At point [" + p + "] found Row " + rowIndex + ", Column " + columnIndex);
598 }
599
600 boolean canContinue = true;
601
602 if (source.isEditing()) {
603
604
605 boolean stopEdit = source.getCellEditor().stopCellEditing();
606 if (!stopEdit) {
607 if (LOG.isWarnEnabled()) {
608 LOG.warn("Could not stop edit cell...");
609 }
610 canContinue = false;
611 }
612 }
613
614 if (canContinue) {
615
616
617 if (rowIndex == -1) {
618 source.clearSelection();
619 } else if (!ArrayUtils.contains(selectedRows, rowIndex)) {
620 source.setRowSelectionInterval(rowIndex, rowIndex);
621 }
622
623
624 if (columnIndex == -1) {
625 source.clearSelection();
626 } else if (!ArrayUtils.contains(selectedColumns, columnIndex)) {
627 source.setColumnSelectionInterval(columnIndex, columnIndex);
628 }
629
630 if (rightClick) {
631
632
633 int modelRowIndex = rowIndex == -1 ? -1 : source.convertRowIndexToModel(rowIndex);
634 int modelColumnIndex = columnIndex == -1 ? -1 : source.convertColumnIndexToModel(columnIndex);
635
636 beforeOpenPopup(modelRowIndex, modelColumnIndex);
637
638
639 popup.show(source, e.getX(), e.getY());
640 }
641 }
642 }
643
644 }
645
646
647
648
649
650
651 protected void listenModelModify(AbstractBeanUIModel model) {
652 Preconditions.checkArgument(getModel() != model, "model can't listen to itself");
653
654 stopListenModelModify(model);
655
656 PropertyChangeListener listener = new PropertyChangeListener() {
657 @Override
658 public void propertyChange(PropertyChangeEvent evt) {
659 Boolean modify = (Boolean) evt.getNewValue();
660 if (modify != null) {
661 ((AbstractBeanUIModel) getModel()).setModify(modify);
662 }
663 }
664 };
665
666 model.addPropertyChangeListener(AbstractBeanUIModel.PROPERTY_MODIFY, listener);
667 modelModifyListenerMap.put(model, listener);
668 }
669
670
671
672
673
674
675 protected void stopListenModelModify(AbstractBeanUIModel model) {
676 PropertyChangeListener listener = modelModifyListenerMap.get(model);
677 if (listener != null) {
678 model.removePropertyChangeListener(AbstractBeanUIModel.PROPERTY_MODIFY, listener);
679 modelModifyListenerMap.remove(model);
680 }
681 }
682
683
684
685
686
687
688 protected void listenModelValid(AbstractBeanUIModel model) {
689 model.addPropertyChangeListener(AbstractBeanUIModel.PROPERTY_VALID, new PropertyChangeListener() {
690 @Override
691 public void propertyChange(PropertyChangeEvent evt) {
692 Boolean valid = (Boolean) evt.getNewValue();
693 if (valid != null) {
694 ((AbstractBeanUIModel) getModel()).setValid(valid);
695 }
696 }
697 });
698 }
699
700
701
702
703
704
705
706 public void setEnabled(Container container, boolean enabled) {
707 Component[] components = container.getComponents();
708 for (Component component : components) {
709 component.setEnabled(enabled);
710 if (component instanceof Container) {
711 setEnabled((Container) component, enabled);
712 }
713 }
714 }
715
716
717
718
719 @Override
720 public void setDate(ActionEvent event, String property) {
721 Date value = null;
722 if (event.getSource() instanceof JXDatePicker) {
723 value = ((JXDatePicker) event.getSource()).getDate();
724 } else if (event.getSource() instanceof JDatePanel) {
725 value = ((JDatePanel) event.getSource()).getDate();
726 } else if (event.getSource() instanceof JDatePicker) {
727 value = ((JDatePicker) event.getSource()).getDate();
728 }
729
730 Date date = (Date) JavaBeanObjectUtil.getProperty(getModel(), property);
731 if (value != null && date != null) {
732 Calendar cal = DateUtils.toCalendar(date);
733 value = DateUtils.setHours(value, cal.get(Calendar.HOUR_OF_DAY));
734 value = DateUtils.setMinutes(value, cal.get(Calendar.MINUTE));
735 value = DateUtils.setSeconds(value, cal.get(Calendar.SECOND));
736 }
737 JavaBeanObjectUtil.setProperty(getModel(), property, value);
738 }
739
740
741
742
743
744
745
746
747 @Override
748 protected void initUIComponent(Object component) {
749 super.initUIComponent(component);
750
751 if (component instanceof NumberEditor) {
752 initNumberEditor((NumberEditor) component);
753
754 } else if (component instanceof JDatePicker) {
755 initDatePicker((JDatePicker) component);
756 }
757 }
758
759 private void initDatePicker(JDatePicker datePicker) {
760
761 String datePattern = getContext().getDateFormat();
762 datePicker.setDateFormat(datePattern, ApplicationUIUtil.getDefault2DigitYearStart());
763
764
765 datePicker.setColor(AbstractComponentColor.Key.FG_MONTH_SELECTOR, Color.black);
766 datePicker.setColor(AbstractComponentColor.Key.BG_MONTH_SELECTOR, UIManager.getColor("background"));
767 datePicker.setColor(AbstractComponentColor.Key.FG_GRID_HEADER, UIManager.getColor("thematicLabelColor"));
768 datePicker.setColor(AbstractComponentColor.Key.BG_GRID_SELECTED, UIManager.getColor("nimbusSelectionBackground"));
769 datePicker.setColor(AbstractComponentColor.Key.BG_GRID_TODAY_SELECTED, UIManager.getColor("nimbusSelectionBackground"));
770
771 datePicker.setToolTipText(t("jaxx.application.common.datefield.tip", datePattern));
772 datePicker.setTextEditable(true);
773 datePicker.setShowYearButtons(true);
774
775 if (isAutoSelectOnFocus(datePicker)) {
776 addAutoSelectOnFocus(datePicker.getEditor());
777 }
778
779 }
780
781 private void initNumberEditor(NumberEditor numberEditor) {
782
783
784 numberEditor.init();
785
786
787 numberEditor.getNumber0().setText(t("numbereditor.0"));
788 }
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820 @Override
821 protected void initTextField(JTextField jTextField) {
822 super.initTextField(jTextField);
823
824 String hint = (String) jTextField.getClientProperty("hint");
825 if (hint != null && UIManager.getLookAndFeel() instanceof NimbusLookAndFeel) {
826 jTextField.setUI(new HintSynthTextFieldUI(hint, false));
827 }
828 }
829
830
831
832
833 @Override
834 protected void initButton(AbstractButton abstractButton) {
835 super.initButton(abstractButton);
836
837
838 abstractButton.getInputMap().put(KeyStroke.getKeyStroke("pressed ENTER"), "pressed");
839 abstractButton.getInputMap().put(KeyStroke.getKeyStroke("released ENTER"), "released");
840
841
842 Class actionName = (Class) abstractButton.getClientProperty("applicationWorkerAction");
843 if (actionName != null) {
844 if (abstractButton.getAction() == null) {
845 Action action = getContext().getActionFactory().createNonBlockingUIAction(this, actionName, abstractButton);
846 abstractButton.setAction(action);
847 } else {
848 if (LOG.isErrorEnabled()) {
849 LOG.error(String.format("button '%s' has already an action. the action '%s' will be ignored", abstractButton.getName(), actionName.getName()));
850 }
851 }
852 }
853 }
854
855
856
857
858 @Override
859 protected <E> void initBeanList(BeanDoubleList<E> list, List<E> data, List<E> selectedData) {
860 initBeanList(list, data, selectedData, -1);
861 }
862
863
864
865
866 @Override
867 protected <E> void initBeanList(BeanDoubleList<E> list, List<E> data, List<E> selectedData, Decorator<E> selectedDecorator) {
868 initBeanList(list, data, selectedData, -1);
869 }
870
871
872
873
874
875
876
877
878
879
880 @SuppressWarnings("unchecked")
881 protected <E> void initBeanList(final BeanDoubleList<E> list, List<E> data, List<E> selectedData, int preferredWidth) {
882
883 Preconditions.checkNotNull(list, "No list!");
884
885 Class<E> beanType = list.getBeanType();
886 Preconditions.checkNotNull(beanType, "No beanType on the double list!");
887
888 String decoratorContext = null;
889 if (list instanceof ExtendedBeanDoubleList) {
890 decoratorContext = ((ExtendedBeanDoubleList) list).getDecoratorContext();
891 }
892
893 Decorator<E> decorator = getDecorator(beanType, decoratorContext);
894
895 if (CollectionUtils.isNotEmpty(data)) {
896 if (decorator != null) {
897 DecoratorComparator<E> comparator = new DecoratorComparator<E>(decorator);
898 Collections.sort(data, comparator);
899 if (selectedData != null) {
900 Collections.sort(selectedData, comparator);
901 }
902 }
903 }
904
905 if (LOG.isDebugEnabled()) {
906 LOG.debug("entity list [" + beanType.getName() + "] : " +
907 (data == null ? 0 : data.size()));
908 }
909
910 list.setI18nPrefix(getContext().getI18nPrefix());
911
912
913
914
915 list.init((JXPathDecorator<E>) decorator, null, data, selectedData);
916
917 if (LOG.isDebugEnabled()) {
918 LOG.debug("Jlist [" + beanType.getName() + "] : " +
919 list.getUniverseList().getModel().getSize());
920 }
921
922 if (preferredWidth > -1) {
923 fixBeanListWidth(list, preferredWidth);
924 }
925
926
927 final ColoredFilteredListCellRenderer universeRenderer = new ColoredFilteredListCellRenderer(list.getHandler().getDecorator(),
928 UIManager.getColor("nimbusSelectionBackground"), UIManager.getColor("nimbusSelectionBackground"));
929 list.getUniverseList().setCellRenderer(universeRenderer);
930 list.getSelectedList().setCellRenderer(newListCellRender(list.getHandler().getDecorator()));
931
932
933
934 final JTextField filterField = list.getFilterField();
935 AbstractDocument document = (AbstractDocument) list.getFilterField().getDocument();
936 DocumentListener[] dls = document.getDocumentListeners();
937 if (dls != null) {
938 for (DocumentListener dl : dls) {
939 if (dl.getClass().getName().contains("BeanDoubleListHandler")) {
940 document.removeDocumentListener(dl);
941 break;
942 }
943 }
944 }
945 final JaxxFilterableListModel<E> filterModel = (JaxxFilterableListModel<E>) list.getModel().getUniverseModel();
946 document.addDocumentListener(new DocumentListener() {
947
948 @Override
949 public void insertUpdate(DocumentEvent e) {
950 String text = filterField.getText();
951 universeRenderer.setFilterText(text);
952 filterModel.setFilterText(text);
953 }
954
955 @Override
956 public void removeUpdate(DocumentEvent e) {
957 String text = filterField.getText();
958 universeRenderer.setFilterText(text);
959 filterModel.setFilterText(text);
960 }
961
962 @Override
963 public void changedUpdate(DocumentEvent e) {
964 String text = filterField.getText();
965 universeRenderer.setFilterText(text);
966 filterModel.setFilterText(text);
967 }
968 });
969
970 filterModel.addListDataListener(new ListDataListener() {
971 @Override
972 public void intervalAdded(ListDataEvent e) {}
973
974 @Override
975 public void intervalRemoved(ListDataEvent e) {}
976
977 @Override
978 public void contentsChanged(ListDataEvent e) {
979
980 boolean empty = e.getIndex0() == 0 && e.getIndex1() == 0;
981 list.getAddButton().setEnabled(!empty && !list.getUniverseList().isSelectionEmpty());
982 if (empty) {
983 list.getUniverseList().clearSelection();
984 }
985 }
986 });
987
988
989 list.getSelectedList().addMouseListener(new MouseAdapter() {
990
991 @Override
992 public void mousePressed(MouseEvent e) {
993 boolean rightClick = SwingUtilities.isRightMouseButton(e);
994 if (rightClick) {
995 JList list = (JList) e.getSource();
996 int index = list.locationToIndex(e.getPoint());
997 list.setSelectedIndex(index);
998 }
999 }
1000 });
1001
1002
1003 list.getUniverseList().setFocusTraversalKeysEnabled(true);
1004 list.getSelectedList().setFocusTraversalKeysEnabled(true);
1005 }
1006
1007 private <E> void fixBeanListWidth(BeanDoubleList<E> list, int preferredWidth) {
1008
1009 JScrollPane scrollPane = (JScrollPane) list.get$objectMap().get("$JScrollPane0");
1010 if (scrollPane == null) {
1011 if (LOG.isWarnEnabled()) {
1012 LOG.warn("the component '$JScrollPane0' has not been found in the BeanDoubleList");
1013 }
1014 } else {
1015 scrollPane.setPreferredSize(new Dimension(preferredWidth, (int) scrollPane.getPreferredSize().getHeight()));
1016 }
1017 scrollPane = (JScrollPane) list.get$objectMap().get("$JScrollPane1");
1018 if (scrollPane == null) {
1019 if (LOG.isWarnEnabled()) {
1020 LOG.warn("the component '$JScrollPane1' has not been found in the BeanDoubleList");
1021 }
1022 } else {
1023 scrollPane.setPreferredSize(new Dimension(preferredWidth, (int) scrollPane.getPreferredSize().getHeight()));
1024 }
1025
1026 }
1027
1028
1029
1030
1031 @Override
1032 @SuppressWarnings("unchecked")
1033 protected <E> void initBeanFilterableComboBox(
1034 final BeanFilterableComboBox<E> comboBox,
1035 final List<E> data,
1036 final E selectedData,
1037 final String decoratorContext) {
1038 Preconditions.checkNotNull(comboBox, "No comboBox!");
1039
1040 final Class<E> beanType = comboBox.getBeanType();
1041
1042 Preconditions.checkNotNull(beanType, "No beanType on the combobox!");
1043
1044 Decorator<E> decorator = getDecorator(beanType, decoratorContext);
1045
1046 List<E> dataTemp = data;
1047 if (dataTemp == null) {
1048 dataTemp = Lists.newArrayList();
1049 }
1050 if (LOG.isDebugEnabled()) {
1051 LOG.debug("entity comboBox list [" + beanType.getName() + "] : " + dataTemp.size());
1052 }
1053
1054 comboBox.setI18nPrefix(getContext().getI18nPrefix());
1055
1056
1057 comboBox.init((JXPathDecorator<E>) decorator, dataTemp);
1058
1059
1060 final Decorator<E> finalDecorator = comboBox.getHandler().getDecorator();
1061
1062
1063
1064
1065 comboBox.getCombobox().setRenderer(new ExtendedDecoratorListCellRenderer(finalDecorator, UIManager.getColor("nimbusSelectionBackground"), false));
1066
1067
1068 comboBox.addPropertyChangeListener(BeanFilterableComboBox.PROPERTY_SELECTED_ITEM, new PropertyChangeListener() {
1069
1070 @Override
1071 public void propertyChange(PropertyChangeEvent evt) {
1072 E newValue = (E) evt.getNewValue();
1073 String tooltip = beanType.isInstance(newValue) ? finalDecorator.toString(newValue) : null;
1074 comboBox.getCombobox().setToolTipText(tooltip);
1075 }
1076 });
1077
1078 comboBox.setSelectedItem(selectedData);
1079
1080 if (LOG.isDebugEnabled()) {
1081 LOG.debug("combo [" + beanType.getName() + "] : " + comboBox.getData().size());
1082 }
1083 }
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098 protected void initActionComboBox(final JComboBox<?> combo) {
1099 Preconditions.checkNotNull(combo, "no combobox to init");
1100 Preconditions.checkNotNull(combo.getModel(), "the combobox has no model");
1101 Preconditions.checkArgument(combo.getModel() instanceof ActionComboBoxModel, "the combobox model must be a ActionListModel");
1102
1103 combo.setEditable(false);
1104 combo.setRenderer(new ActionListCellRenderer(combo));
1105
1106
1107 combo.addActionListener(new ActionListener() {
1108
1109 @Override
1110 public void actionPerformed(ActionEvent e) {
1111 actionComboBoxAction(e);
1112 }
1113 });
1114 combo.addMouseListener(new MouseAdapter() {
1115
1116 @Override
1117 public void mouseClicked(MouseEvent e) {
1118 JComboBox<?> combo = (JComboBox<?>) e.getSource();
1119 if (combo.isEnabled()) {
1120 actionComboBoxAction(e);
1121 }
1122 }
1123
1124 @Override
1125 public void mouseEntered(MouseEvent e) {
1126 JComboBox<?> combo = (JComboBox<?>) e.getSource();
1127 if (combo.isEnabled()) {
1128 combo.showPopup();
1129 }
1130 }
1131 });
1132 }
1133
1134
1135
1136
1137 @Override
1138 protected void initLabel(JLabel jLabel) {
1139 super.initLabel(jLabel);
1140
1141
1142 if (jLabel.getLabelFor() instanceof JComponent) {
1143 JComponent c = (JComponent) jLabel.getLabelFor();
1144 if (c.getClientProperty("validatorLabel") == null) {
1145 c.putClientProperty("validatorLabel", jLabel.getText());
1146 }
1147 }
1148 }
1149
1150
1151
1152
1153
1154
1155
1156
1157 public DefaultComboBoxModel newActionComboBoxModel(Object item, Object... items) {
1158 AbstractButton button = (AbstractButton) item;
1159 AbstractButton[] otherButtons = Arrays.copyOf(items, items.length, AbstractButton[].class);
1160 return new ActionComboBoxModel(button, otherButtons);
1161 }
1162
1163
1164
1165
1166
1167
1168 protected void actionComboBoxAction(EventObject event) {
1169 JComboBox<?> existingCombo = (JComboBox<?>) event.getSource();
1170 JButton selectedButton = (JButton) existingCombo.getSelectedItem();
1171
1172 if (existingCombo.getModel() instanceof ActionComboBoxModel) {
1173 ((ActionComboBoxModel) existingCombo.getModel()).reset();
1174 } else {
1175 existingCombo.setSelectedIndex(0);
1176 }
1177
1178
1179 existingCombo.hidePopup();
1180 if (selectedButton.isEnabled()) {
1181 if (selectedButton.getAction() != null) {
1182 getContext().getActionEngine().runAction(selectedButton);
1183 } else {
1184 selectedButton.doClick();
1185 }
1186 }
1187 }
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215 protected void registerValidators(SwingValidator... validators) {
1216 MainUI main = getContext().getMainUI();
1217 Preconditions.checkNotNull(main, "No mainUI registred in application context");
1218 AbstractMainUIHandler handler = (AbstractMainUIHandler) main.getHandler();
1219 handler.clearValidators();
1220 for (SwingValidator validator : validators) {
1221 handler.registerValidator(validator);
1222 }
1223 }
1224
1225
1226
1227
1228
1229
1230
1231 protected void listenValidatorValid(SimpleBeanValidator validator, final AbstractBeanUIModel model) {
1232
1233 stopListenValidatorValid(validator);
1234 Preconditions.checkNotNull(model);
1235
1236 PropertyChangeListener listener = new PropertyChangeListener() {
1237 @Override
1238 public void propertyChange(PropertyChangeEvent evt) {
1239 if (LOG.isDebugEnabled()) {
1240 LOG.debug("method listenValidatorValid " + "Model [" + model
1241 + "] pass to valid state ["
1242 + evt.getNewValue() + "]");
1243 }
1244 model.setValid((Boolean) evt.getNewValue());
1245 }
1246 };
1247 validator.addPropertyChangeListener(SimpleBeanValidator.VALID_PROPERTY, listener);
1248 validatorValidListenerMap.put(validator, listener);
1249 }
1250
1251
1252
1253
1254
1255
1256 protected void stopListenValidatorValid(SimpleBeanValidator validator) {
1257 PropertyChangeListener listener = validatorValidListenerMap.get(validator);
1258 if (listener != null) {
1259 validator.removePropertyChangeListener(SimpleBeanValidator.VALID_PROPERTY, listener);
1260 validatorValidListenerMap.remove(validator);
1261 }
1262 }
1263
1264
1265
1266
1267
1268
1269
1270 protected void listenValidationTableHasNoFatalError(final SimpleBeanValidator validator,
1271 final AbstractBeanUIModel model) {
1272 getContext().getMainUI().getValidatorMessageWidget().addTableModelListener(new TableModelListener() {
1273 @Override
1274 public void tableChanged(TableModelEvent e) {
1275 boolean valid = !validator.hasFatalErrors();
1276 if (LOG.isDebugEnabled()) {
1277 LOG.debug("method listenValidationTableHasNoFatalError " + "Model [" + model
1278 + "] pass to valid state [" + valid + "]");
1279 }
1280 model.setValid(valid);
1281 }
1282 });
1283 }
1284
1285
1286
1287
1288
1289
1290 protected void listModelIsModify(AbstractBeanUIModel model) {
1291 model.addPropertyChangeListener(new PropertyChangeListener() {
1292
1293 final Set<String> excludeProperties = getPropertiesToIgnore();
1294
1295 @Override
1296 public void propertyChange(PropertyChangeEvent evt) {
1297 if (!excludeProperties.contains(evt.getPropertyName())) {
1298 ((AbstractBeanUIModel) evt.getSource()).setModify(true);
1299 }
1300 }
1301 });
1302 }
1303
1304
1305
1306
1307
1308
1309 protected Set<String> getPropertiesToIgnore() {
1310 return Sets.newHashSet(
1311 AbstractBeanUIModel.PROPERTY_MODIFY,
1312 AbstractBeanUIModel.PROPERTY_VALID);
1313 }
1314
1315
1316
1317
1318
1319
1320
1321
1322 public boolean askBefore(String title, String message) {
1323 return getContext().getDialogHelper().showConfirmDialog(message, title, JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION;
1324 }
1325
1326
1327
1328
1329
1330
1331
1332 public boolean askOverwriteFile(File file) {
1333 if (!file.exists()) {
1334
1335 return true;
1336 }
1337
1338
1339 return getContext().getDialogHelper().showConfirmDialog(
1340 t("quadrige2.action.common.askOverwriteFile.message", file),
1341 t("quadrige2.action.common.askOverwriteFile.title"), DialogHelper.OVERWRITE_FILE_CANCEL_OPTION) == JOptionPane.OK_OPTION;
1342
1343 }
1344
1345
1346
1347
1348 @Override
1349 public int askSaveBeforeLeaving(String message) {
1350 return getContext().getDialogHelper().showConfirmDialog(message, t("quadrige2.action.common.askSaveBeforeLeaving.title"), DialogHelper.SAVE_NO_SAVE_CANCEL_OPTION);
1351 }
1352
1353
1354
1355
1356 @Override
1357 public boolean askCancelEditBeforeLeaving(String message) {
1358 return getContext().getDialogHelper().showConfirmDialog(
1359 message, t("quadrige2.action.common.askCancelEditBeforeLeaving.title"), DialogHelper.NO_SAVE_CANCEL_OPTION) == JOptionPane.OK_OPTION;
1360 }
1361
1362
1363
1364
1365
1366
1367
1368
1369 public boolean askBeforeDelete(String title, String message) {
1370 return getContext().getDialogHelper().showConfirmDialog(message, title, DialogHelper.DELETE_CANCEL_OPTION) == JOptionPane.OK_OPTION;
1371 }
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381 public boolean askBeforeDeleteMany(String title, String message, List<String> list) {
1382 return getContext().getDialogHelper().showConfirmDialog(message, ApplicationUIUtil.getHtmlString(list), null, title, DialogHelper.DELETE_CANCEL_OPTION) == JOptionPane.OK_OPTION;
1383 }
1384
1385
1386
1387
1388
1389
1390
1391 public int askBeforeChangeTab(String message) {
1392 return getContext().getDialogHelper().showConfirmDialog(message, t("quadrige2.action.common.askBeforeChangeTab.title"), DialogHelper.SAVE_NO_SAVE_CANCEL_OPTION);
1393 }
1394
1395
1396
1397
1398
1399
1400
1401
1402 public boolean askBeforeReset(String title, String message) {
1403 return getContext().getDialogHelper().showConfirmDialog(message, title, DialogHelper.RESET_CANCEL_OPTION) == JOptionPane.OK_OPTION;
1404 }
1405
1406
1407
1408
1409
1410
1411
1412 public boolean askDeleteInvalidBeforeLeaving(String message) {
1413 return getContext().getDialogHelper().showConfirmDialog(
1414 message, t("quadrige2.action.common.askDeleteInvalidBeforeLeaving.title"), DialogHelper.DELETE_INVALID_CANCEL_OPTION) == JOptionPane.OK_OPTION;
1415 }
1416
1417
1418
1419
1420 @Override
1421 protected void initScrollPane(JScrollPane scrollPane) {
1422
1423
1424 Boolean onlyVerticalScrollable = (Boolean) scrollPane.getClientProperty("onlyVerticalScrollable");
1425 if (onlyVerticalScrollable != null && onlyVerticalScrollable) {
1426 scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
1427 scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
1428
1429
1430 Component component = scrollPane.getViewport().getView();
1431 JXPanel innerPanel = new JXPanel(new BorderLayout());
1432 innerPanel.add(component);
1433 scrollPane.setViewportView(innerPanel);
1434 innerPanel.setScrollableTracksViewportHeight(false);
1435 innerPanel.setScrollableTracksViewportWidth(true);
1436 }
1437
1438
1439 if (scrollPane.getViewport().getComponentCount() > 0) {
1440 boolean isTable = false;
1441 for (Component component : scrollPane.getViewport().getComponents()) {
1442 if (component instanceof JTable) {
1443 isTable = true;
1444 break;
1445 }
1446 }
1447 if (!isTable) {
1448 scrollPane.getVerticalScrollBar().setUnitIncrement(20);
1449 }
1450 }
1451 }
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462 public void openDialog(JDialog dialog) {
1463 openDialog(dialog, null);
1464 }
1465
1466
1467
1468
1469
1470
1471
1472 public void openDialog(JDialog dialog, Dimension size) {
1473 openDialog(dialog, size, false);
1474 }
1475
1476
1477
1478
1479
1480
1481 public void openDialogForceOnTop(JDialog dialog) {
1482 openDialogForceOnTop(dialog, null);
1483 }
1484
1485
1486
1487
1488
1489
1490
1491 public void openDialogForceOnTop(JDialog dialog, Dimension size) {
1492 openDialog(dialog, size, true);
1493 }
1494
1495 private void openDialog(JDialog dialog, Dimension size, boolean forceOnTop) {
1496
1497
1498 ActionUI oldApplicationActionUI = getContext().getActionUI();
1499
1500 try {
1501
1502 final ActionUI dialogActionUI = new ActionUI(dialog, true) {
1503 @Override
1504 protected ApplicationActionUIHandler createHandler() {
1505
1506 ApplicationUIUtil.setApplicationContext(this, getContext());
1507 return super.createHandler();
1508 }
1509 };
1510 getContext().setActionUI(dialogActionUI);
1511
1512
1513 initDialog(dialog, null);
1514
1515 if (CollectionUtils.isEmpty(dialog.getIconImages())) {
1516 dialog.setIconImage(getContext().getMainUI().getIconImage());
1517 }
1518
1519 if (size != null) {
1520 dialog.setSize(size);
1521 } else {
1522 dialog.pack();
1523 }
1524
1525
1526
1527
1528 SwingUtil.center(getContext().getMainUI(), dialog);
1529
1530 dialog.setModalityType(forceOnTop
1531 ? Dialog.ModalityType.TOOLKIT_MODAL
1532 : Dialog.ModalityType.APPLICATION_MODAL);
1533 dialog.setVisible(true);
1534
1535 } finally {
1536
1537
1538 getContext().setActionUI(oldApplicationActionUI);
1539 }
1540
1541 }
1542
1543 @Override
1544 public void openDialog(org.nuiton.jaxx.application.swing.ApplicationUI dialogContent, String title, Dimension dim) {
1545
1546 Component topestUI = getTopestUI();
1547
1548 JDialog dialog;
1549 if (topestUI instanceof Frame) {
1550 dialog = new JDialog((Frame) topestUI, title, true);
1551 } else {
1552 dialog = new JDialog((Dialog) topestUI, title, true);
1553 }
1554
1555
1556 initDialog(dialog, dialogContent.getHandler());
1557
1558 dialog.setIconImage(getContext().getMainUI().getIconImage());
1559 Component dialogComponent = (Component) dialogContent;
1560 dialogComponent.setVisible(true);
1561 dialog.add(dialogComponent);
1562 dialog.setResizable(true);
1563 dialog.setName("dialog_" + dialogComponent.getName());
1564
1565 if (dim != null) {
1566 dialog.setSize(dim);
1567 } else {
1568 dialog.pack();
1569 }
1570
1571
1572
1573
1574 SwingUtil.center(getContext().getMainUI(), dialog);
1575 dialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
1576 dialog.setVisible(true);
1577 }
1578
1579 public JFrame createFrame(ApplicationUI dialogContent, String title, Image iconImage, Rectangle dim) {
1580
1581 JFrame frame = new JFrame();
1582 frame.setTitle(getContext().getMainUI().getTitle() + (StringUtils.isNotEmpty(title) ? " - " + title : ""));
1583 if (iconImage != null) {
1584 frame.setIconImage(iconImage);
1585 } else {
1586 frame.setIconImage(getContext().getMainUI().getIconImage());
1587 }
1588
1589 Container dialogComponent;
1590 if (dialogContent instanceof Container) {
1591 dialogComponent = (Container) dialogContent;
1592 } else {
1593 dialogComponent = new JPanel(new BorderLayout());
1594 dialogComponent.add((Component) dialogContent);
1595 }
1596
1597
1598 initDialog(frame, dialogContent.getHandler());
1599 dialogComponent.setVisible(true);
1600 frame.setContentPane(dialogComponent);
1601 frame.setName("frame_" + dialogComponent.getName());
1602
1603 if (dim != null) {
1604 frame.setBounds(dim);
1605 } else {
1606 frame.pack();
1607 }
1608
1609 frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
1610 return frame;
1611 }
1612
1613 public JFrame openFrame(ApplicationUI dialogContent, String title, Image iconImage, Rectangle dim) {
1614
1615 JFrame frame = createFrame(dialogContent, title, iconImage, dim);
1616 SwingUtilities.invokeLater(() -> frame.setVisible(true));
1617 return frame;
1618 }
1619
1620 private void initDialog(Window dialog, AbstractApplicationUIHandler dialogHandler) {
1621
1622 final AbstractApplicationUIHandler handler;
1623 if (dialogHandler == null) {
1624 handler = dialog instanceof ApplicationUI
1625 ? ((ApplicationUI) dialog).getHandler()
1626 : null;
1627 } else {
1628 handler = dialogHandler;
1629 }
1630
1631 if (handler instanceof Cancelable) {
1632
1633
1634 final Action cancelAction = new AbstractAction() {
1635
1636 @Override
1637 public void actionPerformed(ActionEvent e) {
1638 ((Cancelable) handler).cancel();
1639 }
1640 };
1641
1642 JRootPane rootPane = ((RootPaneContainer) dialog).getRootPane();
1643 KeyStroke shortcutClosePopup = getContext().getConfiguration().getShortcutClosePopup();
1644 rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(shortcutClosePopup, "close");
1645 rootPane.getActionMap().put("close", cancelAction);
1646
1647 dialog.addWindowListener(new WindowAdapter() {
1648 @Override
1649 public void windowClosing(WindowEvent e) {
1650 cancelAction.actionPerformed(null);
1651 }
1652 });
1653 }
1654
1655 dialog.addWindowListener(new WindowAdapter() {
1656
1657 @Override
1658 public void windowClosed(WindowEvent e) {
1659 closeDialog();
1660 }
1661 });
1662
1663 }
1664
1665
1666
1667
1668 @Override
1669 public void closeDialog() {
1670
1671
1672
1673
1674
1675 if (getUI() instanceof JDialog) {
1676 if (LOG.isDebugEnabled()) {
1677 LOG.debug("Destroy dialog " + getUI());
1678 }
1679 ((JDialog) getUI()).dispose();
1680 } else {
1681 JDialog parent = getParentContainer(JDialog.class);
1682 if (parent != null) {
1683 if (LOG.isDebugEnabled()) {
1684 LOG.debug("Destroy dialog " + parent + " of " + getUI());
1685 }
1686 parent.dispose();
1687 }
1688 }
1689 }
1690
1691 @Override
1692 protected void addHighlighters(JXTable table) {
1693
1694 }
1695
1696 private class BoldFontHighlighter extends AbstractHighlighter {
1697
1698 public BoldFontHighlighter(HighlightPredicate predicate) {
1699 super(predicate);
1700 }
1701
1702 @Override
1703 protected Component doHighlight(Component component, ComponentAdapter adapter) {
1704 if (component.getFont().isItalic()) {
1705 component.setFont(component.getFont().deriveFont(Font.BOLD + Font.ITALIC));
1706 } else {
1707 component.setFont(component.getFont().deriveFont(Font.BOLD));
1708 }
1709 return component;
1710 }
1711 }
1712 }