001: /*
002: * Copyright 2000,2005 wingS development team.
003: *
004: * This file is part of wingS (http://wingsframework.org).
005: *
006: * wingS is free software; you can redistribute it and/or modify
007: * it under the terms of the GNU Lesser General Public License
008: * as published by the Free Software Foundation; either version 2.1
009: * of the License, or (at your option) any later version.
010: *
011: * Please see COPYING for the complete licence.
012: */
013: package wingset;
014:
015: import org.wings.*;
016: import org.wings.style.CSSProperty;
017: import org.wings.style.CSSStyleSheet;
018: import org.wings.event.SMouseEvent;
019: import org.wings.event.SMouseListener;
020: import org.wings.plaf.css.TableCG;
021: import org.wings.table.*;
022: import org.wingx.XTable;
023: import org.wingx.XCalendar;
024: import org.wingx.table.*;
025:
026: import javax.swing.table.TableModel;
027: import java.awt.*;
028: import java.awt.event.*;
029: import java.util.*;
030: import java.util.List;
031:
032: /**
033: * @author Holger Engels
034: */
035: public class XTableExample extends WingSetPane {
036: private XTable table;
037: private SLabel clicks = new SLabel();
038: private TableControls controls;
039: private boolean consume = false;
040: protected final MyCellRenderer cellRenderer = new MyCellRenderer();
041: protected final Color[] colors = { Color.black, Color.cyan,
042: Color.yellow, Color.magenta, Color.orange, Color.pink,
043: Color.red, Color.darkGray, Color.gray, Color.green,
044: Color.lightGray, Color.white, Color.blue };
045: protected final SIcon image = new SResourceIcon(
046: "org/wings/icons/JavaCup.gif");
047:
048: protected SComponent createControls() {
049: controls = new TableControls();
050: return controls;
051: }
052:
053: public SComponent createExample() {
054: table = new XTable(new MyTableModel(7, 5));
055: table.setName("xTableExample");
056: table.setShowGrid(true);
057: table.setSelectionMode(STable.NO_SELECTION);
058: table.setDefaultRenderer(cellRenderer);
059: table.setShowAsFormComponent(true);
060: table.setEditable(false);
061: controls.addControllable(table);
062:
063: getColumn(0).setSortable(true);
064: getColumn(1).setSortable(true);
065: getColumn(5).setSortable(true);
066: getColumn(6).setSortable(true);
067:
068: getColumn(0).setFilterRenderer(new StringFilterRenderer());
069: getColumn(0).setFilterable(true);
070:
071: getColumn(4).setFilterRenderer(new BooleanFilterRenderer());
072: getColumn(4).setCellRenderer(new BooleanEditableCellRenderer());
073: getColumn(4).setFilterable(true);
074:
075: getColumn(5).setFilterRenderer(new StringFilterRenderer());
076: getColumn(5).setFilterable(true);
077:
078: getColumn(6).setCellRenderer(new DateEditableCellRenderer());
079: getColumn(6).setFilterable(true);
080:
081: getColumn(0).setWidth("200px");
082: getColumn(1).setWidth("*");
083: getColumn(2).setWidth("100px");
084: getColumn(3).setWidth("50px");
085: getColumn(4).setWidth("50px");
086: getColumn(5).setWidth("50px");
087: getColumn(6).setWidth("100px");
088:
089: table.addMouseListener(new SMouseListener() {
090: public void mouseClicked(SMouseEvent e) {
091: if (consume && table.columnAtPoint(e.getPoint()) == 1)
092: e.consume();
093: clicks.setText("clicked " + e.getPoint());
094: }
095: });
096: table.setVerticalAlignment(SConstants.TOP_ALIGN);
097:
098: SPanel panel = new SPanel(new SBorderLayout());
099: panel.add(table, SBorderLayout.CENTER);
100: panel.add(clicks, SBorderLayout.SOUTH);
101: panel.setVerticalAlignment(SConstants.TOP_ALIGN);
102: return panel;
103: }
104:
105: private XTableColumn getColumn(final int column) {
106: return ((XTableColumn) table.getColumnModel().getColumn(column));
107: }
108:
109: class MyTableModel extends XTableModel {
110: int cols, rows;
111:
112: Object[][] origData;
113: Object[][] data;
114:
115: MyTableModel(int pCols, int pRows) {
116: this .cols = pCols > 7 ? pCols : 7;
117: this .rows = pRows;
118:
119: origData = new Object[rows][cols];
120:
121: for (int c = 0; c < cols; c++) {
122: for (int r = 0; r < rows; r++)
123: origData[r][c] = (c == 1 ? "stretched cell "
124: : "cell ")
125: + r + ":" + c;
126: }
127: for (int r = 0; r < rows; r++)
128: origData[r][2] = createColor(r);
129: for (int r = 0; r < rows; r++)
130: origData[r][3] = createImage(r);
131: for (int r = 0; r < rows; r++)
132: origData[r][4] = createBoolean(r);
133: for (int r = 0; r < rows; r++)
134: origData[r][5] = createInteger(r);
135: for (int r = 0; r < rows; r++)
136: origData[r][6] = createDate(r);
137:
138: refresh();
139: }
140:
141: public int getColumnCount() {
142: return cols;
143: }
144:
145: public String getColumnName(int col) {
146: return "col " + col;
147: }
148:
149: public int getRowCount() {
150: return data.length;
151: }
152:
153: public Object getValueAt(int row, int col) {
154: return data[row][col];
155: }
156:
157: public void setValueAt(Object value, int row, int col) {
158: if (isDifferent(getValueAt(row, col), value)) {
159: data[row][col] = value;
160: fireTableCellUpdated(row, col);
161: }
162: }
163:
164: public Class getColumnClass(int columnIndex) {
165: switch (columnIndex) {
166: case 2:
167: return Color.class;
168: case 3:
169: return SIcon.class;
170: case 4:
171: return Boolean.class;
172: case 5:
173: return Integer.class;
174: case 6:
175: return Date.class;
176: }
177: return String.class;
178: }
179:
180: public Color createColor(int row) {
181: return colors[row % colors.length];
182: }
183:
184: public SIcon createImage(int row) {
185: return image;
186: }
187:
188: public Boolean createBoolean(int row) {
189: return row % 2 == 1 ? Boolean.FALSE : Boolean.TRUE;
190: }
191:
192: public Integer createInteger(int row) {
193: return new Integer(row);
194: }
195:
196: public Date createDate(int row) {
197: return new Date(System.currentTimeMillis() + row * 1000
198: * 60 * 60 * 24);
199: }
200:
201: public int toInt(String numberString, int startPos) {
202: try {
203: return Integer.parseInt(numberString
204: .substring(startPos).trim());
205: } catch (NumberFormatException ex) {
206: return Integer.MIN_VALUE;
207: }
208: }
209:
210: public void refresh() {
211: List<Object[]> list = new ArrayList<Object[]>(Arrays
212: .asList(origData));
213: for (Iterator<Object[]> iterator = list.iterator(); iterator
214: .hasNext();) {
215: final Object[] rowData = iterator.next();
216: boolean remove = false;
217: for (int i = 0; i < getColumnCount(); i++) {
218: Object filter = getFilter(i);
219: if (filter != null) {
220: if (getColumnClass(i) == String.class) {
221: String s = (String) rowData[i];
222: String f = ((String) filter).toUpperCase();
223: if (s == null
224: || s.toUpperCase().indexOf(f) == -1)
225: remove |= true;
226: } else if (getColumnClass(i) == Boolean.class) {
227: if (!filter.equals(rowData[i]))
228: remove |= true;
229: } else if (getColumnClass(i) == Integer.class) {
230: final int intValue = ((Integer) rowData[i])
231: .intValue();
232: final String filterString = ((String) filter)
233: .trim();
234: if (filterString.startsWith(">="))
235: remove |= !(intValue >= toInt(
236: filterString, 2));
237: else if (filterString.startsWith("<="))
238: remove |= !(intValue <= toInt(
239: filterString, 2));
240: else if (filterString.startsWith("=="))
241: remove |= !(intValue == toInt(
242: filterString, 2));
243: else if (filterString.startsWith(">"))
244: remove |= !(intValue > toInt(
245: filterString, 1));
246: else if (filterString.startsWith("<"))
247: remove |= !(intValue < toInt(
248: filterString, 1));
249: else if (filterString.startsWith("="))
250: remove |= !(intValue == toInt(
251: filterString, 1));
252: else
253: remove |= !(intValue == toInt(
254: filterString, 0));
255: }
256: }
257: }
258: if (remove)
259: iterator.remove();
260: }
261: data = list.toArray(new Object[0][0]);
262:
263: Arrays.sort(data, new Comparator<Object>() {
264: public int compare(Object o1, Object o2) {
265: for (int i = 0; i < getColumnCount(); i++) {
266: Object[] r1 = (Object[]) o1;
267: Object[] r2 = (Object[]) o2;
268: int comparision;
269:
270: switch (getSort(i)) {
271: case SORT_ASCENDING: {
272: Comparable v1 = (Comparable) r1[i];
273: Comparable v2 = (Comparable) r2[i];
274: comparision = v1.compareTo(v2);
275: if (comparision != 0)
276: return comparision;
277: }
278: case SORT_DESCENDING: {
279: Comparable v1 = (Comparable) r1[i];
280: Comparable v2 = (Comparable) r2[i];
281: comparision = v2.compareTo(v1);
282: if (comparision != 0)
283: return comparision;
284: }
285: default:
286: comparision = 0;
287: }
288: }
289: return 0;
290: }
291: });
292:
293: fireTableDataChanged();
294: }
295: }
296:
297: /**
298: * Proof that we can do some really nice tables with j-wings.
299: */
300: public class MyTable extends STable {
301: private final/*static*/TableCG myTableCG = new TableCG();
302:
303: public MyTable(TableModel tm) {
304: super (tm);
305: myTableCG.setFixedTableBorderWidth("0");
306: setCG(myTableCG);
307: }
308:
309: /**
310: * Returns the CSS style for a row (<td style="xxx")
311: */
312: public String getRowStyle(int row) {
313: return isRowSelected(row) ? "table_selected_row"
314: : (row % 2 == 0 ? "table_row1" : "table_row2");
315: }
316: }
317:
318: class TableControls extends ComponentControls {
319: private final String[] SELECTION_MODES = new String[] { "no",
320: "single", "multiple" };
321:
322: public TableControls() {
323: widthTextField.setText("100%");
324: formComponentCheckBox.setSelected(true);
325:
326: final SComboBox selectionMode = new SComboBox(
327: SELECTION_MODES);
328: selectionMode.addItemListener(new ItemListener() {
329: public void itemStateChanged(ItemEvent e) {
330: if ("no".equals(selectionMode.getSelectedItem()))
331: table.setSelectionMode(STable.NO_SELECTION);
332: else if ("single".equals(selectionMode
333: .getSelectedItem()))
334: table.setSelectionMode(STable.SINGLE_SELECTION);
335: else if ("multiple".equals(selectionMode
336: .getSelectedItem()))
337: table
338: .setSelectionMode(STable.MULTIPLE_SELECTION);
339: }
340: });
341:
342: addControl(new SLabel(" selection mode"));
343: addControl(selectionMode);
344:
345: final SComboBox headerColor = new SComboBox(COLORS);
346: headerColor.addActionListener(new ActionListener() {
347: public void actionPerformed(ActionEvent e) {
348: Color color = (Color) ((Object[]) headerColor
349: .getSelectedItem())[1];
350: table.setAttribute(STable.SELECTOR_HEADER,
351: CSSProperty.BACKGROUND_COLOR, CSSStyleSheet
352: .getAttribute(color));
353: }
354: });
355: headerColor.setRenderer(new ObjectPairCellRenderer());
356: addControl(new SLabel(" header"));
357: addControl(headerColor);
358:
359: final SComboBox oddColor = new SComboBox(COLORS);
360: oddColor.addActionListener(new ActionListener() {
361: public void actionPerformed(ActionEvent e) {
362: Color color = (Color) ((Object[]) oddColor
363: .getSelectedItem())[1];
364: table.setAttribute(STable.SELECTOR_ODD_ROWS,
365: CSSProperty.BACKGROUND_COLOR, CSSStyleSheet
366: .getAttribute(color));
367: }
368: });
369: oddColor.setRenderer(new ObjectPairCellRenderer());
370: addControl(new SLabel(" odd"));
371: addControl(oddColor);
372:
373: final SComboBox evenColor = new SComboBox(COLORS);
374: evenColor.addActionListener(new ActionListener() {
375: public void actionPerformed(ActionEvent e) {
376: Color color = (Color) ((Object[]) evenColor
377: .getSelectedItem())[1];
378: table.setAttribute(STable.SELECTOR_EVEN_ROWS,
379: CSSProperty.BACKGROUND_COLOR, CSSStyleSheet
380: .getAttribute(color));
381: }
382: });
383: evenColor.setRenderer(new ObjectPairCellRenderer());
384: addControl(new SLabel(" even"));
385: addControl(evenColor);
386:
387: final SCheckBox reverseColumnOrder = new SCheckBox(
388: "reverse columns");
389: reverseColumnOrder.addActionListener(new ActionListener() {
390: public void actionPerformed(ActionEvent e) {
391: STableColumnModel columnModel = table
392: .getColumnModel();
393: Collections.reverse((java.util.List) columnModel
394: .getColumns());
395: table.reload();
396: }
397: });
398: addControl(reverseColumnOrder);
399:
400: final SCheckBox hideSomeColumns = new SCheckBox(
401: "Hide some Columns");
402: hideSomeColumns.addActionListener(new ActionListener() {
403: public void actionPerformed(ActionEvent e) {
404: SDefaultTableColumnModel columnModel = (SDefaultTableColumnModel) table
405: .getColumnModel();
406: for (int i = 0; i < columnModel.getColumnCount(); ++i) {
407: if (i % 3 == 0) {
408: STableColumn column = columnModel
409: .getColumn(i);
410: columnModel.setColumnHidden(column,
411: hideSomeColumns.isSelected());
412: }
413: }
414: }
415: });
416: addControl(hideSomeColumns);
417: }
418: }
419:
420: private static class StringFilterRenderer extends STextField
421: implements EditableTableCellRenderer {
422: public StringFilterRenderer() {
423: addActionListener(new NoAction());
424: }
425:
426: public Object getValue() {
427: String s = getText();
428: if ("".equals(s))
429: return null;
430: return s;
431: }
432:
433: public SComponent getTableCellRendererComponent(STable table,
434: Object value, boolean isSelected, int row, int column) {
435: setText(value != null ? value.toString() : null);
436: return this ;
437: }
438:
439: public LowLevelEventListener getLowLevelEventListener(
440: STable table, int row, int column) {
441: return this ;
442: }
443: }
444:
445: private static class BooleanEditableCellRenderer extends SCheckBox
446: implements EditableTableCellRenderer {
447: public Object getValue() {
448: return isSelected() ? Boolean.TRUE : Boolean.FALSE;
449: }
450:
451: public SComponent getTableCellRendererComponent(STable table,
452: Object value, boolean isSelected, int row, int column) {
453: setSelected(Boolean.TRUE.equals(value));
454: return this ;
455: }
456:
457: public LowLevelEventListener getLowLevelEventListener(
458: STable table, int row, int column) {
459: return this ;
460: }
461: }
462:
463: private static class BooleanFilterRenderer extends SComboBox
464: implements EditableTableCellRenderer {
465: public BooleanFilterRenderer() {
466: super (new Boolean[] { null, Boolean.TRUE, Boolean.FALSE });
467: addActionListener(new NoAction());
468: }
469:
470: public Object getValue() {
471: return getSelectedItem();
472: }
473:
474: public SComponent getTableCellRendererComponent(STable table,
475: Object value, boolean isSelected, int row, int column) {
476: setSelectedItem(value);
477: return this ;
478: }
479:
480: public LowLevelEventListener getLowLevelEventListener(
481: STable table, int row, int column) {
482: return this ;
483: }
484: }
485:
486: private static class DateEditableCellRenderer extends XCalendar
487: implements EditableTableCellRenderer {
488: public Object getValue() {
489: return getDate();
490: }
491:
492: public SComponent getTableCellRendererComponent(STable table,
493: Object value, boolean isSelected, int row, int column) {
494: setDate((Date) value);
495: return this ;
496: }
497:
498: public LowLevelEventListener getLowLevelEventListener(
499: STable table, int row, int column) {
500: return this ;
501: }
502:
503: public void setNameRaw(String uncheckedName) {
504: super .setNameRaw(uncheckedName);
505: getFormattedTextField().setNameRaw(uncheckedName);
506: }
507: }
508:
509: static class NoAction implements ActionListener {
510: public void actionPerformed(ActionEvent e) {
511: }
512: }
513:
514: private static class MyCellRenderer extends
515: SDefaultTableCellRenderer {
516: private final SFont MONOSPACE = new SFont("monospace",
517: SFont.BOLD, SFont.DEFAULT_SIZE);
518:
519: public MyCellRenderer() {
520: setEditIcon(getSession().getCGManager().getIcon(
521: "TableCG.editIcon"));
522: }
523:
524: public SComponent getTableCellRendererComponent(STable table,
525: Object value, boolean selected, int row, int col) {
526: setHorizontalAlignment(SConstants.LEFT);
527: setIcon(null);
528: setFont(null);
529: setForeground(null);
530: setComponentPopupMenu(null);
531:
532: if (value instanceof Color) {
533: Color c = (Color) value;
534: setFont(MONOSPACE);
535: setText(colorToHex(c));
536: setForeground(c);
537: return this ;
538: } else if (value instanceof Boolean && row != -1) {
539: setText("" + value);
540: return this ;
541: } else if (value instanceof Integer && row != -1) {
542: setHorizontalAlignment(SConstants.RIGHT);
543: return super .getTableCellRendererComponent(table,
544: value, selected, row, col);
545: } else
546: return super .getTableCellRendererComponent(table,
547: value, selected, row, col);
548: }
549: }
550:
551: private static String colorToHex(Color color) {
552: String colorstr = "#";
553:
554: // Red
555: String str = Integer.toHexString(color.getRed());
556: if (str.length() < 2)
557: colorstr += "0" + str;
558: else
559: colorstr += str;
560:
561: // Green
562: str = Integer.toHexString(color.getGreen());
563: if (str.length() < 2)
564: colorstr += "0" + str;
565: else
566: colorstr += str;
567:
568: // Blue
569: str = Integer.toHexString(color.getBlue());
570: if (str.length() < 2)
571: colorstr += "0" + str;
572: else
573: colorstr += str;
574:
575: return colorstr;
576: }
577:
578: }
|