001: /*
002: * Copyright 2001-2006 C:1 Financial Services GmbH
003: *
004: * This software is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License Version 2.1, as published by the Free Software Foundation.
007: *
008: * This software is distributed in the hope that it will be useful,
009: * but WITHOUT ANY WARRANTY; without even the implied warranty of
010: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
011: * Lesser General Public License for more details.
012: *
013: * You should have received a copy of the GNU Lesser General Public
014: * License along with this library; if not, write to the Free Software
015: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
016: */
017:
018: package de.finix.contelligent.client.gui.composed;
019:
020: import java.awt.Dimension;
021: import java.awt.event.ActionEvent;
022: import java.awt.event.ActionListener;
023: import java.util.logging.Level;
024: import java.util.logging.Logger;
025:
026: import javax.swing.DefaultCellEditor;
027: import javax.swing.JCheckBox;
028: import javax.swing.JComponent;
029: import javax.swing.JLabel;
030: import javax.swing.JTable;
031: import javax.swing.event.CellEditorListener;
032: import javax.swing.event.ChangeEvent;
033: import javax.swing.table.TableCellRenderer;
034: import javax.swing.table.TableColumn;
035:
036: import de.finix.contelligent.client.base.ContelligentComponent;
037: import de.finix.contelligent.client.gui.ComponentEditor;
038: import de.finix.contelligent.client.gui.GUI;
039: import de.finix.contelligent.client.gui.UnsupportedGUIException;
040: import de.finix.contelligent.client.gui.View;
041:
042: public class ComponentTable extends JTable {
043:
044: private final static int MIN_ROW_HEIGHT = 22;
045:
046: private static Logger logger = Logger
047: .getLogger(ComponentTable.class.getName());
048:
049: private View view;
050:
051: private int maxRowHeight = 250;
052:
053: private Dimension cachedSize = new Dimension(0, 0);
054:
055: public ComponentTable(ComponentTableModel componentTableModel,
056: View view) {
057: super (componentTableModel);
058: this .view = view;
059:
060: setDefaultRenderer(ContelligentComponent.class,
061: new ComponentTableRenderer());
062: setDefaultRenderer(GUI.class, new ComponentTableRenderer());
063: setDefaultEditor(GUI.class, new ComponentTableEditor());
064: calculateRowHeights();
065: }
066:
067: public boolean isCellEditable(int row, int column) {
068: return true;
069: }
070:
071: public void increaseRowHeight() {
072: maxRowHeight += 10;
073: }
074:
075: public void decreaseRowHeight() {
076: maxRowHeight = Math.max(MIN_ROW_HEIGHT, maxRowHeight - 5);
077: }
078:
079: class ComponentTableEditor extends DefaultCellEditor implements
080: ActionListener, CellEditorListener {
081:
082: private GUI gui;
083:
084: private java.awt.Component cellEditor = null;
085:
086: public ComponentTableEditor() {
087: super (new JCheckBox()); // Bad Swing design
088: addCellEditorListener(this );
089: }
090:
091: // This method is called a bit undeterministic, sometimes even directly
092: // before presssing
093: // the commit button. Disable it to fix bug that drops edits
094: // undeterministicly.
095: public void editingCanceled(ChangeEvent e) {
096: /*
097: * logger.log(Level.FINEST, "Cell editing canceled"); if (
098: * cellEditor instanceof ComponentEditor ) {
099: * ((ComponentEditor)cellEditor).rollback(); } // rollback editor
100: * data
101: */
102: }
103:
104: public void editingStopped(ChangeEvent e) {
105: logger.log(Level.FINEST, "Cell editing stopped!");
106: if (cellEditor instanceof ComponentEditor) {
107: ((ComponentEditor) cellEditor).commit();
108: }
109: // commit editor data
110: }
111:
112: public Object getCellEditorValue() {
113: return gui;
114: }
115:
116: public java.awt.Component getTableCellEditorComponent(
117: JTable table, Object object, boolean isSelected,
118: int row, int column) {
119:
120: ContelligentComponent component = null;
121:
122: ComponentEditor editor = null;
123: int preferredHeight = 0;
124:
125: cellEditor = new JLabel("-");
126:
127: if (object instanceof ContelligentComponent) {
128: component = (ContelligentComponent) object;
129: cellEditor = new JLabel(component.getName(), component
130: .getSmallIcon(), JLabel.LEFT);
131: cellEditor.setFont(table.getFont());
132: } else if (object instanceof GUI) {
133: gui = (GUI) object;
134: try {
135: editor = gui.getEditor(GUI.TABLE);
136:
137: editor.removeActionListener(this );
138: editor.addActionListener(this );
139:
140: int modelColumn = ComponentTable.this
141: .convertColumnIndexToModel(column);
142: editor.setEditable(ComponentTable.this .getModel()
143: .isCellEditable(row, modelColumn));
144:
145: cellEditor = (java.awt.Component) editor;
146: } catch (UnsupportedGUIException uge) {
147: }
148: }
149:
150: ((JComponent) cellEditor).setOpaque(true);
151: if (isSelected) {
152: cellEditor.setBackground(ComponentTable.this
153: .getSelectionBackground());
154: cellEditor.setForeground(ComponentTable.this
155: .getSelectionForeground());
156: } else {
157: cellEditor.setBackground(ComponentTable.this
158: .getBackground());
159: cellEditor.setForeground(ComponentTable.this
160: .getForeground());
161: }
162: return cellEditor;
163: }
164:
165: public void actionPerformed(ActionEvent e) {
166: logger.log(Level.FINE, "Editing stopped!");
167: fireEditingStopped();
168: }
169: }
170:
171: class ComponentTableRenderer implements TableCellRenderer {
172:
173: public java.awt.Component getTableCellRendererComponent(
174: JTable table, Object object, boolean isSelected,
175: boolean hasFocus, int row, int column) {
176: java.awt.Component cellRenderer = new JLabel("-");
177: ContelligentComponent component = null;
178:
179: GUI gui = null;
180: int preferredHeight = 0;
181:
182: if (object instanceof ContelligentComponent) {
183: component = (ContelligentComponent) object;
184: cellRenderer = new JLabel(component.getName(),
185: component.getSmallIcon(), JLabel.LEFT);
186: cellRenderer.setFont(table.getFont());
187: } else if (object instanceof GUI) {
188: gui = (GUI) object;
189: try {
190: cellRenderer = (java.awt.Component) gui
191: .getRenderer(GUI.TABLE);
192: logger.log(Level.FINE, "Requested renderer is: "
193: + cellRenderer);
194: } catch (UnsupportedGUIException uge) {
195: }
196: }
197:
198: ((JComponent) cellRenderer).setOpaque(true);
199: if (isSelected) {
200: cellRenderer.setBackground(ComponentTable.this
201: .getSelectionBackground());
202: cellRenderer.setForeground(ComponentTable.this
203: .getSelectionForeground());
204: } else {
205: cellRenderer.setBackground(ComponentTable.this
206: .getBackground());
207: cellRenderer.setForeground(ComponentTable.this
208: .getForeground());
209: }
210: return cellRenderer;
211: }
212: }
213:
214: public void invalidate() {
215: if (!cachedSize.equals(getSize())) {
216:
217: logger.log(Level.FINEST, "Recalculate table (new size is "
218: + getSize() + ")");
219:
220: cachedSize = getSize();
221: calculateColumnWidths();
222: calculateRowHeights();
223: }
224:
225: super .invalidate();
226: }
227:
228: public void calculateColumnWidths() {
229: ComponentTableModel model = (ComponentTableModel) getModel();
230: if (model.isColspanEnabled()) {
231: for (int column = 0; column < model.getColumnCount(); column++) {
232: logger.log(Level.FINEST, "Preferred width for column "
233: + column
234: + " is "
235: + model.getPreferredColumnWidth(getWidth(),
236: column));
237: TableColumn tableColumn = getColumnModel().getColumn(
238: column);
239: tableColumn.setPreferredWidth(model
240: .getPreferredColumnWidth(getWidth(), column));
241: }
242: }
243: }
244:
245: public void calculateRowHeights() {
246: int contentColumn = ((ComponentTableModel) getModel())
247: .getContentColumn();
248: int rows = getRowCount();
249: int rowHeight[] = new int[rows];
250: int totalRowHeight = 0;
251: int bigRows = 0;
252:
253: for (int i = 0; i < getRowCount(); i++) {
254: try {
255: GUI gui = (GUI) getValueAt(i, contentColumn);
256: java.awt.Component renderer = (java.awt.Component) gui
257: .getRenderer(GUI.TABLE);
258: int preferredHeight = Math.min((int) renderer
259: .getPreferredSize().getHeight(), maxRowHeight);
260: if (preferredHeight > MIN_ROW_HEIGHT) {
261: bigRows++;
262: } else {
263: preferredHeight = MIN_ROW_HEIGHT;
264: }
265: rowHeight[i] = preferredHeight;
266: } catch (UnsupportedGUIException e) {
267: rowHeight[i] = MIN_ROW_HEIGHT;
268: }
269: totalRowHeight += rowHeight[i];
270: }
271: /*
272: * if ( totalRowHeight < maxHeight && bigRows > 0 ) { // there is space
273: * left, so expand big rows to fit the size int extraSpacePerBigRow =
274: * (int) ( maxHeight-totalRowHeight ) / bigRows; for ( int i = 0; i <
275: * getRowCount(); i++ ) { if ( rowHeight[i] > MIN_ROW_HEIGHT ) {
276: * rowHeight[i] += extraSpacePerBigRow; } }
277: * }
278: */
279: for (int i = 0; i < getRowCount(); i++) {
280: setRowHeight(i, rowHeight[i]);
281: }
282: }
283:
284: }
|