001: package com.xoetrope.swing;
002:
003: import com.xoetrope.swing.table.XAltRowTableCellRenderer;
004: import com.xoetrope.swing.table.XColorTableCellRenderer;
005: import com.xoetrope.swing.table.XFormattedTableCellRenderer;
006: import com.xoetrope.swing.table.XTableHeaderRenderer;
007: import com.xoetrope.swing.table.XTableModelAdapter;
008: import java.awt.Color;
009: import java.awt.Component;
010: import java.text.Format;
011: import java.util.Hashtable;
012: import javax.swing.SwingConstants;
013: import javax.swing.table.TableCellEditor;
014:
015: import javax.swing.table.TableCellRenderer;
016: import net.xoetrope.xui.data.XModelHelper;
017: import net.xoetrope.swing.XTable;
018: import net.xoetrope.xui.XProjectManager;
019: import net.xoetrope.xui.data.XBaseModel;
020: import net.xoetrope.xui.data.XModel;
021: import net.xoetrope.xui.data.XModelListener;
022: import javax.swing.table.TableColumnModel;
023: import net.xoetrope.xui.XProject;
024: import net.xoetrope.xui.helper.XTranslator;
025: import net.xoetrope.xui.style.XStyle;
026:
027: /**
028: * <p>Title: XBaseTable</p>
029: * <p>Description: JTable which uses the XTableModelAdapter object to store its
030: * model information. The XTableHeaderRenderer is used to render the header and
031: * uses styles defined in the XUI style file.</p>
032: *
033: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
034: * the GNU Public License (GPL), please see license.txt for more details. If
035: * you make commercial use of this software you must purchase a commercial
036: * license from Xoetrope.</p>
037: * <p> $Revision: 1.20 $</p>
038: */
039: public class XBaseTable extends XTable {
040: protected XTableModelAdapter tableModel;
041: protected boolean doTranslation;
042:
043: /**
044: * The owner project and the context in which this object operates.
045: */
046: protected XProject currentProject = XProjectManager
047: .getCurrentProject();
048:
049: protected Color altUnselectedForeground;
050: protected Color altUnselectedBackground;
051: protected Hashtable renderers;
052:
053: public XBaseTable() {
054: doTranslation = true;
055: getTableHeader().setReorderingAllowed(false);
056: renderers = new Hashtable();
057: }
058:
059: /**
060: * Set one or more attributes of the component. Currently this handles the
061: * attributes
062: * <OL>
063: * <LI>headingStyle, value=the table header style</LI>
064: * <LI>selectionStyle, value=the selected row style</LI>
065: * <LI>interactive, value=true|false</LI>
066: * <LI>updateModel, value=true|false update the underlying model selection (the selected row)</LI>
067: * </OL>
068: * @param attribName the attribute name
069: * @param attribValue the attribute value
070: * @return 0 for success, non zero for failure or to require some further action
071: */
072: public int setAttribute(String attribName, Object attribValue) {
073: int rc = super .setAttribute(attribName, attribValue);
074: if (rc < 0) {
075: String attribNameLwr = attribName.toLowerCase();
076: if (attribNameLwr.equals("altstyle")) {
077: setAltStyle(attribValue.toString());
078: return 0;
079: }
080: }
081:
082: return rc;
083: }
084:
085: /**
086: * Set the XModel which we will be generating the table from
087: * @param xModel The XModel of data
088: */
089: public void setModel(XModel xModel) {
090: super .setModel(xModel);
091: setHeaderStyle();
092: }
093:
094: /**
095: * Retrieves the TableCellEditor for a cell
096: */
097: public TableCellEditor getCellEditor(int row, int column) {
098: if (tableModel != null) {
099: XModel model = (XModel) tableModel.getModelAt(row, column);
100: String editor = model.getAttribValueAsString(model
101: .getAttribute("editor"));
102: if (editor == null)
103: return super .getCellEditor(row, column);
104: }
105:
106: return null;
107: }
108:
109: /**
110: * Sets the tables TableModel object. The XTableModelAdapter is based on the
111: * XModel.
112: * @param model The XTableModelAdapter being set as the model
113: * @param modelListener an XModelListener which be set to listed to the
114: * TableModel changes.
115: */
116: public void setTableModelAdapter(XTableModelAdapter model,
117: XModelListener modelListener) {
118: model.setComponent(this );
119: model.setCellEditable(true);
120: setModel(model);
121: tableModel = model;
122: if (doTranslation)
123: translateTable(model);
124: setHeaderRenderer();
125: }
126:
127: /**
128: * Called when the table's contents need to be translated
129: * @param translate Flag to indicate whether or not to translate the table.
130: */
131: public void setTranslate(boolean translate) {
132: doTranslation = translate;
133: }
134:
135: /*
136: * Retrieve the translate flag
137: */
138: public boolean getTranslate() {
139: return doTranslation;
140: }
141:
142: /**
143: * Uses the Translator Singleton instance to translate the contents of the
144: * table.
145: * @param model The table model
146: */
147: protected void translateTable(XTableModelAdapter model) {
148: XTranslator translator = currentProject.getTranslator();
149: /** @todo replace this as it has the side effect of changing the table
150: * content, see how XTable2 translates.
151: */
152: int numRows = model.getRowCount();
153: int numCols = model.getColumnCount();
154: for (int row = 0; row < numRows; row++) {
155: for (int col = 0; col < numCols; col++) {
156: XBaseModel cellModel = (XBaseModel) model.getModelAt(
157: row, col);
158: if (cellModel != null) {
159: Object obj = cellModel.get();
160: if (obj instanceof String)
161: cellModel.set(translator
162: .translate((String) obj));
163: }
164: }
165: }
166: }
167:
168: /**
169: * Set the style which will be used by the table header.
170: */
171: private void setHeaderStyle() {
172: /** @todo eliminate this method - it is almost certainly a cause of bugs as it resets the header even if a header has been set explicitly */
173: setHeaderRenderer();
174: super .setHeaderStyle(headerStyle);
175: }
176:
177: /**
178: * Set the style of the alternate rows
179: * @param style XStyle
180: */
181: public void setAltStyle(String style) {
182: XStyle xstyle = currentProject.getStyleManager()
183: .getStyle(style);
184: altUnselectedForeground = xstyle
185: .getStyleAsColor(XStyle.COLOR_FORE);
186: altUnselectedBackground = xstyle
187: .getStyleAsColor(XStyle.COLOR_BACK);
188: }
189:
190: /**
191: * Set a new XTableHeaderRenderer for each header. The new translator will
192: * translate the header text.
193: */
194: private void setHeaderRenderer() {
195: /** @todo eliminate this method - it is almost certainly a cause of bugs as it resets the header even if a header has been set explicitly */
196: XTableHeaderRenderer tableHeaderRenderer = new XTableHeaderRenderer(
197: getTableHeader());
198: TableColumnModel columnModel = getColumnModel();
199: int numCols = columnModel.getColumnCount();
200: for (int i = 0; i < numCols; i++)
201: columnModel.getColumn(i).setHeaderRenderer(
202: tableHeaderRenderer);
203: }
204:
205: /**
206: * Set the colors for alternate ( odd ) row colors
207: * @param frgd the foreground color
208: * @param bkgd the background color
209: */
210: public void setAltUnselectedColors(Color frgd, Color bkgd) {
211: altUnselectedForeground = frgd;
212: altUnselectedBackground = bkgd;
213: }
214:
215: /**
216: * Get a render for this cell
217: */
218: public TableCellRenderer getCellRenderer(int row, int column) {
219: TableCellRenderer renderer = (TableCellRenderer) renderers
220: .get("" + column);
221: if (renderer != null)
222: return renderer;
223: else if (altUnselectedBackground != null) {
224: XAltRowTableCellRenderer altRenderer = new XAltRowTableCellRenderer();
225: altRenderer.setAltUnselectedColors(altUnselectedForeground,
226: altUnselectedBackground);
227: renderers.put("" + column, altRenderer);
228: return altRenderer;
229: }
230: return super .getCellRenderer(row, column);
231: }
232:
233: /**
234: * Display the field as a numeric value
235: * @param column the column or field index
236: * @param format format the number format to use in displaying the field
237: */
238: public void displayAsNumericField(int column, Format format) {
239: XFormattedTableCellRenderer renderer = new XFormattedTableCellRenderer(
240: format);
241: renderer.setAltUnselectedColors(altUnselectedForeground,
242: altUnselectedBackground);
243: renderer.setHorizontalAlignment(SwingConstants.RIGHT);
244: renderers.put("" + column, renderer);
245: }
246:
247: /**
248: * Display the field formatted with a background color from the hashtable such
249: * that the field value acts as a key into the hashtable of colors
250: * @param column the column or field index
251: * @param colors the color hashtable
252: */
253: public void displayAsColorField(int column, Hashtable colors) {
254: XColorTableCellRenderer renderer = new XColorTableCellRenderer(
255: colors);
256: renderers.put("" + column, renderer);
257: }
258:
259: /**
260: * Add a cell renderer for the specified column
261: * @param column the column or field index
262: */
263: public void addRenderer(int column, TableCellRenderer renderer) {
264: renderers.put("" + column, renderer);
265: }
266:
267: /**
268: * Retrieve the TableModel.
269: * @return XTableModelAdapter if it is of this type otherwise null
270: */
271: public XBaseModel getBaseModel() {
272: if (getModel() instanceof XTableModelAdapter)
273: return (XBaseModel) ((XTableModelAdapter) getModel())
274: .getModel();
275: else
276: return null;
277: }
278:
279: /**
280: * Retrieve the row of the XTableModelAdapter which represents the passed
281: * index
282: * @param i the row required
283: * @return the row as an XBaseModel
284: */
285: public XBaseModel getRow(int i) {
286: return (XBaseModel) ((XBaseModel) ((XTableModelAdapter) getModel())
287: .getModel()).get(i + 1);
288: }
289:
290: public void setCellValue(XBaseModel templateModel, String col,
291: String attrib, String value) {
292: XBaseModel colModel = (XBaseModel) templateModel.get(col);
293: colModel.setAttribValue(colModel.getAttribute(attrib), value);
294: }
295:
296: /**
297: *
298: */
299: public String getCellValue(String rowName) {
300: XBaseModel model = (XBaseModel) getBaseModel().get(
301: rowName + "/value");
302: return (String) model.get();
303: }
304:
305: public XBaseModel getCellModel(String rowName) {
306: return (XBaseModel) getBaseModel().get(rowName + "/value");
307: }
308:
309: public double getCellValueAsDouble(String rowName) {
310: return XModelHelper.getDoubleValue((XBaseModel) getBaseModel()
311: .get(rowName + "/value"));
312: }
313:
314: public XModelListener getParentListener() {
315: Component c = getParent();
316: while (!(c instanceof XModelListener))
317: c = c.getParent();
318:
319: if (c != null)
320: return (XModelListener) c;
321: else
322: return null;
323: }
324: }
|