001: package com.xoetrope.carousel.visualizer;
002:
003: import java.util.Vector;
004: import javax.swing.BorderFactory;
005: import javax.swing.event.TableModelListener;
006: import javax.swing.table.TableModel;
007: import net.xoetrope.swing.XTable2;
008: import net.xoetrope.xui.data.XBaseModel;
009: import net.xoetrope.xui.data.XModel;
010:
011: public class XTableModelView extends XTable2 {
012: public XTableModelView() {
013: super ();
014: setBorder(BorderFactory.createEmptyBorder());
015: getTableHeader().setBorder(BorderFactory.createEmptyBorder());
016: }
017:
018: /**
019: * Set the XModel which we will be generating the table from
020: * @param xmodel The XModel of data
021: */
022: public void setModel(XModel xmodel) {
023: model = xmodel;
024: if (model != null) {
025: usesDatabase = (model.getClass().getName().indexOf(
026: "DatabaseTableModel") > 0);
027: try {
028: model.get();
029: } catch (Exception ex) {
030: }
031: setModel(new XTableModel(model));
032: }
033: }
034:
035: }
036:
037: class XTableModel implements TableModel {
038: /**
039: * The data model
040: */
041: private XModel model;
042:
043: /**
044: * the table listeners
045: */
046: private Vector listeners;
047:
048: /**
049: * true to display a header
050: */
051: private boolean hasHeaderRow;
052:
053: private boolean usesDatabase;
054:
055: /**
056: * Create a new table model
057: * @param newModel the data model source
058: */
059: public XTableModel(XModel newModel) {
060: model = newModel;
061: if (newModel instanceof VisualiserDebuggerModel) {
062: String rns = ((VisualiserDebuggerModel) model)
063: .getNodeString();
064: usesDatabase = (rns.indexOf("DatabaseTableModel") > 0);
065: } else {
066: usesDatabase = (model.getClass().getName().indexOf(
067: "DatabaseTableModel") > 0);
068: }
069: listeners = new Vector();
070: hasHeaderRow = false;
071: }
072:
073: private int getModelChildrenCount() {
074: int numChildren;
075: try {
076: numChildren = (model != null ? model.getNumChildren() : 0);
077: } catch (Exception ex) {
078: numChildren = 0;
079: }
080: return numChildren;
081: }
082:
083: /**
084: * Returns the number of rows in the model. A
085: * <code>JTable</code> uses this method to determine how many rows it
086: * should display. This method should be quick, as it
087: * is called frequently during rendering.
088: *
089: * @return the number of rows in the model
090: * @see #getColumnCount
091: */
092: public int getRowCount() {
093: if (hasHeaderRow)
094: return getModelChildrenCount() - 1;
095: else
096: return getModelChildrenCount();
097: }
098:
099: /**
100: * Returns the number of columns in the model. A
101: * <code>JTable</code> uses this method to determine how many columns it
102: * should create and display by default.
103: *
104: * @return the number of columns in the model
105: * @see #getRowCount
106: */
107: public int getColumnCount() {
108: if (getModelChildrenCount() > 0) {
109: if (usesDatabase) {
110: return model.getNumAttributes();
111: } else {
112: XModel row0 = (XModel) model.get(0);
113: if (row0.getTagName().equals("th")) {
114: hasHeaderRow = true;
115: return row0.getNumChildren();
116: }
117: }
118: }
119: return model.getNumAttributes();
120: }
121:
122: /**
123: * Returns the name of the column at <code>columnIndex</code>. This is used
124: * to initialize the table's column header name. Note: this name does
125: * not need to be unique; two columns in a table can have the same name.
126: *
127: * @param columnIndex the index of the column
128: * @return the name of the column
129: */
130: public String getColumnName(int columnIndex) {
131: if (hasHeaderRow) {
132: XModel row0 = (XModel) model.get(0);
133: return row0.get(columnIndex).getAttribValueAsString(
134: XBaseModel.VALUE_ATTRIBUTE);
135: }
136:
137: return model.getAttribName(columnIndex);
138: }
139:
140: /**
141: * Returns the most specific superclass for all the cell values
142: * in the column. This is used by the <code>JTable</code> to set up a
143: * default renderer and editor for the column.
144: *
145: * @param columnIndex the index of the column
146: * @return the common ancestor class of the object values in the model.
147: */
148: public Class getColumnClass(int columnIndex) {
149: return String.class;
150: }
151:
152: /**
153: * Returns true if the cell at <code>rowIndex</code> and
154: * <code>columnIndex</code>
155: * is editable. Otherwise, <code>setValueAt</code> on the cell will not
156: * change the value of that cell.
157: *
158: * @param rowIndex the row whose value to be queried
159: * @param columnIndex the column whose value to be queried
160: * @return true if the cell is editable
161: * @see #setValueAt
162: */
163: public boolean isCellEditable(int rowIndex, int columnIndex) {
164: return true;
165: }
166:
167: /**
168: * Returns the value for the cell at <code>columnIndex</code> and
169: * <code>rowIndex</code>.
170: *
171: * @param rowIndex the row whose value is to be queried
172: * @param columnIndex the column whose value is to be queried
173: * @return the value Object at the specified cell
174: */
175: public Object getValueAt(int rowIndex, int columnIndex) {
176: try {
177: if (hasHeaderRow)
178: rowIndex++;
179: if ((rowIndex < 0) || (rowIndex >= getModelChildrenCount()))
180: return "";
181:
182: XModel rowModel = model.get(rowIndex);
183: if ((columnIndex < 0)
184: || (columnIndex >= rowModel.getNumChildren()))
185: return "";
186:
187: return rowModel.get(columnIndex).get();
188: } catch (Exception ex) {
189: return "";
190: }
191: }
192:
193: /**
194: * Sets the value in the cell at <code>columnIndex</code> and
195: * <code>rowIndex</code> to <code>aValue</code>.
196: *
197: * @param aValue the new value
198: * @param rowIndex the row whose value is to be changed
199: * @param columnIndex the column whose value is to be changed
200: * @see #getValueAt
201: * @see #isCellEditable
202: */
203: public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
204: model.get(rowIndex + (hasHeaderRow ? 1 : 0)).get(columnIndex)
205: .set(aValue);
206: }
207:
208: /**
209: * Adds a listener to the list that is notified each time a change
210: * to the data model occurs.
211: *
212: * @param l the TableModelListener
213: */
214: public void addTableModelListener(TableModelListener l) {
215: listeners.add(l);
216: }
217:
218: /**
219: * Removes a listener from the list that is notified each time a
220: * change to the data model occurs.
221: *
222: * @param l the TableModelListener
223: */
224: public void removeTableModelListener(TableModelListener l) {
225: listeners.remove(l);
226: }
227: }
|