View Javadoc
1   package fr.ifremer.quadrige2.ui.swing.common.component.bean;
2   
3   /*-
4    * #%L
5    * Quadrige2 Core :: Quadrige2 UI Common
6    * $Id:$
7    * $HeadURL:$
8    * %%
9    * Copyright (C) 2017 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  
27  import jaxx.runtime.swing.editor.bean.BeanFilterableComboBox;
28  import jaxx.runtime.swing.editor.bean.BeanFilterableComboBoxHandler;
29  import org.apache.commons.lang3.StringUtils;
30  import org.nuiton.decorator.JXPathDecorator;
31  
32  import javax.swing.text.JTextComponent;
33  import java.awt.*;
34  import java.awt.event.*;
35  import java.beans.PropertyChangeEvent;
36  import java.beans.PropertyChangeListener;
37  import java.util.List;
38  
39  import static org.nuiton.i18n.I18n.t;
40  
41  /**
42   * Le handler d'un {@link fr.ifremer.quadrige2.ui.swing.common.component.bean.ExtendedComboBox}.
43   * <p/>
44   * Note: ce handler n'est pas stateless et n'est donc pas partageable entre
45   * plusieurs ui.
46   *
47   * @param <O> le type des objet contenus dans le modèle du composant.
48   * @author Ludovic
49   * @see ExtendedComboBox
50   */
51  public class ExtendedComboBoxHandler<O> extends BeanFilterableComboBoxHandler<O> implements FocusListener {
52  
53      /**
54       * ui if the handler
55       */
56      protected final ExtendedComboBox<O> ui;
57  
58      /**
59       * delegate action listener executed when action button is pressed
60       */
61      ActionListener actionListener;
62  
63      /**
64       * <p>Constructor for ExtendedComboBoxHandler.</p>
65       *
66       * @param ui a {@link jaxx.runtime.swing.editor.bean.BeanFilterableComboBox} object.
67       */
68      @SuppressWarnings("unchecked")
69      public ExtendedComboBoxHandler(BeanFilterableComboBox ui) {
70          super(ui);
71          this.ui = (ExtendedComboBox<O>) ui;
72      }
73  
74      /** {@inheritDoc} */
75      @Override
76      @SuppressWarnings("unchecked")
77      public void init(JXPathDecorator decorator, List data) {
78  
79          // Override default model
80          ui.getCombobox().setModel(new ExtendedComboBoxModel<O>());
81  
82          super.init(decorator, data);
83  
84          ui.getCombobox().getEditor().getEditorComponent().setFocusTraversalKeysEnabled(false);
85          ui.getCombobox().getEditor().getEditorComponent().addKeyListener(new KeyAdapter() {
86  
87              @Override
88              public void keyPressed(final KeyEvent e) {
89                  if (KeyEvent.VK_TAB == e.getKeyCode()) {
90  
91                      // simulate ENTER key action when TAB key pressed
92                      Component editor = ui.getCombobox().getEditor().getEditorComponent();
93                      KeyEvent enterEvent = new KeyEvent(editor, KeyEvent.KEY_PRESSED, e.getWhen() + 1, 0, KeyEvent.VK_ENTER, '\r');
94                      editor.dispatchEvent(enterEvent);
95                      enterEvent = new KeyEvent(editor, KeyEvent.KEY_RELEASED, e.getWhen() + 2, 0, KeyEvent.VK_ENTER, '\r');
96                      editor.dispatchEvent(enterEvent);
97  
98                      if (e.isShiftDown()) {
99                          KeyboardFocusManager.getCurrentKeyboardFocusManager().focusPreviousComponent();
100                     } else {
101                         KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent();
102                     }
103 
104                     return;
105                 }
106                 super.keyPressed(e);
107             }
108 
109             @Override
110             public void keyReleased(KeyEvent e) {
111                 if (KeyEvent.VK_TAB == e.getKeyCode()) {
112                     e.consume();
113                     return;
114                 }
115                 super.keyReleased(e);
116             }
117         });
118         ui.getCombobox().addFocusListener(this);
119         ui.getCombobox().getEditor().getEditorComponent().addFocusListener(this);
120 
121         ui.addPropertyChangeListener(BeanFilterableComboBox.PROPERTY_SELECTED_ITEM, new PropertyChangeListener() {
122             @Override
123             public void propertyChange(PropertyChangeEvent evt) {
124                 resetCaretPosition();
125             }
126         });
127 
128         ui.removeDataBinding(BeanFilterableComboBox.BINDING_TOOLBAR_RIGHT_VISIBLE);
129         ui.getToolbarRight().setVisible(true);
130 
131         initActionButton();
132     }
133 
134     /** {@inheritDoc} */
135     @Override
136     protected void setSelectedItem(O oldValue, O newValue) {
137         super.setSelectedItem(oldValue, newValue);
138         resetCaretPosition();
139     }
140 
141     /** {@inheritDoc} */
142     @Override
143     public void focusGained(FocusEvent e) {
144     }
145 
146     /** {@inheritDoc} */
147     @Override
148     public void focusLost(FocusEvent e) {
149         resetCaretPosition();
150     }
151 
152     /**
153      * <p>resetCaretPosition.</p>
154      */
155     protected void resetCaretPosition() {
156         JTextComponent editor = (JTextComponent) ui.getCombobox().getEditor().getEditorComponent();
157         editor.moveCaretPosition(0);
158     }
159 
160     private void initActionButton() {
161         if (ui.showActionButton) {
162             if (ui.getIcon() != null) {
163                 ui.getActionButton().setIcon(ui.getIcon());
164             }
165             if (StringUtils.isNotBlank(ui.getActionToolTipI18n())) {
166                 ui.getActionButton().setToolTipText(t(ui.getActionToolTipI18n()));
167             }
168         }
169     }
170 
171     /**
172      * <p>doAction.</p>
173      */
174     public void doAction() {
175         if (actionListener != null) {
176             actionListener.actionPerformed(null);
177         }
178     }
179 
180     /**
181      * <p>Setter for the field <code>actionListener</code>.</p>
182      *
183      * @param actionListener a {@link java.awt.event.ActionListener} object.
184      */
185     public void setActionListener(ActionListener actionListener) {
186         this.actionListener = actionListener;
187     }
188 
189 }