001: //** Copyright Statement ***************************************************
002: //The Salmon Open Framework for Internet Applications (SOFIA)
003: // Copyright (C) 1999 - 2002, Salmon LLC
004: //
005: // This program is free software; you can redistribute it and/or
006: // modify it under the terms of the GNU General Public License version 2
007: // as published by the Free Software Foundation;
008: //
009: // This program is distributed in the hope that it will be useful,
010: // but WITHOUT ANY WARRANTY; without even the implied warranty of
011: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: // GNU General Public License for more details.
013: //
014: // You should have received a copy of the GNU General Public License
015: // along with this program; if not, write to the Free Software
016: // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
017: //
018: // For more information please visit http://www.salmonllc.com
019: //** End Copyright Statement ***************************************************
020:
021: package com.salmonllc.swing;
022:
023: import com.salmonllc.swing.events.ValueChangedEvent;
024: import com.salmonllc.swing.events.ValueChangedListener;
025: import com.salmonllc.sql.DataStoreBuffer;
026: import com.salmonllc.sql.ModelChangedEvent;
027: import com.salmonllc.sql.ModelChangedListener;
028: import com.salmonllc.sql.DataStoreException;
029:
030: import java.util.Vector;
031: import javax.swing.*;
032: import javax.swing.text.JTextComponent;
033:
034: /**
035: * SOFIA implementation of a JComboBox. This Combo Box can be bound to a DataStore column
036: */
037:
038: public class SComboBox extends JComboBox implements SComponent,
039: ModelChangedListener {
040: private SComponentHelper _helper;
041: private String _dsCol;
042: private DataStoreBuffer _ds;
043:
044: /**
045: * Constructor for SComboBox.
046: * @param items
047: */
048: public SComboBox(Object[] items) {
049: super (items);
050: _helper = new SComponentHelper(this );
051: }
052:
053: /**
054: * Constructor for SComboBox.
055: * @param items
056: */
057: public SComboBox(Vector items) {
058: super (items);
059: _helper = new SComponentHelper(this );
060: }
061:
062: /**
063: * Creates a <code>JComboBox</code> with a default data model.
064: * The default data model is an empty list of objects.
065: * Use <code>addItem</code> to add items. By default the first item
066: * in the data model becomes selected.
067: *
068: * @see javax.swing.DefaultComboBoxModel
069: */
070: public SComboBox() {
071: super ();
072: _helper = new SComponentHelper(this );
073: }
074:
075: /**
076: * Binds the component to a DataStore column
077: * @param dsb The DataStore to bind to
078: * @param column The column to bind to
079: */
080: public void setColumn(DataStoreBuffer dsb, String column) {
081: _ds = dsb;
082: _dsCol = column;
083: _ds.addModelChangedListener(this );
084: evalColumn();
085: }
086:
087: /**
088: * @see com.salmonllc.sql.ModelChangedListener#modelChanged(com.salmonllc.sql.ModelChangedEvent)
089: */
090: public void modelChanged(ModelChangedEvent evt) {
091: evalColumn();
092: }
093:
094: private void evalColumn() {
095: _helper.setDataDirty(true);
096: try {
097: if (_ds != null && _dsCol != null) {
098: String value = _ds.getFormattedString(_dsCol);
099: ComboBoxModel mod = getModel();
100: boolean found = false;
101: for (int i = 0; i < mod.getSize(); i++) {
102: Object o = mod.getElementAt(i);
103: if (o.equals(value)) {
104: mod.setSelectedItem(o);
105: found = true;
106: break;
107: }
108: }
109: if (!found) {
110: if (isEditable())
111: ((JTextComponent) getEditor()
112: .getEditorComponent()).setText(value);
113: else {
114: _helper.setDataDirty(true);
115: setSelectedItem(null);
116: }
117: }
118: }
119: } catch (Exception e) {
120: getModel().setSelectedItem(null);
121: }
122: _helper.setDataDirty(false);
123:
124: }
125:
126: /**
127: * Returns the value of the data in the component
128: */
129: public String getValue() {
130: try {
131: if (_ds != null) {
132: if (_helper.isDataDirty())
133: return getSelValue();
134: else
135: return _ds.getFormattedString(_dsCol);
136: }
137: } catch (DataStoreException ex) {
138: ex.printStackTrace();
139: return null;
140: }
141: return getSelValue();
142:
143: }
144:
145: private String getSelValue() {
146: Object o = getModel().getSelectedItem();
147: if (o == null)
148: return null;
149: if (o instanceof SOption)
150: return ((SOption) o).getKey();
151: return o.toString();
152: }
153:
154: public void setValue(String value) {
155: setSelectedIndex(-1);
156: for (int i = 0; i < getItemCount(); i++) {
157: Object o = getItemAt(i);
158: if (o instanceof SOption) {
159: if (SComponentHelper.valuesEqual(
160: ((SOption) o).getKey(), value)) {
161: setSelectedIndex(i);
162: return;
163: }
164: }
165: }
166: }
167:
168: /**
169: * This method is used by the framework and should not be called directly
170: */
171: public ValueChangedEvent generateValueChangedEvent() {
172: try {
173: if (_ds == null)
174: return null;
175: else
176: return new ValueChangedEvent(this , _ds
177: .getFormattedString(_dsCol), getSelValue(),
178: _ds, _ds.getRow(), _ds.getColumnIndex(_dsCol));
179: } catch (Exception e) {
180: e.printStackTrace();
181: return null;
182: }
183: }
184:
185: /**
186: * This method is used by the framework and should not be called directly
187: */
188: public SComponentHelper getHelper() {
189: return _helper;
190: }
191:
192: /**
193: * This method adds a listener the will be notified when the value in this component changes.
194: * @param l The listener to add.
195: */
196: public void addValueChangedListener(ValueChangedListener l) {
197: _helper.addValueChangedListener(l);
198: }
199:
200: /**
201: * This method removes a listener from the list that will be notified if the text in the component changes.
202: * @param l The listener to remove.
203: */
204: public void removeValueChangedListener(ValueChangedListener l) {
205: _helper.removeValueChangedListener(l);
206: }
207:
208: /**
209: * Adds an option to the combo box
210: */
211: public void addOption(SOption opt) {
212: addItem(opt);
213: }
214:
215: /**
216: * Returns an array of items in the combo box
217: */
218: public Object[] getItems() {
219: Object o[] = new Object[getItemCount()];
220: for (int i = 0; i < getItemCount(); i++) {
221: o[i] = getItemAt(i);
222: }
223: return o;
224: }
225:
226: /**
227: * Sets the selected item in the combo box display area to the object in
228: * the argument.
229: * If <code>anObject</code> is in the list, the display area shows
230: * <code>anObject</code> selected.
231: * <p>
232: * If <code>anObject</code> is <i>not</i> in the list and the combo box is
233: * uneditable, it will not change the current selection. For editable
234: * combo boxes, the selection will change to <code>anObject</code>.
235: * <p>
236: * If this constitutes a change in the selected item,
237: * <code>ItemListener</code>s added to the combo box will be notified with
238: * one or two <code>ItemEvent</code>s.
239: * If there is a current selected item, an <code>ItemEvent</code> will be
240: * fired and the state change will be <code>ItemEvent.DESELECTED</code>.
241: * If <code>anObject</code> is in the list and is not currently selected
242: * then an <code>ItemEvent</code> will be fired and the state change will
243: * be <code>ItemEvent.SELECTED</code>.
244: * <p>
245: * <code>ActionListener</code>s added to the combo box will be notified
246: * with an <code>ActionEvent</code> when this method is called.
247: *
248: * @param anObject the list object to select; use <code>null</code> to
249: clear the selection
250: */
251: public void setSelectedItem(Object anObject) {
252: ComboBoxModel mod = getModel();
253: Object nullOption = null;
254: for (int i = 0; i < mod.getSize(); i++) {
255: Object o = mod.getElementAt(i);
256: if (o.equals(anObject)) {
257: mod.setSelectedItem(o);
258: return;
259: }
260: if (o instanceof SOption && ((SOption) o).getKey() == null)
261: nullOption = o;
262: }
263: mod.setSelectedItem(nullOption);
264:
265: }
266: }
|