001: package com.xoetrope.swing.table;
002:
003: import java.awt.Component;
004: import java.util.Vector;
005: import javax.swing.event.TableModelListener;
006: import javax.swing.table.TableModel;
007: import net.xoetrope.xui.data.XModelHelper;
008:
009: import net.xoetrope.xui.XProjectManager;
010: import net.xoetrope.xui.data.XBaseModel;
011: import net.xoetrope.xui.data.XModel;
012: import net.xoetrope.xui.data.XModelListener;
013:
014: /**
015: * <p>A TableModel which uses an XModel as the storage for an XBaseTable</p>
016: *
017: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
018: * the GNU Public License (GPL), please see license.txt for more details. If
019: * you make commercial use of this software you must purchase a commercial
020: * license from Xoetrope.</p>
021: * <p> $Revision: 1.9 $</p>
022: */
023: public class XTableModelAdapter implements TableModel {
024: protected XModel model, rootModel;
025: protected Vector listeners;
026: protected boolean editable = false;
027: protected boolean disabledColumns[];
028: protected Component component;
029: protected XModelListener modelListener;
030:
031: public XTableModelAdapter(XModel newModel) {
032: this (newModel, null);
033: }
034:
035: public XTableModelAdapter(XModel newModel, XModelListener listener) {
036: rootModel = XProjectManager.getModel();
037: modelListener = listener;
038: model = newModel;
039: if (model.getNumChildren() == 0)
040: disabledColumns = new boolean[0];
041: else
042: disabledColumns = new boolean[model.get(0).getNumChildren()];
043: listeners = new Vector();
044: }
045:
046: public XModel getModel() {
047: return model;
048: }
049:
050: public void setModelListener(XModelListener listener) {
051: modelListener = listener;
052: }
053:
054: public void init(XModelListener listener) {
055: int numRows = model.getNumChildren();
056: for (int i = 0; i < numRows; i++) {
057: XModel rowModel = model.get(i);
058: addEvents(listener, rowModel, i, -1);
059: int numCols = rowModel.getNumChildren();
060: for (int iCol = 0; iCol < numCols; iCol++) {
061: XModel cellModel = rowModel.get(iCol);
062: addEvents(listener, cellModel, i, iCol);
063: }
064: }
065:
066: for (int i = 0; i < numRows; i++) {
067: XModel rowModel = model.get(i);
068: initBindings(model, i, -1);
069: int numCols = rowModel.getNumChildren();
070: for (int iCol = 0; iCol < numCols; iCol++) {
071: XModel cellModel = rowModel.get(iCol);
072: initBindings(cellModel, i, iCol);
073: }
074: }
075: }
076:
077: private void initBindings(XModel model, int row, int col) {
078: String bindPath = XModelHelper.getAttrib(model, "bind");
079: String editor = XModelHelper.getAttrib(model, "editor");
080: if (bindPath != null) {
081: if ((editor != null) && editor.equals("Combo")) {
082: XBaseModel dataModel = (XBaseModel) rootModel
083: .get(bindPath);
084: model.set(dataModel.get(0).get());
085: }
086: }
087: }
088:
089: private void addEvents(XModelListener listener, XModel cellModel,
090: int row, int col) {
091: String onChange = XModelHelper.getAttrib(cellModel, "onchange");
092: if ((onChange != null) && (listener != null))
093: cellModel.addModelListener(listener, onChange);
094: }
095:
096: /**
097: * Returns the number of rows in the model. A
098: * <code>JTable</code> uses this method to determine how many rows it
099: * should display. This method should be quick, as it
100: * is called frequently during rendering.
101: *
102: * @return the number of rows in the model
103: * @see #getColumnCount
104: */
105: public int getRowCount() {
106: return model.getNumChildren() - 1;
107: }
108:
109: /**
110: * Returns the number of columns in the model. A
111: * <code>JTable</code> uses this method to determine how many columns it
112: * should create and display by default.
113: *
114: * @return the number of columns in the model
115: * @see #getRowCount
116: */
117: public int getColumnCount() {
118: if (model.getNumChildren() == 0)
119: return 0;
120: else
121: return model.get(0).getNumChildren();
122: }
123:
124: /**
125: * Returns the name of the column at <code>columnIndex</code>. This is used
126: * to initialize the table's column header name. Note: this name does
127: * not need to be unique; two columns in a table can have the same name.
128: *
129: * @param columnIndex the index of the column
130: * @return the name of the column
131: */
132: public String getColumnName(int columnIndex) {
133: return (String) model.get(0).get(columnIndex).get();
134: }
135:
136: /**
137: * Returns the most specific superclass for all the cell values
138: * in the column. This is used by the <code>JTable</code> to set up a
139: * default renderer and editor for the column.
140: *
141: * @param columnIndex the index of the column
142: * @return the common ancestor class of the object values in the model.
143: */
144: public Class getColumnClass(int columnIndex) {
145: return String.class;
146: }
147:
148: /**
149: * Returns true if the cell at <code>rowIndex</code> and
150: * <code>columnIndex</code>
151: * is editable. Otherwise, <code>setValueAt</code> on the cell will not
152: * change the value of that cell. The cell is editable if its 'edit' attribute
153: * is 'true'
154: *
155: * @param rowIndex the row whose value to be queried
156: * @param columnIndex the column whose value to be queried
157: * @return true if the cell is editable
158: * @see #setValueAt
159: */
160: public boolean isCellEditable(int rowIndex, int columnIndex) {
161: if (disabledColumns[columnIndex])
162: return false;
163:
164: XModel cellModel = model.get(rowIndex + 1).get(columnIndex);
165: String edit = cellModel.getAttribValueAsString(cellModel
166: .getAttribute("edit"));
167: if ((edit != null) && edit.equals("false"))
168: return false;
169:
170: return editable;
171: }
172:
173: /**
174: * Set the editable state of the cell
175: * @param state the new editable state
176: */
177: public void setCellEditable(boolean state) {
178: editable = state;
179: }
180:
181: /**
182: * Set the enabled state of the column
183: * @param col the column index
184: * @param enabled the new enabled state
185: */
186: public void setColumnEnabled(int col, boolean enabled) {
187: if (disabledColumns.length > col)
188: disabledColumns[col] = !enabled;
189: }
190:
191: /**
192: * Returns the value for the cell at <code>columnIndex</code> and
193: * <code>rowIndex</code>.
194: *
195: * @param rowIndex the row whose value is to be queried
196: * @param columnIndex the column whose value is to be queried
197: * @return the value Object at the specified cell
198: */
199: public Object getValueAt(int rowIndex, int columnIndex) {
200: XModel cellModel = model.get(rowIndex + 1).get(columnIndex);
201: String dataType = XModelHelper.getAttrib(cellModel, "datatype");
202: Object value = cellModel.get();
203: if (dataType != null) {
204: if (dataType.equals("currency")) {
205: //if (price != null)
206: // return CurrencyUtils.formatPriceValue( value );
207: //else
208: return "";
209: } else {
210: XBaseModel typeModel = (XBaseModel) rootModel
211: .get("units/" + dataType);
212: return ((String) value) + " "
213: + typeModel.get().toString();
214: }
215: } else
216: return value;
217: }
218:
219: /**
220: * Get the model value
221: * @param rowIndex the row index
222: * @param columnIndex the column index
223: */
224: public Object getModelAt(int rowIndex, int columnIndex) {
225: try {
226: String datatype = XModelHelper.getAttrib(model.get(
227: rowIndex + 1).get(columnIndex), "datatype");
228: return model.get(rowIndex + 1).get(columnIndex);
229: } catch (Exception e) {
230: return null;
231: }
232: }
233:
234: /**
235: * Get the model for the specified row
236: * @param rowIndex the row index
237: * @return the model value
238: */
239: public Object getModelAt(int rowIndex) {
240: return model.get(rowIndex + 1);
241: }
242:
243: /**
244: * Sets the value in the cell at <code>columnIndex</code> and
245: * <code>rowIndex</code> to <code>aValue</code>.
246: *
247: * @param aValue the new value
248: * @param rowIndex the row whose value is to be changed
249: * @param columnIndex the column whose value is to be changed
250: * @see #getValueAt
251: * @see #isCellEditable
252: */
253: public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
254: model.get(rowIndex + 1).get(columnIndex).set(aValue);
255: }
256:
257: /**
258: * Set the editor component
259: * @param the component instance
260: */
261: public void setComponent(Component comp) {
262: component = comp;
263: }
264:
265: /**
266: * Get the editor component
267: * @return the component instance
268: */
269: public Component getComponent() {
270: return component;
271: }
272:
273: /**
274: * Adds a listener to the list that is notified each time a change
275: * to the data model occurs.
276: *
277: * @param l the TableModelListener
278: */
279: public void addTableModelListener(TableModelListener l) {
280: listeners.add(l);
281: }
282:
283: /**
284: * Removes a listener from the list that is notified each time a
285: * change to the data model occurs.
286: *
287: * @param l the TableModelListener
288: */
289: public void removeTableModelListener(TableModelListener l) {
290: listeners.remove(l);
291: }
292: }
|