001: package net.xoetrope.optional.data;
002:
003: import java.util.Hashtable;
004:
005: import java.awt.Component;
006:
007: import net.xoetrope.xui.XListHolder;
008: import net.xoetrope.xui.XProjectManager;
009: import net.xoetrope.xui.data.XDataBinding;
010: import net.xoetrope.xui.data.XModel;
011: import net.xoetrope.optional.data.sql.DatabaseTableModelAdapter;
012: import net.xoetrope.optional.data.sql.DatabaseTableModel;
013:
014: /**
015: * A data binding for list components, including drop down lists. This binding
016: * allows a key field to be chosen so that records may be chosen using a key
017: * (or ID) value. A display field can also be specified so that the list need
018: * not display the first field from the table.
019: * <p>Copyright Xoetrope (c) 2001-2004</p>
020: * $Revision: 1.3 $
021: */
022: public class XListTableBinding implements XDataBinding {
023: protected DatabaseTableModelAdapter modelAdapter;
024: protected XListHolder target;
025: protected XModel outputNode;
026: protected String outputPath;
027: protected String sourcePath;
028:
029: protected boolean useUnique;
030:
031: protected int displayColumnIdx;
032: protected int keyColumnIdx;
033:
034: /**
035: * Construct a new data binding
036: * @param comp the component to be bound
037: * @param xmodel the model node that is to act as the data source
038: */
039: public XListTableBinding(Object comp, XModel xmodel) {
040: target = (XListHolder) comp;
041: keyColumnIdx = displayColumnIdx = 0;
042: }
043:
044: /**
045: * Construct a new data binding
046: * @param c the component to be bound
047: * @param node the model node
048: */
049: public XListTableBinding(Component c, DatabaseTableModelAdapter node) {
050: modelAdapter = node;
051: target = (XListHolder) c;
052: keyColumnIdx = displayColumnIdx = 0;
053: modelAdapter.setOutputField(displayColumnIdx);
054: }
055:
056: /**
057: * Update the bound component with the value obtained from the data model.
058: */
059: public void get() {
060: Hashtable hashTable = null;
061: if (useUnique)
062: hashTable = new Hashtable();
063: String lastItem = "";
064: Object selectedObj = null;
065:
066: if (outputNode != null)
067: selectedObj = (XModel) XProjectManager.getModel().get(
068: outputPath);
069: else
070: selectedObj = modelAdapter.getSelected(keyColumnIdx);
071:
072: modelAdapter.sync();
073: int items = target.getItemCount();
074: int numChildren = modelAdapter.getNumChildren();
075: if (items != numChildren) { // This should really check a 'dirty' flag
076: target.removeAll();
077: String selected = null;
078: if (selectedObj != null)
079: selected = selectedObj.toString();
080: for (int i = 0; i < numChildren; i++) {
081: String currentObj = (String) modelAdapter.get(i);
082: boolean addItem = false;
083: if (useUnique) {
084: if (hashTable.get(currentObj) == null) {
085: hashTable.put(currentObj, currentObj);
086: addItem = true;
087: }
088: } else if (currentObj.compareTo(lastItem) != 0)
089: addItem = true;
090:
091: if (addItem) {
092: target.addItem((String) currentObj);
093: if (selected != null) {
094: Object currentKey;
095: if (displayColumnIdx != keyColumnIdx)
096: currentKey = (String) ((DatabaseTableModel) modelAdapter
097: .getModel()).getFieldValue(i,
098: keyColumnIdx);
099: else
100: currentKey = currentObj;
101: if (selected.equals(currentKey)) {
102: target.select(i);
103: lastItem = currentObj;
104: }
105: }
106: }
107: }
108: } else if (selectedObj != null) {
109: int selRowIdx = modelAdapter.find(selectedObj.toString(),
110: keyColumnIdx);
111: target.select(selRowIdx);
112: }
113: set();
114: }
115:
116: /**
117: * Update the data model with the value retrieved from the bound component.
118: */
119: public void set() {
120: Object selObj = target.getSelectedObject();
121: String selString = "";
122: if (selObj != null)
123: selString = selObj.toString();
124: int selRowIdx = modelAdapter.find(selString, displayColumnIdx);
125: if (selRowIdx >= 0) {
126: Object result = ((DatabaseTableModel) modelAdapter
127: .getModel()).getFieldValue(selRowIdx, keyColumnIdx);
128: if (result != null)
129: outputNode.set(result);
130: }
131: }
132:
133: /**
134: * Get the component to which this binding is attached
135: */
136: public Component getComponent() {
137: return (Component) target;
138: }
139:
140: /**
141: * Get the model path for the source data
142: */
143: public String getSourcePath() {
144: return sourcePath;
145: }
146:
147: /**
148: * Get the model path for the output/state data
149: */
150: public String getOutputPath() {
151: return outputPath;
152: }
153:
154: /**
155: * Set the model path for the source data
156: */
157: public void setSourcePath(String newPath) {
158: if (newPath != null) {
159: modelAdapter = new DatabaseTableModelAdapter(
160: (XModel) XProjectManager.getModel().get(newPath));
161: sourcePath = newPath;
162: modelAdapter.setOutputField(displayColumnIdx);
163: }
164: }
165:
166: /**
167: * Set the model path for the output/state data
168: */
169: public void setOutputPath(String newPath) {
170: if (newPath != null) {
171: outputPath = XModel.prefixOutputPath(newPath);
172: outputNode = (XModel) XProjectManager.getModel().get(
173: outputPath);
174: }
175: }
176:
177: /**
178: * Update the model node used in the binding. Note that this method does not
179: * modify the path values stored by this node.
180: * @param newNode the new model for the data source
181: */
182: public void setSource(XModel newNode) {
183: modelAdapter = new DatabaseTableModelAdapter(newNode);
184: modelAdapter.setOutputField(displayColumnIdx);
185: }
186:
187: /**
188: * Update the path values stored by this node. The output path is used to
189: * store selection data and state.
190: * @param newNode the new model for saving the output data
191: */
192: public void setOutput(XModel newNode) {
193: outputNode = newNode;
194: }
195:
196: /**
197: * Set the display column index, by default it is set to zero or the first column
198: * @param displayColumn the column index (zero based)
199: */
200: public void setDisplayColumn(String displayColumn) {
201: if (displayColumn != null) {
202: displayColumnIdx = new Integer(displayColumn).intValue();
203: modelAdapter.setOutputField(displayColumnIdx);
204: }
205: }
206:
207: /**
208: * Set the key column index, by default it is set to zero or the first column
209: * @param keyColumn the column index (zero based)
210: */
211: public void setKeyColumn(String keyColumn) {
212: if (keyColumn != null)
213: keyColumnIdx = new Integer(keyColumn).intValue();
214: }
215: }
|