View Javadoc
1   package fr.ifremer.allegro.obsdeb.ui.swing.util.table.component;
2   
3   /*
4    * #%L
5    * SIH Allegro ObsDeb :: UI
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2013 - 2014 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 fr.ifremer.allegro.obsdeb.dto.ObsdebEntity;
27  import jaxx.runtime.swing.editor.bean.BeanFilterableComboBox;
28  import org.apache.commons.collections4.CollectionUtils;
29  
30  import javax.swing.*;
31  import javax.swing.event.AncestorEvent;
32  import javax.swing.event.AncestorListener;
33  import javax.swing.table.TableCellEditor;
34  import javax.swing.text.JTextComponent;
35  import java.awt.*;
36  import java.awt.event.FocusEvent;
37  import java.awt.event.FocusListener;
38  import java.awt.event.MouseEvent;
39  import java.beans.PropertyChangeEvent;
40  import java.beans.PropertyChangeListener;
41  import java.util.EventObject;
42  import java.util.Objects;
43  
44  /**
45   *
46   * @author Ludovic Pecquot (ludovic.pecquot@e-is.pro)
47   */
48  public class FilterableComboBoxCellEditor<B extends ObsdebEntity> extends AbstractCellEditor implements TableCellEditor, FocusListener, AncestorListener {
49  
50      private final BeanFilterableComboBox<B> combo;
51  
52      private boolean dirty;
53  
54      public BeanFilterableComboBox<B> getCombo() {
55          return combo;
56      }
57  
58      public FilterableComboBoxCellEditor(BeanFilterableComboBox<B> comboBox) {
59          combo = comboBox;
60          combo.getCombobox().setPopupVisible(false);
61          combo.getCombobox().addFocusListener(this);
62          combo.getCombobox().getEditor().getEditorComponent().addFocusListener(this);
63          combo.getCombobox().addAncestorListener(this);
64  
65          combo.addPropertyChangeListener(BeanFilterableComboBox.PROPERTY_SELECTED_ITEM, new PropertyChangeListener() {
66  
67              @Override
68              public void propertyChange(PropertyChangeEvent evt) {
69                  Object oldValue = "".equals(evt.getOldValue()) ? null : evt.getOldValue();
70                  Object newValue = "".equals(evt.getNewValue()) ? null : evt.getNewValue();
71  
72                  dirty = !Objects.equals(oldValue, newValue);
73              }
74          });
75      }
76  
77      public boolean isDirty() {
78          return dirty;
79      }
80  
81      public void resetDirty() {
82          dirty = false;
83      }
84  
85      @Override
86      public Object getCellEditorValue() {
87          Object selectedItem = combo.getSelectedItem();
88          if (combo.getBeanType().isInstance(selectedItem)) {
89              return selectedItem;
90          }
91          return null;
92      }
93  
94      @Override
95      public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
96  
97          combo.setMaximumSize(new Dimension(combo.getSize().width, table.getRowHeight(row)));
98  
99          // set the selected item in the combo by comparing each item with value 
100         // because combo.setSelectedItem(value); won't select perfectly the correct item
101         Object dataToSelect = value;
102         if (value != null) {
103             if (CollectionUtils.isNotEmpty(combo.getData())) {
104                 for (Object data : combo.getData()) {
105                     // use the correct comparator to detect equals object
106                     if (Objects.equals(data, value)) {
107                         dataToSelect = data;
108                         break;
109                     }
110                 }
111             }
112         }
113         combo.setSelectedItem(dataToSelect);
114 
115         return combo;
116     }
117 
118     @Override
119     public boolean shouldSelectCell(EventObject anEvent) {
120         if (anEvent instanceof MouseEvent) {
121             MouseEvent e = (MouseEvent) anEvent;
122             return e.getID() != MouseEvent.MOUSE_DRAGGED;
123         }
124         return true;
125     }
126 
127     @Override
128     public void focusGained(FocusEvent e) {
129         focusComboBox();
130     }
131 
132     @Override
133     public void focusLost(FocusEvent e) {
134     }
135 
136     @Override
137     public void ancestorAdded(AncestorEvent event) {
138         focusComboBox();
139     }
140 
141     @Override
142     public void ancestorRemoved(AncestorEvent event) {
143     }
144 
145     @Override
146     public void ancestorMoved(AncestorEvent event) {
147     }
148 
149     private void focusComboBox() {
150 
151         resetDirty();
152 
153         SwingUtilities.invokeLater(new Runnable() {
154             @Override
155             public void run() {
156                 JTextComponent component = (JTextComponent) combo.getCombobox().getEditor().getEditorComponent();
157                 component.selectAll();
158                 component.requestFocusInWindow();
159             }
160         });
161     }
162 
163 }