View Javadoc

1   /*
2      Copyright 2002-2006 Martin van den Bemt
3   
4      Licensed under the Apache License, Version 2.0 (the "License");
5      you may not use this file except in compliance with the License.
6      You may obtain a copy of the License at
7   
8          http://www.apache.org/licenses/LICENSE-2.0
9   
10     Unless required by applicable law or agreed to in writing, software
11     distributed under the License is distributed on an "AS IS" BASIS,
12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13     See the License for the specific language governing permissions and
14     limitations under the License.
15  */
16  package org.xulux.guilayer.swing.widgets;
17  
18  import java.awt.Container;
19  import java.awt.event.FocusEvent;
20  import java.awt.event.FocusListener;
21  import java.awt.event.KeyListener;
22  
23  import org.xulux.api.gui.IXuluxListener;
24  import org.xulux.gui.XuluxCombo;
25  import org.xulux.gui.XuluxListener;
26  import org.xulux.gui.utils.ColorUtils;
27  import org.xulux.gui.utils.XuluxEventQueue;
28  import org.xulux.guilayer.swing.extensions.NyxJComboBox;
29  import org.xulux.guilayer.swing.listeners.ImmidiateListener;
30  import org.xulux.guilayer.swing.listeners.PrePostFieldListener;
31  import org.xulux.guilayer.swing.models.DefaultComboModel;
32  
33  /**
34   * The swing combo widget.
35   *
36   * @author <a href="mailto:martin@mvdb.net">Martin van den Bemt</a>
37   * @version $Id: Combo.java,v 1.1 2005/12/18 12:58:18 mvdb Exp $
38   */
39  public class Combo extends XuluxCombo {
40      /**
41       * The native combobox
42       */
43      private NyxJComboBox combo;
44      /**
45       * The key listener
46       */
47      private KeyListener keyListener;
48      /**
49       * the combo model
50       */
51      private DefaultComboModel model;
52      /**
53       * the actionlistener
54       */
55      private PrePostFieldListener actionListener;
56      /**
57       * The focus event listener. We cannot use
58       * the prepostlistener, since that would trigger
59       * field processing code, we just need to release
60       * the queue when focus is gained.
61       */
62      private FocusEventListener focusEventListener;
63  
64      /**
65       * Constructor for NyxCombo.
66       * @param name the name of the combo
67       */
68      public Combo(String name) {
69          super(name);
70      }
71  
72      /**
73       * @see org.xulux.api.gui.IWidget#getNativeWidget()
74       */
75      public Object getNativeWidget() {
76          initialize();
77          return combo;
78      }
79  
80  
81      /**
82       * @see org.xulux.api.gui.IWidget#destroy()
83       */
84      public void destroy() {
85          processDestroy();
86          removeAllRules();
87          if (combo != null) {
88              if (actionListener != null) {
89                  combo.removeActionListener(actionListener);
90                  actionListener = null;
91              }
92              if (keyListener != null) {
93                  combo.removeKeyListener(keyListener);
94                  keyListener = null;
95              }
96              if (focusEventListener != null) {
97                  combo.removeFocusListener(focusEventListener);
98                  focusEventListener = null;
99              }
100             combo.removeAll();
101             Container container = combo.getParent();
102             if (container != null) {
103                 container.remove(combo);
104             }
105             combo = null;
106         }
107         super.destroy();
108     }
109 
110 
111     /**
112      * @see org.xulux.api.gui.IWidget#initialize()
113      */
114     public void initialize() {
115 
116         if (this.initialized) {
117             return;
118         }
119         contentChanged = true;
120         this.initialized = true;
121         String nsv = getProperty("notselectedvalue");
122         if (nsv != null) {
123             this.notSelectedValue = nsv;
124         }
125         combo = new NyxJComboBox();
126         // add a focuslistener to be able to free the eventqueue..
127         this.focusEventListener = new FocusEventListener();
128         combo.addFocusListener(this.focusEventListener);
129         refresh();
130         processInit();
131     }
132 
133 
134     /**
135      * @see org.xulux.api.gui.IWidget#refresh()
136      */
137     public void refresh() {
138         if (settingValue) {
139             return;
140         }
141         if (isRefreshing()) {
142             return;
143         }
144         isRefreshing = true;
145         initialize();
146         if (isImmidiate() && keyListener == null) {
147             keyListener = new ImmidiateListener(this);
148             combo.addKeyListener(keyListener);
149         } else if (!isImmidiate() && keyListener != null) {
150             combo.removeKeyListener(keyListener);
151         }
152         // for now commented out. This makes the combo editable, when the
153         // table columns are editable.
154         //combo.setEditable(BooleanUtils.toBoolean(getProperty("editable")));
155         combo.setEnabled(isEnabled());
156         combo.setVisible(isVisible());
157         if (contentChanged) {
158             initializeContent();
159             initializeNotSelectedValue();
160             if (this.model != null) {
161                 this.model.destroy();
162             }
163             if (content != null) {
164                 this.model = new DefaultComboModel(content, getProperty("combofields"), this);
165             } else {
166                 this.model = new DefaultComboModel();
167             }
168             combo.setModel(this.model);
169             if (this.actionListener == null) {
170                 IXuluxListener listener = getPart().getFieldEventHandler(this);
171                 if (listener != null) {
172                     this.actionListener = (PrePostFieldListener) listener;
173                 } else {
174                     this.actionListener = new PrePostFieldListener(this);
175                 }
176                 combo.addActionListener(this.actionListener);
177             }
178             contentChanged = false;
179         }
180         if (getValue() instanceof DefaultComboModel.ComboShowable) {
181             model.setSelectedItem(getValue());
182         } else {
183             if (content != null && getValue() != null) {
184                 System.out.println("Setting value to : " + getValue());
185                 model.setRealSelectedValue(getValue());
186             } else if (model != null && content != null && getValue() == null) {
187                 // if we don't have a value select
188                 // the first one in the list
189                 System.out.println("Select the first one in the list");
190                 if (!content.isEmpty()) {
191                     model.setSelectedItem(0);
192                     if (getField() == null && getProvider() == null) {
193                         this.value = model.getRealSelectedValue();
194                     } else if (getProvider() == null) {
195                         setValue(model.getRealSelectedValue(), false);
196                     }
197                 }
198             }
199             if (model != null && model.getSelectedIndex() == 0 && contentChanged && getProvider() == null) {
200                 this.value = model.getRealSelectedValue();
201             }
202         }
203         String backgroundColor = null;
204         if (isRequired() && isEnabled()) {
205             backgroundColor = getProperty("required-background-color");
206         } else if (!isEnabled()) {
207             backgroundColor = getProperty("disabled-background-color");
208         } else {
209             backgroundColor = getProperty("default-background-color");
210         }
211         if (backgroundColor != null) {
212             combo.setBackground(ColorUtils.getSwingColor(backgroundColor));
213         }
214         isRefreshing = false;
215     }
216 
217     /**
218      * @see org.xulux.api.gui.IWidget#focus()
219      */
220     public void focus() {
221         combo.requestFocus();
222     }
223 
224 
225     /**
226      * @see org.xulux.api.gui.IWidget#getGuiValue()
227      */
228     public Object getGuiValue() {
229         if (this.model != null) {
230             return this.model.getRealSelectedValue();
231         } else {
232             return null;
233         }
234     }
235 
236 
237     /**
238      * @see org.xulux.api.gui.IWidget#canContainValue()
239      */
240     public boolean canContainValue() {
241         return true;
242     }
243 
244     /**
245      * @see org.xulux.api.gui.IWidget#isValueEmpty()
246      */
247     public boolean isValueEmpty() {
248         if (getGuiValue() == null || getGuiValue().equals("") || getGuiValue().equals(getNotSelectedValue())) {
249             return true;
250         }
251         return false;
252     }
253 
254     /**
255      * This is a hack to get a focusevent for the combobox.
256      * I need to handle post rules correctly..
257      */
258     public final class FocusEventListener extends XuluxListener implements FocusListener {
259         /**
260          * @see java.awt.event.FocusListener#focusGained(java.awt.event.FocusEvent)
261          */
262         public void focusGained(FocusEvent e) {
263             // free up the eventqueue when combo gains focus..
264             XuluxEventQueue q = XuluxEventQueue.getInstance();
265             if (q != null) {
266                 q.holdEvents(false);
267             }
268         }
269 
270         /**
271          * @see java.awt.event.FocusListener#focusLost(java.awt.event.FocusEvent)
272          */
273         public void focusLost(FocusEvent e) {
274         }
275 
276     }
277 
278 
279     /**
280      * @see org.xulux.api.gui.IContentWidget#contentChanged()
281      */
282     public void contentChanged() {
283         contentChanged = true;
284     }
285     
286     /**
287      * @return the model of the combo or null if non present
288      */
289     public DefaultComboModel getModel() {
290         return this.model;
291     }
292 }