Java/Swing Components/Grid Table
Содержание
- 1 Animated Icon Header Example
- 2 Animated Icon Table Example
- 3 Button Table Example
- 4 Calculated Column Table
- 5 Cell Border Table Example
- 6 Colored Cell Table Example
- 7 Column Border Table Example
- 8 Column popup menu
- 9 ComboBox Table
- 10 CurrencyTable
- 11 Each Row with different Editor Example
- 12 Editable Header Table Example
- 13 Editable Header Table Example 2
- 14 Editable Highlight Currency Table
- 15 Fixed Table Column Example
- 16 Fixed Table Row Example
- 17 Fraction Currency Table
- 18 Groupable(Group) Header Example
- 19 Hide Column Table Example
- 20 Highlight Currency Table
- 21 Highlight Currency Table 2
- 22 Icon Currency Table
- 23 Indicator Table Example
- 24 JSortTable
- 25 Mixed Table Example
- 26 MultiLine Cell Example
- 27 MultiLine Header Example
- 28 MultiLine Header Table
- 29 MultiLine Table
- 30 multiple Component Table 2: checkbox
- 31 Multiple Component Table: Checkbox and Combobox
- 32 multiple Font Cell Table Example
- 33 multiple Row Header Example
- 34 Multi Span Cell Table Example
- 35 MultiWidth Header Example
- 36 Pushable Table Header Example
- 37 Radio Button Table Example
- 38 RadioButton Table Example 2
- 39 Sortable Table Example
- 40 Striped Currency Table
- 41 Swing Table in ComboBox
- 42 Tabbable Currency Table
- 43 Table Row Header Example
- 44 Table Utilities
- 45 ToolTip Header Table Example
- 46 ToolTip Table
- 47 Total(Calculate) Row Example
- 48 Union Data Table Example
- 49 Updatable Highlight Currency Table
Animated Icon Header Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1.1beta2) */ import java.awt.Image; import java.awt.Rectangle; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.ImageObserver; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.table.AbstractTableModel; import javax.swing.table.JTableHeader; /**
* @version 1.0 06/19/99 */
public class AnimatedIconHeaderExample extends JFrame {
public AnimatedIconHeaderExample() { super("AnimatedIconHeader Example"); final Object[][] data = new Object[][] { { "Leopard", "Lycaon" }, { "Jagur", "Jackal" }, { "Cheetah", "Coyote" }, { "Puma", "Dingo" }, { "Lynx", "Fox" }, { "Tom", "Hot" } }; final String[] column = new String[] { "Cat", "Dog" }; ImageIcon[] icons = { new ImageIcon("jexpAnimation.gif"), new ImageIcon("jexpAnimation.gif") }; AbstractTableModel model = new AbstractTableModel() { public int getColumnCount() { return column.length; } public int getRowCount() { return data.length; } public String getColumnName(int col) { return column[col]; } public Object getValueAt(int row, int col) { return data[row][col]; } }; JTable table = new JTable(model); JTableHeader header = table.getTableHeader(); JLabel renderer; for (int i = 0; i < model.getColumnCount(); i++) { renderer = (JLabel) table.getColumn(column[i]).getHeaderRenderer(); renderer.setIcon(icons[i]); // If you have only one column. // icons[i].setImageObserver(header); icons[i].setImageObserver(new HeaderImageObserver(header, i)); } JScrollPane pane = new JScrollPane(table); getContentPane().add(pane); } class HeaderImageObserver implements ImageObserver { JTableHeader header; int col; HeaderImageObserver(JTableHeader header, int col) { this.header = header; this.col = col; } public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h) { if ((flags & (FRAMEBITS | ALLBITS)) != 0) { Rectangle rect = header.getHeaderRect(col); header.repaint(rect); } return (flags & (ALLBITS | ABORT)) == 0; } } public static void main(String[] args) { AnimatedIconHeaderExample frame = new AnimatedIconHeaderExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setSize(300, 140); frame.setVisible(true); }
}
</source>
Animated Icon Table Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1.1beta2) */
import java.awt.Image; import java.awt.Rectangle; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.ImageObserver; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableModel; /**
* @version 1.0 06/19/99 */
public class AnimatedIconTableExample extends JFrame {
public AnimatedIconTableExample() { super("AnimatedIconTable Example"); final Object[][] data = new Object[][] { { new ImageIcon("jexpAnimation.gif"), new ImageIcon("jexpAnimation.gif") }, { new ImageIcon("jexpAnimation.gif"), new ImageIcon("jexpAnimation.gif") } }; final Object[] column = new Object[] { "Boy and Girl", "Dog and Cat" }; AbstractTableModel model = new AbstractTableModel() { public int getColumnCount() { return column.length; } public int getRowCount() { return data.length; } public String getColumnName(int col) { return (String) column[col]; } public Object getValueAt(int row, int col) { return data[row][col]; } public Class getColumnClass(int col) { return ImageIcon.class; } }; JTable table = new JTable(model); table.setRowHeight(50); setImageObserver(table); JScrollPane pane = new JScrollPane(table); getContentPane().add(pane); } private void setImageObserver(JTable table) { TableModel model = table.getModel(); int colCount = model.getColumnCount(); int rowCount = model.getRowCount(); for (int col = 0; col < colCount; col++) { if (ImageIcon.class == model.getColumnClass(col)) { for (int row = 0; row < rowCount; row++) { ImageIcon icon = (ImageIcon) model.getValueAt(row, col); if (icon != null) { icon.setImageObserver(new CellImageObserver(table, row, col)); } } } } } class CellImageObserver implements ImageObserver { JTable table; int row; int col; CellImageObserver(JTable table, int row, int col) { this.table = table; this.row = row; this.col = col; } public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h) { if ((flags & (FRAMEBITS | ALLBITS)) != 0) { Rectangle rect = table.getCellRect(row, col, false); table.repaint(rect); } return (flags & (ALLBITS | ABORT)) == 0; } } public static void main(String[] args) { AnimatedIconTableExample frame = new AnimatedIconTableExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setSize(300, 150); frame.setVisible(true); }
}
</source>
Button Table Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html import java.awt.ruponent; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.DefaultCellEditor; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; /**
* @version 1.0 11/09/98 */
public class JButtonTableExample extends JFrame {
public JButtonTableExample() { super("JButtonTable Example"); DefaultTableModel dm = new DefaultTableModel(); dm.setDataVector(new Object[][] { { "button 1", "foo" }, { "button 2", "bar" } }, new Object[] { "Button", "String" }); JTable table = new JTable(dm); table.getColumn("Button").setCellRenderer(new ButtonRenderer()); table.getColumn("Button").setCellEditor( new ButtonEditor(new JCheckBox())); JScrollPane scroll = new JScrollPane(table); getContentPane().add(scroll); setSize(400, 100); setVisible(true); } public static void main(String[] args) { JButtonTableExample frame = new JButtonTableExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); }
} /**
* @version 1.0 11/09/98 */
class ButtonRenderer extends JButton implements TableCellRenderer {
public ButtonRenderer() { setOpaque(true); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (isSelected) { setForeground(table.getSelectionForeground()); setBackground(table.getSelectionBackground()); } else { setForeground(table.getForeground()); setBackground(UIManager.getColor("Button.background")); } setText((value == null) ? "" : value.toString()); return this; }
} /**
* @version 1.0 11/09/98 */
class ButtonEditor extends DefaultCellEditor {
protected JButton button; private String label; private boolean isPushed; public ButtonEditor(JCheckBox checkBox) { super(checkBox); button = new JButton(); button.setOpaque(true); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { fireEditingStopped(); } }); } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { if (isSelected) { button.setForeground(table.getSelectionForeground()); button.setBackground(table.getSelectionBackground()); } else { button.setForeground(table.getForeground()); button.setBackground(table.getBackground()); } label = (value == null) ? "" : value.toString(); button.setText(label); isPushed = true; return button; } public Object getCellEditorValue() { if (isPushed) { // // JOptionPane.showMessageDialog(button, label + ": Ouch!"); // System.out.println(label + ": Ouch!"); } isPushed = false; return new String(label); } public boolean stopCellEditing() { isPushed = false; return super.stopCellEditing(); } protected void fireEditingStopped() { super.fireEditingStopped(); }
}
</source>
Calculated Column Table
<source lang="java">
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall
- /
import java.awt.ruponent; import java.awt.Insets; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.text.NumberFormat; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; public class CalculatedColumnTable {
public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception evt) {} JFrame f = new JFrame("Calculated Column Table"); JTable tbl = new JTable(new CurrencyTableModel()); tbl.setDefaultRenderer(java.lang.Number.class, new FractionCellRenderer(10, 3, SwingConstants.RIGHT)); TableColumnModel tcm = tbl.getColumnModel(); TextWithIconCellRenderer renderer = new TextWithIconCellRenderer(); tcm.getColumn(0).setCellRenderer(renderer); // Automatically configure the column widths TableUtilities .setColumnWidths(tbl, new Insets(0, 4, 0, 4), true, false); tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tbl.setPreferredScrollableViewportSize(tbl.getPreferredSize()); // Diagnostics: display the chosen column widths for (int i = 0; i < tcm.getColumnCount(); i++) { System.out.println("Column " + i + ": width is " + tcm.getColumn(i).getPreferredWidth()); } JScrollPane sp = new JScrollPane(tbl); f.getContentPane().add(sp, "Center"); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); f.setVisible(true); }
} class DataWithIcon {
public DataWithIcon(Object data, Icon icon) { this.data = data; this.icon = icon; } public Icon getIcon() { return icon; } public Object getData() { return data; } public String toString() { return data.toString(); } protected Icon icon; protected Object data;
} class CurrencyTableModel extends AbstractTableModel {
protected String[] columnNames = { "Currency", "Yesterday", "Today", "Change" }; // Constructor: calculate currency change to create the last column public CurrencyTableModel() { for (int i = 0; i < data.length; i++) { data[i][DIFF_COLUMN] = new Double( ((Double) data[i][NEW_RATE_COLUMN]).doubleValue() - ((Double) data[i][OLD_RATE_COLUMN]).doubleValue()); } } // Implementation of TableModel interface public int getRowCount() { return data.length; } public int getColumnCount() { return COLUMN_COUNT; } public Object getValueAt(int row, int column) { return data[row][column]; } public Class getColumnClass(int column) { return (data[0][column]).getClass(); } public String getColumnName(int column) { return columnNames[column]; } protected static final int OLD_RATE_COLUMN = 1; protected static final int NEW_RATE_COLUMN = 2; protected static final int DIFF_COLUMN = 3; protected static final int COLUMN_COUNT = 4; protected static final Class thisClass = CurrencyTableModel.class; protected Object[][] data = new Object[][] { { new DataWithIcon("Belgian Franc", new ImageIcon(thisClass .getResource("belgium.gif"))), new Double(37.6460110), new Double(37.6508921), null }, { new DataWithIcon("British Pound", new ImageIcon(thisClass .getResource("gb.gif"))), new Double(0.6213051), new Double(0.6104102), null }, { new DataWithIcon("Canadian Dollar", new ImageIcon(thisClass .getResource("canada.gif"))), new Double(1.4651209), new Double(1.5011104), null }, { new DataWithIcon("French Franc", new ImageIcon(thisClass .getResource("france.gif"))), new Double(6.1060001), new Double(6.0100101), null }, { new DataWithIcon("Italian Lire", new ImageIcon(thisClass .getResource("italy.gif"))), new Double(1181.3668977), new Double(1182.104), null }, { new DataWithIcon("German Mark", new ImageIcon(thisClass .getResource("germany.gif"))), new Double(1.8191804), new Double(1.8223421), null }, { new DataWithIcon("Japanese Yen", new ImageIcon(thisClass .getResource("japan.gif"))), new Double(141.0815412), new Double(121.0040432), null } };
} class FractionCellRenderer extends DefaultTableCellRenderer {
public FractionCellRenderer(int integer, int fraction, int align) { this.integer = integer; // maximum integer digits this.fraction = fraction; // exact number of fraction digits this.align = align; // alignment (LEFT, CENTER, RIGHT) } protected void setValue(Object value) { if (value != null && value instanceof Number) { formatter.setMaximumIntegerDigits(integer); formatter.setMaximumFractionDigits(fraction); formatter.setMinimumFractionDigits(fraction); setText(formatter.format(((Number) value).doubleValue())); } else { super.setValue(value); } setHorizontalAlignment(align); } protected int integer; protected int fraction; protected int align; protected static NumberFormat formatter = NumberFormat.getInstance();
} class TextWithIconCellRenderer extends DefaultTableCellRenderer {
protected void setValue(Object value) { if (value instanceof DataWithIcon) { if (value != null) { DataWithIcon d = (DataWithIcon) value; Object dataValue = d.getData(); setText(dataValue == null ? "" : dataValue.toString()); setIcon(d.getIcon()); setHorizontalTextPosition(SwingConstants.RIGHT); setVerticalTextPosition(SwingConstants.CENTER); setHorizontalAlignment(SwingConstants.LEFT); setVerticalAlignment(SwingConstants.CENTER); } else { setText(""); setIcon(null); } } else { super.setValue(value); } }
} class TableUtilities {
// Calculate the required width of a table column public static int calculateColumnWidth(JTable table, int columnIndex) { int width = 0; // The return value int rowCount = table.getRowCount(); for (int i = 0; i < rowCount; i++) { TableCellRenderer renderer = table.getCellRenderer(i, columnIndex); Component comp = renderer.getTableCellRendererComponent(table, table.getValueAt(i, columnIndex), false, false, i, columnIndex); int thisWidth = comp.getPreferredSize().width; if (thisWidth > width) { width = thisWidth; } } return width; } // Set the widths of every column in a table public static void setColumnWidths(JTable table, Insets insets, boolean setMinimum, boolean setMaximum) { int columnCount = table.getColumnCount(); TableColumnModel tcm = table.getColumnModel(); int spare = (insets == null ? 0 : insets.left + insets.right); for (int i = 0; i < columnCount; i++) { int width = calculateColumnWidth(table, i); width += spare; TableColumn column = tcm.getColumn(i); column.setPreferredWidth(width); if (setMinimum == true) { column.setMinWidth(width); } if (setMaximum == true) { column.setMaxWidth(width); } } } // Sort an array of integers in place public static void sort(int[] values) { int length = values.length; if (length > 1) { for (int i = 0; i < length - 1; i++) { for (int j = i + 1; j < length; j++) { if (values[j] < values[i]) { int temp = values[i]; values[i] = values[j]; values[j] = temp; } } } } }
}
</source>
Cell Border Table Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1) */ import java.awt.BorderLayout; import java.awt.Color; import java.awt.ruponent; import java.awt.Dimension; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.border.AbstractBorder; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.border.TitledBorder; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; /**
* @version 1.0 3/06/99 */
public class CellBorderTableExample extends JFrame {
public CellBorderTableExample() { super("Cell Border Example"); final Color color = UIManager.getColor("Table.gridColor"); DefaultTableModel dm = new DefaultTableModel(12, 6) { public void setValueAt(Object obj, int row, int col) { if (obj instanceof MyData) { super.setValueAt(obj, row, col); } else { MyData myData = null; Object oldObject = getValueAt(row, col); if (oldObject == null) { myData = new MyData(obj, new LinesBorder(color, 0)); } else if (oldObject instanceof MyData) { myData = (MyData) oldObject; } else { System.out.println("error"); return; } myData.setObject(obj); super.setValueAt(myData, row, col); } } }; JTable table = new JTable(dm); table.setIntercellSpacing(new Dimension(0, 0)); table.setCellSelectionEnabled(true); table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); table.setDefaultRenderer(Object.class, new BorderCellRenderer()); JScrollPane scroll = new JScrollPane(table); ThicknessPanel thicknessPanel = new ThicknessPanel(); Box box = new Box(BoxLayout.Y_AXIS); box.add(thicknessPanel); box.add(new ButtonPanel(table, thicknessPanel)); getContentPane().add(scroll, BorderLayout.CENTER); getContentPane().add(box, BorderLayout.EAST); } public static void main(String[] args) { CellBorderTableExample frame = new CellBorderTableExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setSize(400, 240); frame.setVisible(true); } class ThicknessPanel extends JPanel { JComboBox[] combos; ThicknessPanel() { String[] str = { "top", "left", "bottom", "right" }; int n = str.length; setLayout(new GridLayout(n, 2)); setBorder(new TitledBorder("Thickness")); combos = new JComboBox[n]; for (int i = 0; i < n; i++) { combos[i] = new JComboBox(new Object[] { "0", "1", "2", "3" }); add(new JLabel(str[i])); add(combos[i]); } } public Insets getThickness() { Insets insets = new Insets(0, 0, 0, 0); insets.top = combos[0].getSelectedIndex(); insets.left = combos[1].getSelectedIndex(); insets.bottom = combos[2].getSelectedIndex(); insets.right = combos[3].getSelectedIndex(); return insets; } } class ButtonPanel extends JPanel { JTable table; ThicknessPanel thicknessPanel; Color color = UIManager.getColor("Table.gridColor"); ButtonPanel(JTable table, ThicknessPanel thicknessPanel) { this.table = table; this.thicknessPanel = thicknessPanel; setLayout(new GridLayout(3, 1)); setBorder(new TitledBorder("Append Lines")); final JCheckBox oneBlock = new JCheckBox("Block"); JButton b_and = new JButton("REPLACE"); JButton b_or = new JButton("OR"); add(oneBlock); add(b_and); add(b_or); b_and.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setCellBorder(true, oneBlock.isSelected()); } }); b_or.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { setCellBorder(false, oneBlock.isSelected()); } }); } private void setCellBorder(boolean isReplace, boolean isBlock) { boolean isTop, isLeft, isBottom, isRight; Insets insets = thicknessPanel.getThickness(); int[] columns = table.getSelectedColumns(); int[] rows = table.getSelectedRows(); int rowMax = rows.length; int columnMax = columns.length; for (int i = 0; i < rowMax; i++) { int row = rows[i]; isTop = (i == 0) ? true : false; isBottom = (i == rowMax - 1) ? true : false; for (int j = 0; j < columnMax; j++) { int column = columns[j]; isLeft = (j == 0) ? true : false; isRight = (j == columnMax - 1) ? true : false; MyData myData = (MyData) table.getValueAt(row, column); if (myData == null) { myData = new MyData("", new LinesBorder(color, 0)); } LinesBorder border = (LinesBorder) myData.getBorder(); if (isBlock) { Insets tmp = new Insets(0, 0, 0, 0); if (isTop) tmp.top = Math.max(tmp.top, insets.top); if (isLeft) tmp.left = Math.max(tmp.left, insets.left); if (isBottom) tmp.bottom = Math.max(tmp.bottom, insets.bottom); if (isRight) tmp.right = Math.max(tmp.right, insets.right); border.append(tmp, isReplace); } else { border.append(insets, isReplace); } table.setValueAt(myData, row, column); } } table.clearSelection(); table.revalidate(); table.repaint(); } } class MyData implements CellBorder { private Border border; private Object obj; public MyData(Object obj, Border border) { this.obj = obj; this.border = border; } public void setObject(Object obj) { this.obj = obj; } public String toString() { return obj.toString(); } // CellBorder public void setBorder(Border border) { this.border = border; } public Border getBorder() { return border; } public void setBorder(Border border, int row, int col) { } public Border getBorder(int row, int col) { return null; } }
} class BorderCellRenderer extends JLabel implements TableCellRenderer {
protected Border noFocusBorder; protected Border columnBorder; public BorderCellRenderer() { noFocusBorder = new EmptyBorder(1, 2, 1, 2); setOpaque(true); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (isSelected) { setForeground(table.getSelectionForeground()); setBackground(table.getSelectionBackground()); } else { setForeground(table.getForeground()); setBackground(table.getBackground()); } setFont(table.getFont()); if (hasFocus) { setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); if (table.isCellEditable(row, column)) { setForeground(UIManager.getColor("Table.focusCellForeground")); setBackground(UIManager.getColor("Table.focusCellBackground")); } } else { if (value instanceof CellBorder) { Border border = ((CellBorder) value).getBorder(); setBorder(border); } else { if (columnBorder != null) { setBorder(columnBorder); } else { setBorder(noFocusBorder); } } } setText((value == null) ? "" : value.toString()); return this; } public void setColumnBorder(Border border) { columnBorder = border; } public Border getColumnBorder() { return columnBorder; }
} interface CellBorder {
public Border getBorder(); public Border getBorder(int row, int column); public void setBorder(Border border); public void setBorder(Border border, int row, int column);
} class LinesBorder extends AbstractBorder implements SwingConstants {
protected int northThickness; protected int southThickness; protected int eastThickness; protected int westThickness; protected Color northColor; protected Color southColor; protected Color eastColor; protected Color westColor; public LinesBorder(Color color) { this(color, 1); } public LinesBorder(Color color, int thickness) { setColor(color); setThickness(thickness); } public LinesBorder(Color color, Insets insets) { setColor(color); setThickness(insets); } public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { Color oldColor = g.getColor(); g.setColor(northColor); for (int i = 0; i < northThickness; i++) { g.drawLine(x, y + i, x + width - 1, y + i); } g.setColor(southColor); for (int i = 0; i < southThickness; i++) { g .drawLine(x, y + height - i - 1, x + width - 1, y + height - i - 1); } g.setColor(eastColor); for (int i = 0; i < westThickness; i++) { g.drawLine(x + i, y, x + i, y + height - 1); } g.setColor(westColor); for (int i = 0; i < eastThickness; i++) { g.drawLine(x + width - i - 1, y, x + width - i - 1, y + height - 1); } g.setColor(oldColor); } public Insets getBorderInsets(Component c) { return new Insets(northThickness, westThickness, southThickness, eastThickness); } public Insets getBorderInsets(Component c, Insets insets) { return new Insets(northThickness, westThickness, southThickness, eastThickness); } public boolean isBorderOpaque() { return true; } public void setColor(Color c) { northColor = c; southColor = c; eastColor = c; westColor = c; } public void setColor(Color c, int direction) { switch (direction) { case NORTH: northColor = c; break; case SOUTH: southColor = c; break; case EAST: eastColor = c; break; case WEST: westColor = c; break; default: } } public void setThickness(int n) { northThickness = n; southThickness = n; eastThickness = n; westThickness = n; } public void setThickness(Insets insets) { northThickness = insets.top; southThickness = insets.bottom; eastThickness = insets.right; westThickness = insets.left; } public void setThickness(int n, int direction) { switch (direction) { case NORTH: northThickness = n; break; case SOUTH: southThickness = n; break; case EAST: eastThickness = n; break; case WEST: westThickness = n; break; default: } } public void append(LinesBorder b, boolean isReplace) { if (isReplace) { northThickness = b.northThickness; southThickness = b.southThickness; eastThickness = b.eastThickness; westThickness = b.westThickness; } else { northThickness = Math.max(northThickness, b.northThickness); southThickness = Math.max(southThickness, b.southThickness); eastThickness = Math.max(eastThickness, b.eastThickness); westThickness = Math.max(westThickness, b.westThickness); } } public void append(Insets insets, boolean isReplace) { if (isReplace) { northThickness = insets.top; southThickness = insets.bottom; eastThickness = insets.right; westThickness = insets.left; } else { northThickness = Math.max(northThickness, insets.top); southThickness = Math.max(southThickness, insets.bottom); eastThickness = Math.max(eastThickness, insets.right); westThickness = Math.max(westThickness, insets.left); } }
}
</source>
Colored Cell Table Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /*
* (swing1.1beta3) */
import java.awt.BorderLayout; import java.awt.Color; import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Enumeration; import java.util.Vector; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JColorChooser; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.event.TableModelEvent; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableModel; /**
* @version 1.0 11/22/98 */
public class ColoredCellTableExample extends JFrame {
private JTable table; private ColoredCell cellAtt; public ColoredCellTableExample() { super("Colored Cell Example"); AttributiveCellTableModel ml = new AttributiveCellTableModel(10, 6); cellAtt = (ColoredCell) ml.getCellAttribute(); table = new JTable(ml); table.setCellSelectionEnabled(true); table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); table.setDefaultRenderer(Object.class, new AttributiveCellRenderer()); JScrollPane scroll = new JScrollPane(table); JButton b_fore = new JButton("Foreground"); b_fore.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { changeColor(true); } }); JButton b_back = new JButton("Background"); b_back.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { changeColor(false); } }); JPanel p_buttons = new JPanel(); p_buttons.setLayout(new GridLayout(2, 1)); p_buttons.add(b_fore); p_buttons.add(b_back); Box box = new Box(BoxLayout.X_AXIS); box.add(scroll); box.add(new JSeparator(SwingConstants.HORIZONTAL)); box.add(p_buttons); getContentPane().add(box); setSize(400, 200); setVisible(true); } private final void changeColor(boolean isForeground) { int[] columns = table.getSelectedColumns(); int[] rows = table.getSelectedRows(); if ((rows == null) || (columns == null)) return; if ((rows.length < 1) || (columns.length < 1)) return; Color target = cellAtt.getForeground(rows[0], columns[0]); Color reference = cellAtt.getBackground(rows[0], columns[0]); for (int i = 0; i < rows.length; i++) { int row = rows[i]; for (int j = 0; j < columns.length; j++) { int column = columns[j]; target = (target != cellAtt.getForeground(row, column)) ? null : target; reference = (reference != cellAtt.getBackground(row, column)) ? null : reference; } } String title; if (isForeground) { target = (target != null) ? target : table.getForeground(); reference = (reference != null) ? reference : table.getBackground(); title = "Foreground Color"; } else { target = (reference != null) ? reference : table.getBackground(); reference = (target != null) ? target : table.getForeground(); title = "Foreground Color"; } TextColorChooser chooser = new TextColorChooser(target, reference, isForeground); Color color = chooser.showDialog(ColoredCellTableExample.this, title); if (color != null) { if (isForeground) { cellAtt.setForeground(color, rows, columns); } else { cellAtt.setBackground(color, rows, columns); } table.clearSelection(); table.revalidate(); table.repaint(); } } public static void main(String[] args) { ColoredCellTableExample frame = new ColoredCellTableExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); }
} /*
* (swing1.1beta3) * */
/**
* @version 1.0 11/22/98 */
class AttributiveCellTableModel extends DefaultTableModel {
protected CellAttribute cellAtt; public AttributiveCellTableModel() { this((Vector) null, 0); } public AttributiveCellTableModel(int numRows, int numColumns) { Vector names = new Vector(numColumns); names.setSize(numColumns); setColumnIdentifiers(names); dataVector = new Vector(); setNumRows(numRows); cellAtt = new DefaultCellAttribute(numRows, numColumns); } public AttributiveCellTableModel(Vector columnNames, int numRows) { setColumnIdentifiers(columnNames); dataVector = new Vector(); setNumRows(numRows); cellAtt = new DefaultCellAttribute(numRows, columnNames.size()); } public AttributiveCellTableModel(Object[] columnNames, int numRows) { this(convertToVector(columnNames), numRows); } public AttributiveCellTableModel(Vector data, Vector columnNames) { setDataVector(data, columnNames); } public AttributiveCellTableModel(Object[][] data, Object[] columnNames) { setDataVector(data, columnNames); } public void setDataVector(Vector newData, Vector columnNames) { if (newData == null) throw new IllegalArgumentException("setDataVector() - Null parameter"); dataVector = new Vector(0); setColumnIdentifiers(columnNames); dataVector = newData; // cellAtt = new DefaultCellAttribute(dataVector.size(), columnIdentifiers .size()); newRowsAdded(new TableModelEvent(this, 0, getRowCount() - 1, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } public void addColumn(Object columnName, Vector columnData) { if (columnName == null) throw new IllegalArgumentException("addColumn() - null parameter"); columnIdentifiers.addElement(columnName); int index = 0; Enumeration eeration = dataVector.elements(); while (eeration.hasMoreElements()) { Object value; if ((columnData != null) && (index < columnData.size())) value = columnData.elementAt(index); else value = null; ((Vector) eeration.nextElement()).addElement(value); index++; } // cellAtt.addColumn(); fireTableStructureChanged(); } public void addRow(Vector rowData) { Vector newData = null; if (rowData == null) { newData = new Vector(getColumnCount()); } else { rowData.setSize(getColumnCount()); } dataVector.addElement(newData); // cellAtt.addRow(); newRowsAdded(new TableModelEvent(this, getRowCount() - 1, getRowCount() - 1, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } public void insertRow(int row, Vector rowData) { if (rowData == null) { rowData = new Vector(getColumnCount()); } else { rowData.setSize(getColumnCount()); } dataVector.insertElementAt(rowData, row); // cellAtt.insertRow(row); newRowsAdded(new TableModelEvent(this, row, row, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } public CellAttribute getCellAttribute() { return cellAtt; } public void setCellAttribute(CellAttribute newCellAtt) { int numColumns = getColumnCount(); int numRows = getRowCount(); if ((newCellAtt.getSize().width != numColumns) || (newCellAtt.getSize().height != numRows)) { newCellAtt.setSize(new Dimension(numRows, numColumns)); } cellAtt = newCellAtt; fireTableDataChanged(); } /* * public void changeCellAttribute(int row, int column, Object command) { * cellAtt.changeAttribute(row, column, command); } * * public void changeCellAttribute(int[] rows, int[] columns, Object * command) { cellAtt.changeAttribute(rows, columns, command); } */
} /**
* @version 1.0 11/22/98 */
class DefaultCellAttribute // implements CellAttribute ,CellSpan {
implements CellAttribute, CellSpan, ColoredCell, CellFont { // // !!!! CAUTION !!!!! // these values must be synchronized to Table data // protected int rowSize; protected int columnSize; protected int[][][] span; // CellSpan protected Color[][] foreground; // ColoredCell protected Color[][] background; // protected Font[][] font; // CellFont public DefaultCellAttribute() { this(1, 1); } public DefaultCellAttribute(int numRows, int numColumns) { setSize(new Dimension(numColumns, numRows)); } protected void initValue() { for (int i = 0; i < span.length; i++) { for (int j = 0; j < span[i].length; j++) { span[i][j][CellSpan.COLUMN] = 1; span[i][j][CellSpan.ROW] = 1; } } } // // CellSpan // public int[] getSpan(int row, int column) { if (isOutOfBounds(row, column)) { int[] ret_code = { 1, 1 }; return ret_code; } return span[row][column]; } public void setSpan(int[] span, int row, int column) { if (isOutOfBounds(row, column)) return; this.span[row][column] = span; } public boolean isVisible(int row, int column) { if (isOutOfBounds(row, column)) return false; if ((span[row][column][CellSpan.COLUMN] < 1) || (span[row][column][CellSpan.ROW] < 1)) return false; return true; } public void combine(int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; int rowSpan = rows.length; int columnSpan = columns.length; int startRow = rows[0]; int startColumn = columns[0]; for (int i = 0; i < rowSpan; i++) { for (int j = 0; j < columnSpan; j++) { if ((span[startRow + i][startColumn + j][CellSpan.COLUMN] != 1) || (span[startRow + i][startColumn + j][CellSpan.ROW] != 1)) { //System.out.println("can"t combine"); return; } } } for (int i = 0, ii = 0; i < rowSpan; i++, ii--) { for (int j = 0, jj = 0; j < columnSpan; j++, jj--) { span[startRow + i][startColumn + j][CellSpan.COLUMN] = jj; span[startRow + i][startColumn + j][CellSpan.ROW] = ii; //System.out.println("r " +ii +" c " +jj); } } span[startRow][startColumn][CellSpan.COLUMN] = columnSpan; span[startRow][startColumn][CellSpan.ROW] = rowSpan; } public void split(int row, int column) { if (isOutOfBounds(row, column)) return; int columnSpan = span[row][column][CellSpan.COLUMN]; int rowSpan = span[row][column][CellSpan.ROW]; for (int i = 0; i < rowSpan; i++) { for (int j = 0; j < columnSpan; j++) { span[row + i][column + j][CellSpan.COLUMN] = 1; span[row + i][column + j][CellSpan.ROW] = 1; } } } // // ColoredCell // public Color getForeground(int row, int column) { if (isOutOfBounds(row, column)) return null; return foreground[row][column]; } public void setForeground(Color color, int row, int column) { if (isOutOfBounds(row, column)) return; foreground[row][column] = color; } public void setForeground(Color color, int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; setValues(foreground, color, rows, columns); } public Color getBackground(int row, int column) { if (isOutOfBounds(row, column)) return null; return background[row][column]; } public void setBackground(Color color, int row, int column) { if (isOutOfBounds(row, column)) return; background[row][column] = color; } public void setBackground(Color color, int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; setValues(background, color, rows, columns); } // // // CellFont // public Font getFont(int row, int column) { if (isOutOfBounds(row, column)) return null; return font[row][column]; } public void setFont(Font font, int row, int column) { if (isOutOfBounds(row, column)) return; this.font[row][column] = font; } public void setFont(Font font, int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; setValues(this.font, font, rows, columns); } // // // CellAttribute // public void addColumn() { int[][][] oldSpan = span; int numRows = oldSpan.length; int numColumns = oldSpan[0].length; span = new int[numRows][numColumns + 1][2]; System.arraycopy(oldSpan, 0, span, 0, numRows); for (int i = 0; i < numRows; i++) { span[i][numColumns][CellSpan.COLUMN] = 1; span[i][numColumns][CellSpan.ROW] = 1; } } public void addRow() { int[][][] oldSpan = span; int numRows = oldSpan.length; int numColumns = oldSpan[0].length; span = new int[numRows + 1][numColumns][2]; System.arraycopy(oldSpan, 0, span, 0, numRows); for (int i = 0; i < numColumns; i++) { span[numRows][i][CellSpan.COLUMN] = 1; span[numRows][i][CellSpan.ROW] = 1; } } public void insertRow(int row) { int[][][] oldSpan = span; int numRows = oldSpan.length; int numColumns = oldSpan[0].length; span = new int[numRows + 1][numColumns][2]; if (0 < row) { System.arraycopy(oldSpan, 0, span, 0, row - 1); } System.arraycopy(oldSpan, 0, span, row, numRows - row); for (int i = 0; i < numColumns; i++) { span[row][i][CellSpan.COLUMN] = 1; span[row][i][CellSpan.ROW] = 1; } } public Dimension getSize() { return new Dimension(rowSize, columnSize); } public void setSize(Dimension size) { columnSize = size.width; rowSize = size.height; span = new int[rowSize][columnSize][2]; // 2: COLUMN,ROW foreground = new Color[rowSize][columnSize]; background = new Color[rowSize][columnSize]; font = new Font[rowSize][columnSize]; initValue(); } /* * public void changeAttribute(int row, int column, Object command) { } * * public void changeAttribute(int[] rows, int[] columns, Object command) { } */ protected boolean isOutOfBounds(int row, int column) { if ((row < 0) || (rowSize <= row) || (column < 0) || (columnSize <= column)) { return true; } return false; } protected boolean isOutOfBounds(int[] rows, int[] columns) { for (int i = 0; i < rows.length; i++) { if ((rows[i] < 0) || (rowSize <= rows[i])) return true; } for (int i = 0; i < columns.length; i++) { if ((columns[i] < 0) || (columnSize <= columns[i])) return true; } return false; } protected void setValues(Object[][] target, Object value, int[] rows, int[] columns) { for (int i = 0; i < rows.length; i++) { int row = rows[i]; for (int j = 0; j < columns.length; j++) { int column = columns[j]; target[row][column] = value; } } }
} /**
* @version 1.0 11/22/98 */
/*
* (swing1.1beta3) * */
/**
* @version 1.0 11/22/98 */
interface CellAttribute {
public void addColumn(); public void addRow(); public void insertRow(int row); public Dimension getSize(); public void setSize(Dimension size);
} interface ColoredCell {
public Color getForeground(int row, int column); public void setForeground(Color color, int row, int column); public void setForeground(Color color, int[] rows, int[] columns); public Color getBackground(int row, int column); public void setBackground(Color color, int row, int column); public void setBackground(Color color, int[] rows, int[] columns);
} /**
* @version 1.0 11/22/98 */
class AttributiveCellRenderer extends JLabel implements TableCellRenderer {
protected static Border noFocusBorder; public AttributiveCellRenderer() { noFocusBorder = new EmptyBorder(1, 2, 1, 2); setOpaque(true); setBorder(noFocusBorder); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Color foreground = null; Color background = null; Font font = null; TableModel model = table.getModel(); if (model instanceof AttributiveCellTableModel) { CellAttribute cellAtt = ((AttributiveCellTableModel) model) .getCellAttribute(); if (cellAtt instanceof ColoredCell) { foreground = ((ColoredCell) cellAtt).getForeground(row, column); background = ((ColoredCell) cellAtt).getBackground(row, column); } if (cellAtt instanceof CellFont) { font = ((CellFont) cellAtt).getFont(row, column); } } if (isSelected) { setForeground((foreground != null) ? foreground : table .getSelectionForeground()); setBackground(table.getSelectionBackground()); } else { setForeground((foreground != null) ? foreground : table .getForeground()); setBackground((background != null) ? background : table .getBackground()); } setFont((font != null) ? font : table.getFont()); if (hasFocus) { setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); if (table.isCellEditable(row, column)) { setForeground((foreground != null) ? foreground : UIManager .getColor("Table.focusCellForeground")); setBackground(UIManager.getColor("Table.focusCellBackground")); } } else { setBorder(noFocusBorder); } setValue(value); return this; } protected void setValue(Object value) { setText((value == null) ? "" : value.toString()); }
} /**
* @version 1.0 11/22/98 */
class TextPreviewLabel extends JLabel {
private String sampleText = " Sample Text Sample Text "; boolean isForgroundSelection; public TextPreviewLabel() { this(Color.black, Color.white, true); } public TextPreviewLabel(Color fore, Color back, boolean isForgroundSelection) { setOpaque(true); setForeground(fore); setBackground(back); this.isForgroundSelection = isForgroundSelection; setText(sampleText); } public void setForeground(Color col) { if (isForgroundSelection) { super.setForeground(col); } else { super.setBackground(col); } }
} class ColorChooserDialog extends JDialog {
private Color initialColor; private Color retColor; private JColorChooser chooserPane; public ColorChooserDialog(Component c, String title, final JColorChooser chooserPane) { super(JOptionPane.getFrameForComponent(c), title, true); setResizable(false); this.chooserPane = chooserPane; String okString = UIManager.getString("ColorChooser.okText"); String cancelString = UIManager.getString("ColorChooser.cancelText"); String resetString = UIManager.getString("ColorChooser.resetText"); Container contentPane = getContentPane(); contentPane.setLayout(new BorderLayout()); contentPane.add(chooserPane, BorderLayout.CENTER); JPanel buttonPane = new JPanel(); buttonPane.setLayout(new FlowLayout(FlowLayout.CENTER)); JButton okButton = new JButton(okString); getRootPane().setDefaultButton(okButton); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { retColor = chooserPane.getColor(); setVisible(false); } }); buttonPane.add(okButton); JButton cancelButton = new JButton(cancelString); cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { retColor = null; setVisible(false); } }); buttonPane.add(cancelButton); JButton resetButton = new JButton(resetString); resetButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { chooserPane.setColor(initialColor); } }); buttonPane.add(resetButton); contentPane.add(buttonPane, BorderLayout.SOUTH); pack(); setLocationRelativeTo(c); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { setVisible(false); } }); } public Color getColor() { return retColor; }
} class TextColorChooser extends JColorChooser {
public TextColorChooser(Color target, Color reference, boolean isForgroundSelection) { super(target); if (isForgroundSelection) { setPreviewPanel(new TextPreviewLabel(target, reference, isForgroundSelection)); } else { setPreviewPanel(new TextPreviewLabel(reference, target, isForgroundSelection)); } updateUI(); } public Color showDialog(Component component, String title) { ColorChooserDialog dialog = new ColorChooserDialog(component, title, this); dialog.show(); Color col = dialog.getColor(); dialog.dispose(); return col; }
} interface CellFont {
public Font getFont(int row, int column); public void setFont(Font font, int row, int column); public void setFont(Font font, int[] rows, int[] columns);
} interface CellSpan {
public final int ROW = 0; public final int COLUMN = 1; public int[] getSpan(int row, int column); public void setSpan(int[] span, int row, int column); public boolean isVisible(int row, int column); public void combine(int[] rows, int[] columns); public void split(int row, int column);
}
</source>
Column Border Table Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1) */
import java.awt.BorderLayout; import java.awt.Color; import java.awt.ruponent; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Insets; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.border.AbstractBorder; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumnModel; /**
* @version 1.0 3/06/99 */
public class ColumnBorderTableExample extends JFrame {
public ColumnBorderTableExample() { super("Column Border Example"); DefaultTableModel dm = new DefaultTableModel(4, 10); JTable table = new JTable(dm); table.setIntercellSpacing(new Dimension(0, 0)); Color color = table.getGridColor(); BorderCellRenderer[] renderers = new BorderCellRenderer[6]; renderers[0] = createRenderer(color, new Insets(0, 0, 0, 1)); renderers[1] = createRenderer(color, new Insets(0, 1, 0, 1)); renderers[2] = createRenderer(color, new Insets(0, 1, 0, 2)); renderers[3] = createRenderer(color, new Insets(0, 2, 0, 2)); renderers[4] = createRenderer(color, new Insets(0, 2, 0, 0)); renderers[5] = createRenderer(Color.red, new Insets(0, 1, 1, 1)); TableColumnModel model = table.getColumnModel(); model.getColumn(1).setCellRenderer(renderers[0]); model.getColumn(2).setCellRenderer(renderers[0]); model.getColumn(3).setCellRenderer(renderers[0]); model.getColumn(4).setCellRenderer(renderers[1]); model.getColumn(5).setCellRenderer(renderers[2]); model.getColumn(6).setCellRenderer(renderers[3]); model.getColumn(7).setCellRenderer(renderers[4]); model.getColumn(8).setCellRenderer(renderers[5]); JScrollPane scroll = new JScrollPane(table); getContentPane().add(scroll, BorderLayout.CENTER); } public static void main(String[] args) { ColumnBorderTableExample frame = new ColumnBorderTableExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setSize(300, 120); frame.setVisible(true); } private static BorderCellRenderer createRenderer(Color color, Insets insets) { BorderCellRenderer renderer = new BorderCellRenderer(); renderer.setColumnBorder(new LinesBorder(color, insets)); return renderer; }
} class BorderCellRenderer extends JLabel implements TableCellRenderer {
protected Border noFocusBorder; protected Border columnBorder; public BorderCellRenderer() { noFocusBorder = new EmptyBorder(1, 2, 1, 2); setOpaque(true); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (isSelected) { setForeground(table.getSelectionForeground()); setBackground(table.getSelectionBackground()); } else { setForeground(table.getForeground()); setBackground(table.getBackground()); } setFont(table.getFont()); if (hasFocus) { setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); if (table.isCellEditable(row, column)) { setForeground(UIManager.getColor("Table.focusCellForeground")); setBackground(UIManager.getColor("Table.focusCellBackground")); } } else { if (value instanceof CellBorder) { Border border = ((CellBorder) value).getBorder(); setBorder(border); } else { if (columnBorder != null) { setBorder(columnBorder); } else { setBorder(noFocusBorder); } } } setText((value == null) ? "" : value.toString()); return this; } public void setColumnBorder(Border border) { columnBorder = border; } public Border getColumnBorder() { return columnBorder; }
} interface CellBorder {
public Border getBorder(); public Border getBorder(int row, int column); public void setBorder(Border border); public void setBorder(Border border, int row, int column);
} class LinesBorder extends AbstractBorder implements SwingConstants {
protected int northThickness; protected int southThickness; protected int eastThickness; protected int westThickness; protected Color northColor; protected Color southColor; protected Color eastColor; protected Color westColor; public LinesBorder(Color color) { this(color, 1); } public LinesBorder(Color color, int thickness) { setColor(color); setThickness(thickness); } public LinesBorder(Color color, Insets insets) { setColor(color); setThickness(insets); } public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { Color oldColor = g.getColor(); g.setColor(northColor); for (int i = 0; i < northThickness; i++) { g.drawLine(x, y + i, x + width - 1, y + i); } g.setColor(southColor); for (int i = 0; i < southThickness; i++) { g .drawLine(x, y + height - i - 1, x + width - 1, y + height - i - 1); } g.setColor(eastColor); for (int i = 0; i < westThickness; i++) { g.drawLine(x + i, y, x + i, y + height - 1); } g.setColor(westColor); for (int i = 0; i < eastThickness; i++) { g.drawLine(x + width - i - 1, y, x + width - i - 1, y + height - 1); } g.setColor(oldColor); } public Insets getBorderInsets(Component c) { return new Insets(northThickness, westThickness, southThickness, eastThickness); } public Insets getBorderInsets(Component c, Insets insets) { return new Insets(northThickness, westThickness, southThickness, eastThickness); } public boolean isBorderOpaque() { return true; } public void setColor(Color c) { northColor = c; southColor = c; eastColor = c; westColor = c; } public void setColor(Color c, int direction) { switch (direction) { case NORTH: northColor = c; break; case SOUTH: southColor = c; break; case EAST: eastColor = c; break; case WEST: westColor = c; break; default: } } public void setThickness(int n) { northThickness = n; southThickness = n; eastThickness = n; westThickness = n; } public void setThickness(Insets insets) { northThickness = insets.top; southThickness = insets.bottom; eastThickness = insets.right; westThickness = insets.left; } public void setThickness(int n, int direction) { switch (direction) { case NORTH: northThickness = n; break; case SOUTH: southThickness = n; break; case EAST: eastThickness = n; break; case WEST: westThickness = n; break; default: } } public void append(LinesBorder b, boolean isReplace) { if (isReplace) { northThickness = b.northThickness; southThickness = b.southThickness; eastThickness = b.eastThickness; westThickness = b.westThickness; } else { northThickness = Math.max(northThickness, b.northThickness); southThickness = Math.max(southThickness, b.southThickness); eastThickness = Math.max(eastThickness, b.eastThickness); westThickness = Math.max(westThickness, b.westThickness); } } public void append(Insets insets, boolean isReplace) { if (isReplace) { northThickness = insets.top; southThickness = insets.bottom; eastThickness = insets.right; westThickness = insets.left; } else { northThickness = Math.max(northThickness, insets.top); southThickness = Math.max(southThickness, insets.bottom); eastThickness = Math.max(eastThickness, insets.right); westThickness = Math.max(westThickness, insets.left); } }
}
</source>
<source lang="java">
(From http://swinglabs.org/downloads.jsp)
</source>
ComboBox Table
<source lang="java">
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall
- /
import javax.swing.*; import javax.swing.table.*; import java.awt.event.*; public class ComboBoxTable {
public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception evt) {} JFrame f = new JFrame("Combo Box Table"); JTable tbl = new JTable(new ComboBoxTableModel()); // Create the combo box editor JComboBox comboBox = new JComboBox(ComboBoxTableModel.getValidStates()); comboBox.setEditable(true); DefaultCellEditor editor = new DefaultCellEditor(comboBox); // Assign the editor to the second column TableColumnModel tcm = tbl.getColumnModel(); tcm.getColumn(1).setCellEditor(editor); // Set column widths tcm.getColumn(0).setPreferredWidth(200); tcm.getColumn(1).setPreferredWidth(100); // Set row heighht tbl.setRowHeight(20); tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tbl.setPreferredScrollableViewportSize(tbl.getPreferredSize()); f.getContentPane().add(new JScrollPane(tbl), "Center"); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); f.setVisible(true); }
} class ComboBoxTableModel extends AbstractTableModel {
// Implementation of TableModel interface public int getRowCount() { return data.length; } public int getColumnCount() { return COLUMN_COUNT; } public Object getValueAt(int row, int column) { return data[row][column]; } public Class getColumnClass(int column) { return (data[0][column]).getClass(); } public String getColumnName(int column) { return columnNames[column]; } public boolean isCellEditable(int row, int column) { return column == 1; } public void setValueAt(Object value, int row, int column) { if (isValidValue(value)) { data[row][column] = value; fireTableRowsUpdated(row, row); } } // Extra public methods public static String[] getValidStates() { return validStates; } // Protected methods protected boolean isValidValue(Object value) { if (value instanceof String) { String sValue = (String)value; for (int i = 0; i < validStates.length; i++) { if (sValue.equals(validStates[i])) { return true; } } } return false; } protected static final int COLUMN_COUNT = 2; protected static final String[] validStates = { "On order", "In stock", "Out of print" }; protected Object[][] data = new Object[][] { { "Core Java Volume 1", validStates[0] }, { "Core Java Volume 2", validStates[0] }, { "Core Web Programming", validStates[0] }, { "Core Visual Basic 5", validStates[0] }, { "Core Java Foundation Classes", validStates[0] } }; protected static final String[] columnNames = { "Book Name", "Status" };
}
</source>
CurrencyTable
<source lang="java">
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall
- /
import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableColumnModel; public class CurrencyTable {
public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception evt) {} JFrame f = new JFrame("Currency Table"); JTable tbl = new JTable(new CurrencyTableModel()); TableColumnModel tcm = tbl.getColumnModel(); tcm.getColumn(0).setPreferredWidth(150); tcm.getColumn(0).setMinWidth(150); tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tbl.setPreferredScrollableViewportSize(tbl.getPreferredSize()); JScrollPane sp = new JScrollPane(tbl); f.getContentPane().add(sp, "Center"); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); f.setVisible(true); }
} class DataWithIcon {
public DataWithIcon(Object data, Icon icon) { this.data = data; this.icon = icon; } public Icon getIcon() { return icon; } public Object getData() { return data; } public String toString() { return data.toString(); } protected Icon icon; protected Object data;
} class CurrencyTableModel extends AbstractTableModel {
protected String[] columnNames = { "Currency", "Yesterday", "Today", "Change" }; // Constructor: calculate currency change to create the last column public CurrencyTableModel() { for (int i = 0; i < data.length; i++) { data[i][DIFF_COLUMN] = new Double( ((Double) data[i][NEW_RATE_COLUMN]).doubleValue() - ((Double) data[i][OLD_RATE_COLUMN]).doubleValue()); } } // Implementation of TableModel interface public int getRowCount() { return data.length; } public int getColumnCount() { return COLUMN_COUNT; } public Object getValueAt(int row, int column) { return data[row][column]; } public Class getColumnClass(int column) { return (data[0][column]).getClass(); } public String getColumnName(int column) { return columnNames[column]; } protected static final int OLD_RATE_COLUMN = 1; protected static final int NEW_RATE_COLUMN = 2; protected static final int DIFF_COLUMN = 3; protected static final int COLUMN_COUNT = 4; protected static final Class thisClass = CurrencyTableModel.class; protected Object[][] data = new Object[][] { { new DataWithIcon("Belgian Franc", new ImageIcon(thisClass .getResource("belgium.gif"))), new Double(37.6460110), new Double(37.6508921), null }, { new DataWithIcon("British Pound", new ImageIcon(thisClass .getResource("gb.gif"))), new Double(0.6213051), new Double(0.6104102), null }, { new DataWithIcon("Canadian Dollar", new ImageIcon(thisClass .getResource("canada.gif"))), new Double(1.4651209), new Double(1.5011104), null }, { new DataWithIcon("French Franc", new ImageIcon(thisClass .getResource("france.gif"))), new Double(6.1060001), new Double(6.0100101), null }, { new DataWithIcon("Italian Lire", new ImageIcon(thisClass .getResource("italy.gif"))), new Double(1181.3668977), new Double(1182.104), null }, { new DataWithIcon("German Mark", new ImageIcon(thisClass .getResource("germany.gif"))), new Double(1.8191804), new Double(1.8223421), null }, { new DataWithIcon("Japanese Yen", new ImageIcon(thisClass .getResource("japan.gif"))), new Double(141.0815412), new Double(121.0040432), null } };
}
</source>
Each Row with different Editor Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1.1) */
import java.awt.BorderLayout; import java.awt.ruponent; import java.awt.event.ruponentAdapter; import java.awt.event.ruponentEvent; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.EventObject; import java.util.Hashtable; import javax.swing.DefaultCellEditor; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.CellEditorListener; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellEditor; /**
* @version 1.1 09/09/99 */
public class EachRowEditorExample extends JFrame {
public EachRowEditorExample() { super("EachRow Editor Example"); DefaultTableModel dm = new DefaultTableModel(); dm.setDataVector(new Object[][] { { "Name", "MyName" }, { "Gender", "Male" } }, new Object[] { "Column1", "Column2" }); JTable table = new JTable(dm); JComboBox comboBox = new JComboBox(); comboBox.addItem("Male"); comboBox.addItem("Female"); comboBox.addComponentListener(new ComponentAdapter() { public void componentShown(ComponentEvent e) { final JComponent c = (JComponent) e.getSource(); SwingUtilities.invokeLater(new Runnable() { public void run() { c.requestFocus(); System.out.println(c); if (c instanceof JComboBox) { System.out.println("a"); } } }); } }); EachRowEditor rowEditor = new EachRowEditor(table); rowEditor.setEditorAt(1, new DefaultCellEditor(comboBox)); table.getColumn("Column2").setCellEditor(rowEditor); JScrollPane scroll = new JScrollPane(table); getContentPane().add(scroll, BorderLayout.CENTER); setSize(400, 100); setVisible(true); } public static void main(String[] args) { EachRowEditorExample frame = new EachRowEditorExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); }
} /**
* each row TableCellEditor * * @version 1.1 09/09/99 * @author Nobuo Tamemasa */
class EachRowEditor implements TableCellEditor {
protected Hashtable editors; protected TableCellEditor editor, defaultEditor; JTable table; /** * Constructs a EachRowEditor. create default editor * * @see TableCellEditor * @see DefaultCellEditor */ public EachRowEditor(JTable table) { this.table = table; editors = new Hashtable(); defaultEditor = new DefaultCellEditor(new JTextField()); } /** * @param row * table row * @param editor * table cell editor */ public void setEditorAt(int row, TableCellEditor editor) { editors.put(new Integer(row), editor); } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { //editor = (TableCellEditor)editors.get(new Integer(row)); //if (editor == null) { // editor = defaultEditor; //} return editor.getTableCellEditorComponent(table, value, isSelected, row, column); } public Object getCellEditorValue() { return editor.getCellEditorValue(); } public boolean stopCellEditing() { return editor.stopCellEditing(); } public void cancelCellEditing() { editor.cancelCellEditing(); } public boolean isCellEditable(EventObject anEvent) { selectEditor((MouseEvent) anEvent); return editor.isCellEditable(anEvent); } public void addCellEditorListener(CellEditorListener l) { editor.addCellEditorListener(l); } public void removeCellEditorListener(CellEditorListener l) { editor.removeCellEditorListener(l); } public boolean shouldSelectCell(EventObject anEvent) { selectEditor((MouseEvent) anEvent); return editor.shouldSelectCell(anEvent); } protected void selectEditor(MouseEvent e) { int row; if (e == null) { row = table.getSelectionModel().getAnchorSelectionIndex(); } else { row = table.rowAtPoint(e.getPoint()); } editor = (TableCellEditor) editors.get(new Integer(row)); if (editor == null) { editor = defaultEditor; } }
}
</source>
Editable Header Table Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html import java.awt.ruponent; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.EventObject; import javax.swing.DefaultCellEditor; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.CellEditorListener; import javax.swing.event.ChangeEvent; import javax.swing.event.MouseInputListener; import javax.swing.plaf.basic.BasicTableHeaderUI; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellEditor; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; /**
* @version 1.0 08/22/99 */
public class EditableHeaderTableExample extends JFrame {
public EditableHeaderTableExample() { super("EditableHeader Example"); JTable table = new JTable(7, 5); TableColumnModel columnModel = table.getColumnModel(); table.setTableHeader(new EditableHeader(columnModel)); JScrollPane pane = new JScrollPane(table); getContentPane().add(pane); } public static void main(String[] args) { EditableHeaderTableExample frame = new EditableHeaderTableExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setSize(300, 100); frame.setVisible(true); }
} class EditableHeader extends JTableHeader implements CellEditorListener {
public final int HEADER_ROW = -10; transient protected int editingColumn; transient protected TableCellEditor cellEditor; transient protected Component editorComp; public EditableHeader(TableColumnModel columnModel) { super(columnModel); setReorderingAllowed(false); cellEditor = null; recreateTableColumn(columnModel); } public void updateUI() { setUI(new EditableHeaderUI()); resizeAndRepaint(); invalidate(); } protected void recreateTableColumn(TableColumnModel columnModel) { int n = columnModel.getColumnCount(); EditableHeaderTableColumn[] newCols = new EditableHeaderTableColumn[n]; TableColumn[] oldCols = new TableColumn[n]; for (int i = 0; i < n; i++) { oldCols[i] = columnModel.getColumn(i); newCols[i] = new EditableHeaderTableColumn(); newCols[i].copyValues(oldCols[i]); } for (int i = 0; i < n; i++) { columnModel.removeColumn(oldCols[i]); } for (int i = 0; i < n; i++) { columnModel.addColumn(newCols[i]); } } public boolean editCellAt(int index) { return editCellAt(index); } public boolean editCellAt(int index, EventObject e) { if (cellEditor != null && !cellEditor.stopCellEditing()) { return false; } if (!isCellEditable(index)) { return false; } TableCellEditor editor = getCellEditor(index); if (editor != null && editor.isCellEditable(e)) { editorComp = prepareEditor(editor, index); editorComp.setBounds(getHeaderRect(index)); add(editorComp); editorComp.validate(); setCellEditor(editor); setEditingColumn(index); editor.addCellEditorListener(this); return true; } return false; } public boolean isCellEditable(int index) { if (getReorderingAllowed()) { return false; } int columnIndex = columnModel.getColumn(index).getModelIndex(); EditableHeaderTableColumn col = (EditableHeaderTableColumn) columnModel .getColumn(columnIndex); return col.isHeaderEditable(); } public TableCellEditor getCellEditor(int index) { int columnIndex = columnModel.getColumn(index).getModelIndex(); EditableHeaderTableColumn col = (EditableHeaderTableColumn) columnModel .getColumn(columnIndex); return col.getHeaderEditor(); } public void setCellEditor(TableCellEditor newEditor) { TableCellEditor oldEditor = cellEditor; cellEditor = newEditor; // firePropertyChange if (oldEditor != null && oldEditor instanceof TableCellEditor) { ((TableCellEditor) oldEditor) .removeCellEditorListener((CellEditorListener) this); } if (newEditor != null && newEditor instanceof TableCellEditor) { ((TableCellEditor) newEditor) .addCellEditorListener((CellEditorListener) this); } } public Component prepareEditor(TableCellEditor editor, int index) { Object value = columnModel.getColumn(index).getHeaderValue(); boolean isSelected = true; int row = HEADER_ROW; JTable table = getTable(); Component comp = editor.getTableCellEditorComponent(table, value, isSelected, row, index); if (comp instanceof JComponent) { ((JComponent) comp).setNextFocusableComponent(this); } return comp; } public TableCellEditor getCellEditor() { return cellEditor; } public Component getEditorComponent() { return editorComp; } public void setEditingColumn(int aColumn) { editingColumn = aColumn; } public int getEditingColumn() { return editingColumn; } public void removeEditor() { TableCellEditor editor = getCellEditor(); if (editor != null) { editor.removeCellEditorListener(this); requestFocus(); remove(editorComp); int index = getEditingColumn(); Rectangle cellRect = getHeaderRect(index); setCellEditor(null); setEditingColumn(-1); editorComp = null; repaint(cellRect); } } public boolean isEditing() { return (cellEditor == null) ? false : true; } // // CellEditorListener // public void editingStopped(ChangeEvent e) { TableCellEditor editor = getCellEditor(); if (editor != null) { Object value = editor.getCellEditorValue(); int index = getEditingColumn(); columnModel.getColumn(index).setHeaderValue(value); removeEditor(); } } public void editingCanceled(ChangeEvent e) { removeEditor(); } // // public void setReorderingAllowed(boolean b) { // reorderingAllowed = false; // }
} class EditableHeaderUI extends BasicTableHeaderUI {
protected MouseInputListener createMouseInputListener() { return new MouseInputHandler((EditableHeader) header); } public class MouseInputHandler extends BasicTableHeaderUI.MouseInputHandler { private Component dispatchComponent; protected EditableHeader header; public MouseInputHandler(EditableHeader header) { this.header = header; } private void setDispatchComponent(MouseEvent e) { Component editorComponent = header.getEditorComponent(); Point p = e.getPoint(); Point p2 = SwingUtilities.convertPoint(header, p, editorComponent); dispatchComponent = SwingUtilities.getDeepestComponentAt( editorComponent, p2.x, p2.y); } private boolean repostEvent(MouseEvent e) { if (dispatchComponent == null) { return false; } MouseEvent e2 = SwingUtilities.convertMouseEvent(header, e, dispatchComponent); dispatchComponent.dispatchEvent(e2); return true; } public void mousePressed(MouseEvent e) { if (!SwingUtilities.isLeftMouseButton(e)) { return; } super.mousePressed(e); if (header.getResizingColumn() == null) { Point p = e.getPoint(); TableColumnModel columnModel = header.getColumnModel(); int index = columnModel.getColumnIndexAtX(p.x); if (index != -1) { if (header.editCellAt(index, e)) { setDispatchComponent(e); repostEvent(e); } } } } public void mouseReleased(MouseEvent e) { super.mouseReleased(e); if (!SwingUtilities.isLeftMouseButton(e)) { return; } repostEvent(e); dispatchComponent = null; } }
} class EditableHeaderTableColumn extends TableColumn {
protected TableCellEditor headerEditor; protected boolean isHeaderEditable; public EditableHeaderTableColumn() { setHeaderEditor(createDefaultHeaderEditor()); isHeaderEditable = true; } public void setHeaderEditor(TableCellEditor headerEditor) { this.headerEditor = headerEditor; } public TableCellEditor getHeaderEditor() { return headerEditor; } public void setHeaderEditable(boolean isEditable) { isHeaderEditable = isEditable; } public boolean isHeaderEditable() { return isHeaderEditable; } public void copyValues(TableColumn base) { modelIndex = base.getModelIndex(); identifier = base.getIdentifier(); width = base.getWidth(); minWidth = base.getMinWidth(); setPreferredWidth(base.getPreferredWidth()); maxWidth = base.getMaxWidth(); headerRenderer = base.getHeaderRenderer(); headerValue = base.getHeaderValue(); cellRenderer = base.getCellRenderer(); cellEditor = base.getCellEditor(); isResizable = base.getResizable(); } protected TableCellEditor createDefaultHeaderEditor() { return new DefaultCellEditor(new JTextField()); }
}
</source>
Editable Header Table Example 2
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html
import java.awt.ruponent; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.EventObject; import javax.swing.DefaultCellEditor; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.event.CellEditorListener; import javax.swing.event.ChangeEvent; import javax.swing.event.MouseInputListener; import javax.swing.plaf.basic.BasicTableHeaderUI; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; /**
* @version 1.0 08/22/99 */
public class EditableHeaderTableExample2 extends JFrame {
public EditableHeaderTableExample2() { super("EditableHeader Example"); JTable table = new JTable(7, 5); TableColumnModel columnModel = table.getColumnModel(); table.setTableHeader(new EditableHeader(columnModel)); String[] items = { "Dog", "Cat" }; JComboBox combo = new JComboBox(); for (int i = 0; i < items.length; i++) { combo.addItem(items[i]); } ComboRenderer renderer = new ComboRenderer(items); EditableHeaderTableColumn col; // column 1 col = (EditableHeaderTableColumn) table.getColumnModel().getColumn(1); col.setHeaderValue(combo.getItemAt(0)); col.setHeaderRenderer(renderer); col.setHeaderEditor(new DefaultCellEditor(combo)); // column 3 col = (EditableHeaderTableColumn) table.getColumnModel().getColumn(3); col.setHeaderValue(combo.getItemAt(0)); //col.setHeaderRenderer(renderer); col.setHeaderEditor(new DefaultCellEditor(combo)); JScrollPane pane = new JScrollPane(table); getContentPane().add(pane); } class ComboRenderer extends JComboBox implements TableCellRenderer { ComboRenderer(String[] items) { for (int i = 0; i < items.length; i++) { addItem(items[i]); } } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { setSelectedItem(value); return this; } } public static void main(String[] args) { EditableHeaderTableExample2 frame = new EditableHeaderTableExample2(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setSize(300, 100); frame.setVisible(true); }
} class EditableHeader extends JTableHeader implements CellEditorListener {
public final int HEADER_ROW = -10; transient protected int editingColumn; transient protected TableCellEditor cellEditor; transient protected Component editorComp; public EditableHeader(TableColumnModel columnModel) { super(columnModel); setReorderingAllowed(false); cellEditor = null; recreateTableColumn(columnModel); } public void updateUI() { setUI(new EditableHeaderUI()); resizeAndRepaint(); invalidate(); } protected void recreateTableColumn(TableColumnModel columnModel) { int n = columnModel.getColumnCount(); EditableHeaderTableColumn[] newCols = new EditableHeaderTableColumn[n]; TableColumn[] oldCols = new TableColumn[n]; for (int i = 0; i < n; i++) { oldCols[i] = columnModel.getColumn(i); newCols[i] = new EditableHeaderTableColumn(); newCols[i].copyValues(oldCols[i]); } for (int i = 0; i < n; i++) { columnModel.removeColumn(oldCols[i]); } for (int i = 0; i < n; i++) { columnModel.addColumn(newCols[i]); } } public boolean editCellAt(int index) { return editCellAt(index); } public boolean editCellAt(int index, EventObject e) { if (cellEditor != null && !cellEditor.stopCellEditing()) { return false; } if (!isCellEditable(index)) { return false; } TableCellEditor editor = getCellEditor(index); if (editor != null && editor.isCellEditable(e)) { editorComp = prepareEditor(editor, index); editorComp.setBounds(getHeaderRect(index)); add(editorComp); editorComp.validate(); setCellEditor(editor); setEditingColumn(index); editor.addCellEditorListener(this); return true; } return false; } public boolean isCellEditable(int index) { if (getReorderingAllowed()) { return false; } int columnIndex = columnModel.getColumn(index).getModelIndex(); EditableHeaderTableColumn col = (EditableHeaderTableColumn) columnModel .getColumn(columnIndex); return col.isHeaderEditable(); } public TableCellEditor getCellEditor(int index) { int columnIndex = columnModel.getColumn(index).getModelIndex(); EditableHeaderTableColumn col = (EditableHeaderTableColumn) columnModel .getColumn(columnIndex); return col.getHeaderEditor(); } public void setCellEditor(TableCellEditor newEditor) { TableCellEditor oldEditor = cellEditor; cellEditor = newEditor; // firePropertyChange if (oldEditor != null && oldEditor instanceof TableCellEditor) { ((TableCellEditor) oldEditor) .removeCellEditorListener((CellEditorListener) this); } if (newEditor != null && newEditor instanceof TableCellEditor) { ((TableCellEditor) newEditor) .addCellEditorListener((CellEditorListener) this); } } public Component prepareEditor(TableCellEditor editor, int index) { Object value = columnModel.getColumn(index).getHeaderValue(); boolean isSelected = true; int row = HEADER_ROW; JTable table = getTable(); Component comp = editor.getTableCellEditorComponent(table, value, isSelected, row, index); if (comp instanceof JComponent) { ((JComponent) comp).setNextFocusableComponent(this); } return comp; } public TableCellEditor getCellEditor() { return cellEditor; } public Component getEditorComponent() { return editorComp; } public void setEditingColumn(int aColumn) { editingColumn = aColumn; } public int getEditingColumn() { return editingColumn; } public void removeEditor() { TableCellEditor editor = getCellEditor(); if (editor != null) { editor.removeCellEditorListener(this); requestFocus(); remove(editorComp); int index = getEditingColumn(); Rectangle cellRect = getHeaderRect(index); setCellEditor(null); setEditingColumn(-1); editorComp = null; repaint(cellRect); } } public boolean isEditing() { return (cellEditor == null) ? false : true; } // // CellEditorListener // public void editingStopped(ChangeEvent e) { TableCellEditor editor = getCellEditor(); if (editor != null) { Object value = editor.getCellEditorValue(); int index = getEditingColumn(); columnModel.getColumn(index).setHeaderValue(value); removeEditor(); } } public void editingCanceled(ChangeEvent e) { removeEditor(); } // // public void setReorderingAllowed(boolean b) { // reorderingAllowed = false; // }
} class EditableHeaderUI extends BasicTableHeaderUI {
protected MouseInputListener createMouseInputListener() { return new MouseInputHandler((EditableHeader) header); } public class MouseInputHandler extends BasicTableHeaderUI.MouseInputHandler { private Component dispatchComponent; protected EditableHeader header; public MouseInputHandler(EditableHeader header) { this.header = header; } private void setDispatchComponent(MouseEvent e) { Component editorComponent = header.getEditorComponent(); Point p = e.getPoint(); Point p2 = SwingUtilities.convertPoint(header, p, editorComponent); dispatchComponent = SwingUtilities.getDeepestComponentAt( editorComponent, p2.x, p2.y); } private boolean repostEvent(MouseEvent e) { if (dispatchComponent == null) { return false; } MouseEvent e2 = SwingUtilities.convertMouseEvent(header, e, dispatchComponent); dispatchComponent.dispatchEvent(e2); return true; } public void mousePressed(MouseEvent e) { if (!SwingUtilities.isLeftMouseButton(e)) { return; } super.mousePressed(e); if (header.getResizingColumn() == null) { Point p = e.getPoint(); TableColumnModel columnModel = header.getColumnModel(); int index = columnModel.getColumnIndexAtX(p.x); if (index != -1) { if (header.editCellAt(index, e)) { setDispatchComponent(e); repostEvent(e); } } } } public void mouseReleased(MouseEvent e) { super.mouseReleased(e); if (!SwingUtilities.isLeftMouseButton(e)) { return; } repostEvent(e); dispatchComponent = null; } }
} class EditableHeaderTableColumn extends TableColumn {
protected TableCellEditor headerEditor; protected boolean isHeaderEditable; public EditableHeaderTableColumn() { setHeaderEditor(createDefaultHeaderEditor()); isHeaderEditable = true; } public void setHeaderEditor(TableCellEditor headerEditor) { this.headerEditor = headerEditor; } public TableCellEditor getHeaderEditor() { return headerEditor; } public void setHeaderEditable(boolean isEditable) { isHeaderEditable = isEditable; } public boolean isHeaderEditable() { return isHeaderEditable; } public void copyValues(TableColumn base) { modelIndex = base.getModelIndex(); identifier = base.getIdentifier(); width = base.getWidth(); minWidth = base.getMinWidth(); setPreferredWidth(base.getPreferredWidth()); maxWidth = base.getMaxWidth(); headerRenderer = base.getHeaderRenderer(); headerValue = base.getHeaderValue(); cellRenderer = base.getCellRenderer(); cellEditor = base.getCellEditor(); isResizable = base.getResizable(); } protected TableCellEditor createDefaultHeaderEditor() { return new DefaultCellEditor(new JTextField()); }
}
</source>
Editable Highlight Currency Table
<source lang="java">
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall
- /
import java.awt.Color; import java.awt.ruponent; import java.awt.Dimension; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.text.NumberFormat; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; public class EditableHighlightCurrencyTable {
public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception evt) {} JFrame f = new JFrame("Editable Highlighted Currency Table"); JTable tbl = new JTable(new EditableCurrencyTableModel()); tbl.setDefaultRenderer(java.lang.Number.class, new FractionCellRenderer(10, 3, SwingConstants.RIGHT)); TableColumnModel tcm = tbl.getColumnModel(); tcm.getColumn(0).setPreferredWidth(150); tcm.getColumn(0).setMinWidth(150); TextWithIconCellRenderer renderer = new TextWithIconCellRenderer(); tcm.getColumn(0).setCellRenderer(renderer); tbl.setShowHorizontalLines(false); tbl.setIntercellSpacing(new Dimension(1, 0)); // Add the stripe renderer in the leftmost four columns. StripedTableCellRenderer.installInColumn(tbl, 0, Color.lightGray, Color.white, null, null); StripedTableCellRenderer.installInColumn(tbl, 1, Color.lightGray, Color.white, null, null); StripedTableCellRenderer.installInColumn(tbl, 2, Color.lightGray, Color.white, null, null); StripedTableCellRenderer.installInColumn(tbl, 3, Color.lightGray, Color.white, null, null); // Add the highlight renderer to the difference column. // The following comparator makes it highlight // cells with negative numeric values. Comparator cmp = new Comparator() { public boolean shouldHighlight(JTable tbl, Object value, int row, int column) { if (value instanceof Number) { double columnValue = ((Number) value).doubleValue(); return columnValue < (double) 0.0; } return false; } }; tcm.getColumn(3).setCellRenderer( new HighlightRenderer(cmp, null, Color.pink, Color.black, Color.pink.darker(), Color.white)); tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tbl.setPreferredScrollableViewportSize(tbl.getPreferredSize()); JScrollPane sp = new JScrollPane(tbl); f.getContentPane().add(sp, "Center"); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); f.setVisible(true); }
} class EditableCurrencyTableModel extends CurrencyTableModel {
public boolean isCellEditable(int row, int column) { return column == OLD_RATE_COLUMN || column == NEW_RATE_COLUMN; } public void setValueAt(Object value, int row, int column) { try { if (column == OLD_RATE_COLUMN || column == NEW_RATE_COLUMN) { Double newObjectValue; // New value as an Object double newValue; // double, for validity checking if (value instanceof Number) { // Convert Number to Double newValue = ((Number) value).doubleValue(); newObjectValue = new Double(newValue); } else if (value instanceof String) { // Convert a String to a Double newObjectValue = new Double((String) value); newValue = newObjectValue.doubleValue(); } else { // Unrecognized - ignore return; } if (newValue > (double) 0.0) { // Store new value, but reject zero or negative values data[row][column] = newObjectValue; data[row][DIFF_COLUMN] = new Double( ((Double) data[row][NEW_RATE_COLUMN]).doubleValue() - ((Double) data[row][OLD_RATE_COLUMN]) .doubleValue()); fireTableRowsUpdated(row, row); } } } catch (NumberFormatException e) { // Ignore a badly-formatted number } }
} class CurrencyTableModel extends AbstractTableModel {
protected String[] columnNames = { "Currency", "Yesterday", "Today", "Change" }; // Constructor: calculate currency change to create the last column public CurrencyTableModel() { for (int i = 0; i < data.length; i++) { data[i][DIFF_COLUMN] = new Double( ((Double) data[i][NEW_RATE_COLUMN]).doubleValue() - ((Double) data[i][OLD_RATE_COLUMN]).doubleValue()); } } // Implementation of TableModel interface public int getRowCount() { return data.length; } public int getColumnCount() { return COLUMN_COUNT; } public Object getValueAt(int row, int column) { return data[row][column]; } public Class getColumnClass(int column) { return (data[0][column]).getClass(); } public String getColumnName(int column) { return columnNames[column]; } protected static final int OLD_RATE_COLUMN = 1; protected static final int NEW_RATE_COLUMN = 2; protected static final int DIFF_COLUMN = 3; protected static final int COLUMN_COUNT = 4; protected static final Class thisClass = CurrencyTableModel.class; protected Object[][] data = new Object[][] { { new DataWithIcon("Belgian Franc", new ImageIcon(thisClass .getResource("belgium.gif"))), new Double(37.6460110), new Double(37.6508921), null }, { new DataWithIcon("British Pound", new ImageIcon(thisClass .getResource("gb.gif"))), new Double(0.6213051), new Double(0.6104102), null }, { new DataWithIcon("Canadian Dollar", new ImageIcon(thisClass .getResource("canada.gif"))), new Double(1.4651209), new Double(1.5011104), null }, { new DataWithIcon("French Franc", new ImageIcon(thisClass .getResource("france.gif"))), new Double(6.1060001), new Double(6.0100101), null }, { new DataWithIcon("Italian Lire", new ImageIcon(thisClass .getResource("italy.gif"))), new Double(1181.3668977), new Double(1182.104), null }, { new DataWithIcon("German Mark", new ImageIcon(thisClass .getResource("germany.gif"))), new Double(1.8191804), new Double(1.8223421), null }, { new DataWithIcon("Japanese Yen", new ImageIcon(thisClass .getResource("japan.gif"))), new Double(141.0815412), new Double(121.0040432), null } };
} class FractionCellRenderer extends DefaultTableCellRenderer {
public FractionCellRenderer(int integer, int fraction, int align) { this.integer = integer; // maximum integer digits this.fraction = fraction; // exact number of fraction digits this.align = align; // alignment (LEFT, CENTER, RIGHT) } protected void setValue(Object value) { if (value != null && value instanceof Number) { formatter.setMaximumIntegerDigits(integer); formatter.setMaximumFractionDigits(fraction); formatter.setMinimumFractionDigits(fraction); setText(formatter.format(((Number) value).doubleValue())); } else { super.setValue(value); } setHorizontalAlignment(align); } protected int integer; protected int fraction; protected int align; protected static NumberFormat formatter = NumberFormat.getInstance();
} class TextWithIconCellRenderer extends DefaultTableCellRenderer {
protected void setValue(Object value) { if (value instanceof DataWithIcon) { if (value != null) { DataWithIcon d = (DataWithIcon) value; Object dataValue = d.getData(); setText(dataValue == null ? "" : dataValue.toString()); setIcon(d.getIcon()); setHorizontalTextPosition(SwingConstants.RIGHT); setVerticalTextPosition(SwingConstants.CENTER); setHorizontalAlignment(SwingConstants.LEFT); setVerticalAlignment(SwingConstants.CENTER); } else { setText(""); setIcon(null); } } else { super.setValue(value); } }
} class DataWithIcon {
public DataWithIcon(Object data, Icon icon) { this.data = data; this.icon = icon; } public Icon getIcon() { return icon; } public Object getData() { return data; } public String toString() { return data.toString(); } protected Icon icon; protected Object data;
} class StripedTableCellRenderer implements TableCellRenderer {
public StripedTableCellRenderer(TableCellRenderer targetRenderer, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { this.targetRenderer = targetRenderer; this.evenBack = evenBack; this.evenFore = evenFore; this.oddBack = oddBack; this.oddFore = oddFore; } // Implementation of TableCellRenderer interface public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { TableCellRenderer renderer = targetRenderer; if (renderer == null) { // Get default renderer from the table renderer = table.getDefaultRenderer(table.getColumnClass(column)); } // Let the real renderer create the component Component comp = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); // Now apply the stripe effect if (isSelected == false && hasFocus == false) { if ((row & 1) == 0) { comp.setBackground(evenBack != null ? evenBack : table .getBackground()); comp.setForeground(evenFore != null ? evenFore : table .getForeground()); } else { comp.setBackground(oddBack != null ? oddBack : table .getBackground()); comp.setForeground(oddFore != null ? oddFore : table .getForeground()); } } return comp; } // Convenience method to apply this renderer to single column public static void installInColumn(JTable table, int columnIndex, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { TableColumn tc = table.getColumnModel().getColumn(columnIndex); // Get the cell renderer for this column, if any TableCellRenderer targetRenderer = tc.getCellRenderer(); // Create a new StripedTableCellRenderer and install it tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } // Convenience method to apply this renderer to an entire table public static void installInTable(JTable table, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { StripedTableCellRenderer sharedInstance = null; int columns = table.getColumnCount(); for (int i = 0; i < columns; i++) { TableColumn tc = table.getColumnModel().getColumn(i); TableCellRenderer targetRenderer = tc.getCellRenderer(); if (targetRenderer != null) { // This column has a specific renderer tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } else { // This column uses a class renderer - use a shared renderer if (sharedInstance == null) { sharedInstance = new StripedTableCellRenderer(null, evenBack, evenFore, oddBack, oddFore); } tc.setCellRenderer(sharedInstance); } } } protected TableCellRenderer targetRenderer; protected Color evenBack; protected Color evenFore; protected Color oddBack; protected Color oddFore;
} interface Comparator {
public abstract boolean shouldHighlight(JTable tbl, Object value, int row, int column);
} class HighlightRenderer implements TableCellRenderer {
public HighlightRenderer(Comparator cmp, TableCellRenderer targetRenderer, Color backColor, Color foreColor, Color highlightBack, Color highlightFore) { this.cmp = cmp; this.targetRenderer = targetRenderer; this.backColor = backColor; this.foreColor = foreColor; this.highlightBack = highlightBack; this.highlightFore = highlightFore; } public Component getTableCellRendererComponent(JTable tbl, Object value, boolean isSelected, boolean hasFocus, int row, int column) { TableCellRenderer renderer = targetRenderer; if (renderer == null) { renderer = tbl.getDefaultRenderer(tbl.getColumnClass(column)); } Component comp = renderer.getTableCellRendererComponent(tbl, value, isSelected, hasFocus, row, column); if (isSelected == false && hasFocus == false && value != null) { if (cmp.shouldHighlight(tbl, value, row, column)) { comp.setForeground(highlightFore); comp.setBackground(highlightBack); } else { comp.setForeground(foreColor); comp.setBackground(backColor); } } return comp; } protected Comparator cmp; protected TableCellRenderer targetRenderer; protected Color backColor; protected Color foreColor; protected Color highlightBack; protected Color highlightFore;
}
</source>
Fixed Table Column Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1beta3) */ import java.awt.BorderLayout; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JViewport; import javax.swing.UIManager; import javax.swing.ListSelectionModel; import javax.swing.event.ListSelectionEvent; import javax.swing.table.AbstractTableModel; /**
* @version 1.0 12/05/98 */
public class FixedColumnExample extends JFrame {
Object[][] data; Object[] column; JTable fixedTable, table; public FixedColumnExample() { super("Fixed Column Example"); setSize(400, 150); data = new Object[][] { { "1", "11", "A", "", "", "", "", "" }, { "2", "22", "", "B", "", "", "", "" }, { "3", "33", "", "", "C", "", "", "" }, { "4", "44", "", "", "", "D", "", "" }, { "5", "55", "", "", "", "", "E", "" }, { "6", "66", "", "", "", "", "", "F" } }; column = new Object[] { "fixed 1", "fixed 2", "a", "b", "c", "d", "e", "f" }; AbstractTableModel fixedModel = new AbstractTableModel() { public int getColumnCount() { return 2; } public int getRowCount() { return data.length; } public String getColumnName(int col) { return (String) column[col]; } public Object getValueAt(int row, int col) { return data[row][col]; } }; AbstractTableModel model = new AbstractTableModel() { public int getColumnCount() { return column.length - 2; } public int getRowCount() { return data.length; } public String getColumnName(int col) { return (String) column[col + 2]; } public Object getValueAt(int row, int col) { return data[row][col + 2]; } public void setValueAt(Object obj, int row, int col) { data[row][col + 2] = obj; } public boolean CellEditable(int row, int col) { return true; } }; fixedTable = new JTable(fixedModel) { public void valueChanged(ListSelectionEvent e) { super.valueChanged(e); checkSelection(true); } }; table = new JTable(model) { public void valueChanged(ListSelectionEvent e) { super.valueChanged(e); checkSelection(false); } }; fixedTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); fixedTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JScrollPane scroll = new JScrollPane(table); JViewport viewport = new JViewport(); viewport.setView(fixedTable); viewport.setPreferredSize(fixedTable.getPreferredSize()); scroll.setRowHeaderView(viewport); scroll.setCorner(JScrollPane.UPPER_LEFT_CORNER, fixedTable .getTableHeader()); getContentPane().add(scroll, BorderLayout.CENTER); } private void checkSelection(boolean isFixedTable) { int fixedSelectedIndex = fixedTable.getSelectedRow(); int selectedIndex = table.getSelectedRow(); if (fixedSelectedIndex != selectedIndex) { if (isFixedTable) { table.setRowSelectionInterval(fixedSelectedIndex, fixedSelectedIndex); } else { fixedTable .setRowSelectionInterval(selectedIndex, selectedIndex); } } } public static void main(String[] args) { FixedColumnExample frame = new FixedColumnExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); }
}
</source>
Fixed Table Row Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1.1beta1) */ import java.awt.BorderLayout; import java.awt.ruponent; import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.AdjustmentEvent; import java.awt.event.AdjustmentListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JScrollBar; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.UIManager; import javax.swing.table.AbstractTableModel; /**
* @version 1.0 03/05/99 */
public class FixedRowExample extends JFrame {
Object[][] data; Object[] column; JTable fixedTable, table; private int FIXED_NUM = 2; public FixedRowExample() { super("Fixed Row Example"); data = new Object[][] { { "a", "", "", "", "", "" }, { "", "b", "", "", "", "" }, { "", "", "c", "", "", "" }, { "", "", "", "d", "", "" }, { "", "", "", "", "e", "" }, { "", "", "", "", "", "f" }, { "fixed1", "", "", "", "", "", "", "" }, { "fixed2", "", "", "", "", "", "", "" } }; column = new Object[] { "A", "B", "C", "D", "E", "F" }; AbstractTableModel model = new AbstractTableModel() { public int getColumnCount() { return column.length; } public int getRowCount() { return data.length - FIXED_NUM; } public String getColumnName(int col) { return (String) column[col]; } public Object getValueAt(int row, int col) { return data[row][col]; } public void setValueAt(Object obj, int row, int col) { data[row][col] = obj; } public boolean CellEditable(int row, int col) { return true; } }; AbstractTableModel fixedModel = new AbstractTableModel() { public int getColumnCount() { return column.length; } public int getRowCount() { return FIXED_NUM; } public Object getValueAt(int row, int col) { return data[row + (data.length - FIXED_NUM)][col]; } }; table = new JTable(model); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); fixedTable = new JTable(fixedModel); fixedTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); fixedTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JScrollPane scroll = new JScrollPane(table); scroll .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); JScrollPane fixedScroll = new JScrollPane(fixedTable) { public void setColumnHeaderView(Component view) { } // work around }; // // fixedScroll.setColumnHeader(null); fixedScroll .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); JScrollBar bar = fixedScroll.getVerticalScrollBar(); JScrollBar dummyBar = new JScrollBar() { public void paint(Graphics g) { } }; dummyBar.setPreferredSize(bar.getPreferredSize()); fixedScroll.setVerticalScrollBar(dummyBar); final JScrollBar bar1 = scroll.getHorizontalScrollBar(); JScrollBar bar2 = fixedScroll.getHorizontalScrollBar(); bar2.addAdjustmentListener(new AdjustmentListener() { public void adjustmentValueChanged(AdjustmentEvent e) { bar1.setValue(e.getValue()); } }); scroll.setPreferredSize(new Dimension(400, 100)); fixedScroll.setPreferredSize(new Dimension(400, 52)); // Hmm... getContentPane().add(scroll, BorderLayout.CENTER); getContentPane().add(fixedScroll, BorderLayout.SOUTH); } public static void main(String[] args) { FixedRowExample frame = new FixedRowExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.pack(); frame.setVisible(true); }
}
</source>
Fraction Currency Table
<source lang="java">
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall
- /
import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.text.NumberFormat; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableColumnModel; public class FractionCurrencyTable {
public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception evt) {} JFrame f = new JFrame("Fraction Currency Table"); JTable tbl = new JTable(new CurrencyTableModel()); tbl.setDefaultRenderer(java.lang.Number.class, new FractionCellRenderer(10, 3, SwingConstants.RIGHT)); TableColumnModel tcm = tbl.getColumnModel(); tcm.getColumn(0).setPreferredWidth(150); tcm.getColumn(0).setMinWidth(150); tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tbl.setPreferredScrollableViewportSize(tbl.getPreferredSize()); JScrollPane sp = new JScrollPane(tbl); f.getContentPane().add(sp, "Center"); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); f.setVisible(true); }
} class DataWithIcon {
public DataWithIcon(Object data, Icon icon) { this.data = data; this.icon = icon; } public Icon getIcon() { return icon; } public Object getData() { return data; } public String toString() { return data.toString(); } protected Icon icon; protected Object data;
} class CurrencyTableModel extends AbstractTableModel {
protected String[] columnNames = { "Currency", "Yesterday", "Today", "Change" }; // Constructor: calculate currency change to create the last column public CurrencyTableModel() { for (int i = 0; i < data.length; i++) { data[i][DIFF_COLUMN] = new Double( ((Double) data[i][NEW_RATE_COLUMN]).doubleValue() - ((Double) data[i][OLD_RATE_COLUMN]).doubleValue()); } } // Implementation of TableModel interface public int getRowCount() { return data.length; } public int getColumnCount() { return COLUMN_COUNT; } public Object getValueAt(int row, int column) { return data[row][column]; } public Class getColumnClass(int column) { return (data[0][column]).getClass(); } public String getColumnName(int column) { return columnNames[column]; } protected static final int OLD_RATE_COLUMN = 1; protected static final int NEW_RATE_COLUMN = 2; protected static final int DIFF_COLUMN = 3; protected static final int COLUMN_COUNT = 4; protected static final Class thisClass = CurrencyTableModel.class; protected Object[][] data = new Object[][] { { new DataWithIcon("Belgian Franc", new ImageIcon(thisClass .getResource("belgium.gif"))), new Double(37.6460110), new Double(37.6508921), null }, { new DataWithIcon("British Pound", new ImageIcon(thisClass .getResource("gb.gif"))), new Double(0.6213051), new Double(0.6104102), null }, { new DataWithIcon("Canadian Dollar", new ImageIcon(thisClass .getResource("canada.gif"))), new Double(1.4651209), new Double(1.5011104), null }, { new DataWithIcon("French Franc", new ImageIcon(thisClass .getResource("france.gif"))), new Double(6.1060001), new Double(6.0100101), null }, { new DataWithIcon("Italian Lire", new ImageIcon(thisClass .getResource("italy.gif"))), new Double(1181.3668977), new Double(1182.104), null }, { new DataWithIcon("German Mark", new ImageIcon(thisClass .getResource("germany.gif"))), new Double(1.8191804), new Double(1.8223421), null }, { new DataWithIcon("Japanese Yen", new ImageIcon(thisClass .getResource("japan.gif"))), new Double(141.0815412), new Double(121.0040432), null } };
} class FractionCellRenderer extends DefaultTableCellRenderer {
public FractionCellRenderer(int integer, int fraction, int align) { this.integer = integer; // maximum integer digits this.fraction = fraction; // exact number of fraction digits this.align = align; // alignment (LEFT, CENTER, RIGHT) } protected void setValue(Object value) { if (value != null && value instanceof Number) { formatter.setMaximumIntegerDigits(integer); formatter.setMaximumFractionDigits(fraction); formatter.setMinimumFractionDigits(fraction); setText(formatter.format(((Number) value).doubleValue())); } else { super.setValue(value); } setHorizontalAlignment(align); } protected int integer; protected int fraction; protected int align; protected static NumberFormat formatter = NumberFormat.getInstance();
}
</source>
Groupable(Group) Header Example
<source lang="java">
/* (swing1.1beta3)
*example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html * */
/* (swing1.1beta3)
* * |-----------------------------------------------------| * | | Name | Language | * | |-----------------|--------------------------| * | SNo. | | | | Others | * | | 1 | 2 | Native |-----------------| * | | | | | 2 | 3 | * |-----------------------------------------------------| * | | | | | | | * */
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.*;
/**
* @version 1.0 11/09/98 */
public class GroupableHeaderExample extends JFrame {
GroupableHeaderExample() { super( "Groupable Header Example" ); DefaultTableModel dm = new DefaultTableModel(); dm.setDataVector(new Object[][]{ {"119","foo","bar","ja","ko","zh"}, {"911","bar","foo","en","fr","pt"}}, new Object[]{"SNo.","1","2","Native","2","3"}); JTable table = new JTable( dm ) { protected JTableHeader createDefaultTableHeader() { return new GroupableTableHeader(columnModel); } }; TableColumnModel cm = table.getColumnModel(); ColumnGroup g_name = new ColumnGroup("Name"); g_name.add(cm.getColumn(1)); g_name.add(cm.getColumn(2)); ColumnGroup g_lang = new ColumnGroup("Language"); g_lang.add(cm.getColumn(3)); ColumnGroup g_other = new ColumnGroup("Others"); g_other.add(cm.getColumn(4)); g_other.add(cm.getColumn(5)); g_lang.add(g_other); GroupableTableHeader header = (GroupableTableHeader)table.getTableHeader(); header.addColumnGroup(g_name); header.addColumnGroup(g_lang); JScrollPane scroll = new JScrollPane( table ); getContentPane().add( scroll ); setSize( 400, 120 ); } public static void main(String[] args) { GroupableHeaderExample frame = new GroupableHeaderExample(); frame.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit(0); } }); frame.setVisible(true); }
} /*
* (swing1.1beta3) * */
import java.util.*; import java.awt.*; import javax.swing.*; import javax.swing.table.*;
/**
* GroupableTableHeader * * @version 1.0 10/20/98 * @author Nobuo Tamemasa */
public class GroupableTableHeader extends JTableHeader {
private static final String uiClassID = "GroupableTableHeaderUI"; protected Vector columnGroups = null; public GroupableTableHeader(TableColumnModel model) { super(model); setUI(new GroupableTableHeaderUI()); setReorderingAllowed(false); } public void updateUI(){ setUI(new GroupableTableHeaderUI()); } public void setReorderingAllowed(boolean b) { reorderingAllowed = false; } public void addColumnGroup(ColumnGroup g) { if (columnGroups == null) { columnGroups = new Vector(); } columnGroups.addElement(g); } public Enumeration getColumnGroups(TableColumn col) { if (columnGroups == null) return null; Enumeration e = columnGroups.elements(); while (e.hasMoreElements()) { ColumnGroup cGroup = (ColumnGroup)e.nextElement(); Vector v_ret = (Vector)cGroup.getColumnGroups(col,new Vector()); if (v_ret != null) { return v_ret.elements(); } } return null; } public void setColumnMargin() { if (columnGroups == null) return; int columnMargin = getColumnModel().getColumnMargin(); Enumeration e = columnGroups.elements(); while (e.hasMoreElements()) { ColumnGroup cGroup = (ColumnGroup)e.nextElement(); cGroup.setColumnMargin(columnMargin); } }
} /*
* (swing1.1beta3) * */
import java.util.*; import java.awt.*; import javax.swing.*; import javax.swing.border.*; import javax.swing.table.*; import javax.swing.plaf.basic.*;
public class GroupableTableHeaderUI extends BasicTableHeaderUI {
public void paint(Graphics g, JComponent c) { Rectangle clipBounds = g.getClipBounds(); if (header.getColumnModel() == null) return; ((GroupableTableHeader)header).setColumnMargin(); int column = 0; Dimension size = header.getSize(); Rectangle cellRect = new Rectangle(0, 0, size.width, size.height); Hashtable h = new Hashtable(); int columnMargin = header.getColumnModel().getColumnMargin(); Enumeration enumeration = header.getColumnModel().getColumns(); while (enumeration.hasMoreElements()) { cellRect.height = size.height; cellRect.y = 0; TableColumn aColumn = (TableColumn)enumeration.nextElement(); Enumeration cGroups = ((GroupableTableHeader)header).getColumnGroups(aColumn); if (cGroups != null) { int groupHeight = 0; while (cGroups.hasMoreElements()) { ColumnGroup cGroup = (ColumnGroup)cGroups.nextElement(); Rectangle groupRect = (Rectangle)h.get(cGroup); if (groupRect == null) { groupRect = new Rectangle(cellRect); Dimension d = cGroup.getSize(header.getTable()); groupRect.width = d.width; groupRect.height = d.height; h.put(cGroup, groupRect); } paintCell(g, groupRect, cGroup); groupHeight += groupRect.height; cellRect.height = size.height - groupHeight; cellRect.y = groupHeight; } } cellRect.width = aColumn.getWidth() + columnMargin; if (cellRect.intersects(clipBounds)) { paintCell(g, cellRect, column); } cellRect.x += cellRect.width; column++; } } private void paintCell(Graphics g, Rectangle cellRect, int columnIndex) { TableColumn aColumn = header.getColumnModel().getColumn(columnIndex); TableCellRenderer renderer = aColumn.getHeaderRenderer(); //revised by jexp.ru renderer = new DefaultTableCellRenderer(){ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JLabel header = new JLabel(); header.setForeground(table.getTableHeader().getForeground()); header.setBackground(table.getTableHeader().getBackground()); header.setFont(table.getTableHeader().getFont()); header.setHorizontalAlignment(JLabel.CENTER); header.setText(value.toString()); header.setBorder(UIManager.getBorder("TableHeader.cellBorder")); return header; } }; Component c = renderer.getTableCellRendererComponent( header.getTable(), aColumn.getHeaderValue(),false, false, -1, columnIndex); c.setBackground(UIManager.getColor("control")); rendererPane.add(c); rendererPane.paintComponent(g, c, header, cellRect.x, cellRect.y, cellRect.width, cellRect.height, true); } private void paintCell(Graphics g, Rectangle cellRect,ColumnGroup cGroup) { TableCellRenderer renderer = cGroup.getHeaderRenderer(); //revised by jexp.ru // if(renderer == null){
// return ;
// } Component component = renderer.getTableCellRendererComponent( header.getTable(), cGroup.getHeaderValue(),false, false, -1, -1); rendererPane.add(component); rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y, cellRect.width, cellRect.height, true); } private int getHeaderHeight() { int height = 0; TableColumnModel columnModel = header.getColumnModel(); for(int column = 0; column < columnModel.getColumnCount(); column++) { TableColumn aColumn = columnModel.getColumn(column); TableCellRenderer renderer = aColumn.getHeaderRenderer(); //revised by jexp.ru if(renderer == null){ return 60; } Component comp = renderer.getTableCellRendererComponent( header.getTable(), aColumn.getHeaderValue(), false, false,-1, column); int cHeight = comp.getPreferredSize().height; Enumeration e = ((GroupableTableHeader)header).getColumnGroups(aColumn); if (e != null) { while (e.hasMoreElements()) { ColumnGroup cGroup = (ColumnGroup)e.nextElement(); cHeight += cGroup.getSize(header.getTable()).height; } } height = Math.max(height, cHeight); } return height; } private Dimension createHeaderSize(long width) { TableColumnModel columnModel = header.getColumnModel(); width += columnModel.getColumnMargin() * columnModel.getColumnCount(); if (width > Integer.MAX_VALUE) { width = Integer.MAX_VALUE; } return new Dimension((int)width, getHeaderHeight()); } public Dimension getPreferredSize(JComponent c) { long width = 0; Enumeration enumeration = header.getColumnModel().getColumns(); while (enumeration.hasMoreElements()) { TableColumn aColumn = (TableColumn)enumeration.nextElement(); width = width + aColumn.getPreferredWidth(); } return createHeaderSize(width); }
} /*
* (swing1.1beta3) * */
import java.util.*; import java.awt.*; import javax.swing.*; import javax.swing.table.*;
/**
* ColumnGroup * * @version 1.0 10/20/98 * @author Nobuo Tamemasa */
class ColumnGroup {
protected TableCellRenderer renderer; protected Vector v; protected String text; protected int margin=0; public ColumnGroup(String text) { this(null,text); } public ColumnGroup(TableCellRenderer renderer,String text) { if (renderer == null) { this.renderer = new DefaultTableCellRenderer() { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JTableHeader header = table.getTableHeader(); if (header != null) { setForeground(header.getForeground()); setBackground(header.getBackground()); setFont(header.getFont()); } setHorizontalAlignment(JLabel.CENTER); setText((value == null) ? "" : value.toString()); setBorder(UIManager.getBorder("TableHeader.cellBorder")); return this; } }; } else { this.renderer = renderer; } this.text = text; v = new Vector(); } /** * @param obj TableColumn or ColumnGroup */ public void add(Object obj) { if (obj == null) { return; } v.addElement(obj); } /** * @param c TableColumn * @param v ColumnGroups */ public Vector getColumnGroups(TableColumn c, Vector g) { g.addElement(this); if (v.contains(c)) return g; Enumeration e = v.elements(); while (e.hasMoreElements()) { Object obj = e.nextElement(); if (obj instanceof ColumnGroup) { Vector groups = (Vector)((ColumnGroup)obj).getColumnGroups(c,(Vector)g.clone()); if (groups != null) return groups; } } return null; } public TableCellRenderer getHeaderRenderer() { return renderer; } public void setHeaderRenderer(TableCellRenderer renderer) { if (renderer != null) { this.renderer = renderer; } } public Object getHeaderValue() { return text; } public Dimension getSize(JTable table) { Component comp = renderer.getTableCellRendererComponent( table, getHeaderValue(), false, false,-1, -1); int height = comp.getPreferredSize().height; int width = 0; Enumeration e = v.elements(); while (e.hasMoreElements()) { Object obj = e.nextElement(); if (obj instanceof TableColumn) { TableColumn aColumn = (TableColumn)obj; width += aColumn.getWidth(); width += margin; } else { width += ((ColumnGroup)obj).getSize(table).width; } } return new Dimension(width, height); } public void setColumnMargin(int margin) { this.margin = margin; Enumeration e = v.elements(); while (e.hasMoreElements()) { Object obj = e.nextElement(); if (obj instanceof ColumnGroup) { ((ColumnGroup)obj).setColumnMargin(margin); } } }
}
</source>
Hide Column Table Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1.1beta2) */ import java.awt.Color; import java.awt.ruponent; import java.awt.Container; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.Insets; import java.awt.Rectangle; import java.awt.SystemColor; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Stack; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.ScrollPaneLayout; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.border.AbstractBorder; import javax.swing.plaf.basic.BasicArrowButton; import javax.swing.table.JTableHeader; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; /**
* @version 1.0 05/31/99 */
public class HideColumnTableExample extends JFrame {
public HideColumnTableExample() { super("HideColumnTable Example"); JTable table = new JTable(5, 7); ColumnButtonScrollPane pane = new ColumnButtonScrollPane(table); getContentPane().add(pane); } public static void main(String[] args) { HideColumnTableExample frame = new HideColumnTableExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setSize(400, 100); frame.setVisible(true); }
} class ColumnButtonScrollPane extends JScrollPane {
Component columnButton; public ColumnButtonScrollPane(JTable table) { super(table); TableColumnModel cm = table.getColumnModel(); LimitedTableHeader header = new LimitedTableHeader(cm); table.setTableHeader(header); columnButton = createUpperCorner(header); setCorner(UPPER_RIGHT_CORNER, columnButton); setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_ALWAYS); ColumnButtonScrollPaneLayout layout = new ColumnButtonScrollPaneLayout(); setLayout(layout); layout.syncWithScrollPane(this); } protected Component createUpperCorner(JTableHeader header) { ColumnButton corner = new ColumnButton(header); return corner; } public class LimitedTableHeader extends JTableHeader { public LimitedTableHeader(TableColumnModel cm) { super(cm); } // actually, this is a not complete way. but easy one. // you can see last column painted wider, short time :) // If you don"t like this kind cheap fake, // you have to overwrite the paint method in UI class. public void paintComponent(Graphics g) { super.paintComponent(g); columnButton.repaint(); } } public class ColumnButton extends JPanel { JTable table; TableColumnModel cm; JButton revealButton; JButton hideButton; Stack stack; public ColumnButton(JTableHeader header) { setLayout(new GridLayout(1, 2)); setBorder(new LinesBorder(SystemColor.controlShadow, new Insets(0, 1, 0, 0))); stack = new Stack(); table = header.getTable(); cm = table.getColumnModel(); revealButton = createButton(header, SwingConstants.WEST); hideButton = createButton(header, SwingConstants.EAST); add(revealButton); add(hideButton); revealButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { TableColumn column = (TableColumn) stack.pop(); cm.addColumn(column); if (stack.empty()) { revealButton.setEnabled(false); } hideButton.setEnabled(true); table.sizeColumnsToFit(-1); } }); hideButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int n = cm.getColumnCount(); TableColumn column = cm.getColumn(n - 1); stack.push(column); cm.removeColumn(column); if (n < 3) { hideButton.setEnabled(false); } revealButton.setEnabled(true); table.sizeColumnsToFit(-1); } }); if (1 < cm.getColumnCount()) { hideButton.setEnabled(true); } else { hideButton.setEnabled(false); } revealButton.setEnabled(false); } protected JButton createButton(JTableHeader header, int direction) { //int iconHeight = header.getPreferredSize().height - 6; int iconHeight = 8; JButton button = new JButton(); button.setIcon(new ArrowIcon(iconHeight, direction, true)); button.setDisabledIcon(new ArrowIcon(iconHeight, direction, false)); button.setRequestFocusEnabled(false); button.setForeground(header.getForeground()); button.setBackground(header.getBackground()); button.setBorder(UIManager.getBorder("TableHeader.cellBorder")); return button; } }
} class ColumnButtonScrollPaneLayout extends ScrollPaneLayout {
public ColumnButtonScrollPaneLayout() { super.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_ALWAYS); } public void setVerticalScrollBarPolicy(int x) { // VERTICAL_SCROLLBAR_ALWAYS super.setVerticalScrollBarPolicy(VERTICAL_SCROLLBAR_ALWAYS); } public void layoutContainer(Container parent) { super.layoutContainer(parent); if ((colHead == null) || (!colHead.isVisible()) || (upperRight == null) || (vsb == null)) { return; } Rectangle vsbR = new Rectangle(0, 0, 0, 0); vsbR = vsb.getBounds(vsbR); Rectangle colHeadR = new Rectangle(0, 0, 0, 0); colHeadR = colHead.getBounds(colHeadR); colHeadR.width -= vsbR.width; colHead.getBounds(colHeadR); Rectangle upperRightR = upperRight.getBounds(); upperRightR.x -= vsbR.width; upperRightR.width += vsbR.width + 1; upperRight.setBounds(upperRightR); }
} class LinesBorder extends AbstractBorder implements SwingConstants {
protected int northThickness; protected int southThickness; protected int eastThickness; protected int westThickness; protected Color northColor; protected Color southColor; protected Color eastColor; protected Color westColor; public LinesBorder(Color color) { this(color, 1); } public LinesBorder(Color color, int thickness) { setColor(color); setThickness(thickness); } public LinesBorder(Color color, Insets insets) { setColor(color); setThickness(insets); } public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { Color oldColor = g.getColor(); g.setColor(northColor); for (int i = 0; i < northThickness; i++) { g.drawLine(x, y + i, x + width - 1, y + i); } g.setColor(southColor); for (int i = 0; i < southThickness; i++) { g .drawLine(x, y + height - i - 1, x + width - 1, y + height - i - 1); } g.setColor(eastColor); for (int i = 0; i < westThickness; i++) { g.drawLine(x + i, y, x + i, y + height - 1); } g.setColor(westColor); for (int i = 0; i < eastThickness; i++) { g.drawLine(x + width - i - 1, y, x + width - i - 1, y + height - 1); } g.setColor(oldColor); } public Insets getBorderInsets(Component c) { return new Insets(northThickness, westThickness, southThickness, eastThickness); } public Insets getBorderInsets(Component c, Insets insets) { return new Insets(northThickness, westThickness, southThickness, eastThickness); } public boolean isBorderOpaque() { return true; } public void setColor(Color c) { northColor = c; southColor = c; eastColor = c; westColor = c; } public void setColor(Color c, int direction) { switch (direction) { case NORTH: northColor = c; break; case SOUTH: southColor = c; break; case EAST: eastColor = c; break; case WEST: westColor = c; break; default: } } public void setThickness(int n) { northThickness = n; southThickness = n; eastThickness = n; westThickness = n; } public void setThickness(Insets insets) { northThickness = insets.top; southThickness = insets.bottom; eastThickness = insets.right; westThickness = insets.left; } public void setThickness(int n, int direction) { switch (direction) { case NORTH: northThickness = n; break; case SOUTH: southThickness = n; break; case EAST: eastThickness = n; break; case WEST: westThickness = n; break; default: } } public void append(LinesBorder b, boolean isReplace) { if (isReplace) { northThickness = b.northThickness; southThickness = b.southThickness; eastThickness = b.eastThickness; westThickness = b.westThickness; } else { northThickness = Math.max(northThickness, b.northThickness); southThickness = Math.max(southThickness, b.southThickness); eastThickness = Math.max(eastThickness, b.eastThickness); westThickness = Math.max(westThickness, b.westThickness); } } public void append(Insets insets, boolean isReplace) { if (isReplace) { northThickness = insets.top; southThickness = insets.bottom; eastThickness = insets.right; westThickness = insets.left; } else { northThickness = Math.max(northThickness, insets.top); southThickness = Math.max(southThickness, insets.bottom); eastThickness = Math.max(eastThickness, insets.right); westThickness = Math.max(westThickness, insets.left); } }
} class ArrowIcon implements Icon, SwingConstants {
private static final int DEFAULT_SIZE = 11; //private static final int DEFAULT_SIZE = 5; private int size; private int iconSize; private int direction; private boolean isEnabled; private BasicArrowButton iconRenderer; public ArrowIcon(int direction, boolean isPressedView) { this(DEFAULT_SIZE, direction, isPressedView); } public ArrowIcon(int iconSize, int direction, boolean isEnabled) { this.size = iconSize / 2; this.iconSize = iconSize; this.direction = direction; this.isEnabled = isEnabled; iconRenderer = new BasicArrowButton(direction); } public void paintIcon(Component c, Graphics g, int x, int y) { iconRenderer.paintTriangle(g, x, y, size, direction, isEnabled); } public int getIconWidth() { //int retCode; switch (direction) { case NORTH: case SOUTH: return iconSize; case EAST: case WEST: return size; } return iconSize; } public int getIconHeight() { switch (direction) { case NORTH: case SOUTH: return size; case EAST: case WEST: return iconSize; } return size; }
}
</source>
Highlight Currency Table
<source lang="java">
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall
- /
import java.awt.Color; import java.awt.ruponent; import java.awt.Dimension; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.text.NumberFormat; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; public class HighlightCurrencyTable {
public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception evt) {} JFrame f = new JFrame("Highlighted Currency Table"); JTable tbl = new JTable(new CurrencyTableModel()); tbl.setDefaultRenderer(java.lang.Number.class, new FractionCellRenderer(10, 3, SwingConstants.RIGHT)); TableColumnModel tcm = tbl.getColumnModel(); tcm.getColumn(0).setPreferredWidth(150); tcm.getColumn(0).setMinWidth(150); TextWithIconCellRenderer renderer = new TextWithIconCellRenderer(); tcm.getColumn(0).setCellRenderer(renderer); tbl.setShowHorizontalLines(false); tbl.setIntercellSpacing(new Dimension(1, 0)); // Add the stipe renderer. StripedTableCellRenderer.installInTable(tbl, Color.lightGray, Color.white, null, null); // Add the highlight renderer to the last column. // The following comparator makes it highlight // cells with negative numeric values. Comparator cmp = new Comparator() { public boolean shouldHighlight(JTable tbl, Object value, int row, int column) { if (value instanceof Number) { double columnValue = ((Number) value).doubleValue(); return columnValue < (double) 0.0; } return false; } }; tcm.getColumn(3).setCellRenderer( new HighlightRenderer(cmp, null, Color.pink, Color.black, Color.pink.darker(), Color.white)); tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tbl.setPreferredScrollableViewportSize(tbl.getPreferredSize()); JScrollPane sp = new JScrollPane(tbl); f.getContentPane().add(sp, "Center"); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); f.setVisible(true); }
} class DataWithIcon {
public DataWithIcon(Object data, Icon icon) { this.data = data; this.icon = icon; } public Icon getIcon() { return icon; } public Object getData() { return data; } public String toString() { return data.toString(); } protected Icon icon; protected Object data;
} class CurrencyTableModel extends AbstractTableModel {
protected String[] columnNames = { "Currency", "Yesterday", "Today", "Change" }; // Constructor: calculate currency change to create the last column public CurrencyTableModel() { for (int i = 0; i < data.length; i++) { data[i][DIFF_COLUMN] = new Double( ((Double) data[i][NEW_RATE_COLUMN]).doubleValue() - ((Double) data[i][OLD_RATE_COLUMN]).doubleValue()); } } // Implementation of TableModel interface public int getRowCount() { return data.length; } public int getColumnCount() { return COLUMN_COUNT; } public Object getValueAt(int row, int column) { return data[row][column]; } public Class getColumnClass(int column) { return (data[0][column]).getClass(); } public String getColumnName(int column) { return columnNames[column]; } protected static final int OLD_RATE_COLUMN = 1; protected static final int NEW_RATE_COLUMN = 2; protected static final int DIFF_COLUMN = 3; protected static final int COLUMN_COUNT = 4; protected static final Class thisClass = CurrencyTableModel.class; protected Object[][] data = new Object[][] { { new DataWithIcon("Belgian Franc", new ImageIcon(thisClass .getResource("belgium.gif"))), new Double(37.6460110), new Double(37.6508921), null }, { new DataWithIcon("British Pound", new ImageIcon(thisClass .getResource("gb.gif"))), new Double(0.6213051), new Double(0.6104102), null }, { new DataWithIcon("Canadian Dollar", new ImageIcon(thisClass .getResource("canada.gif"))), new Double(1.4651209), new Double(1.5011104), null }, { new DataWithIcon("French Franc", new ImageIcon(thisClass .getResource("france.gif"))), new Double(6.1060001), new Double(6.0100101), null }, { new DataWithIcon("Italian Lire", new ImageIcon(thisClass .getResource("italy.gif"))), new Double(1181.3668977), new Double(1182.104), null }, { new DataWithIcon("German Mark", new ImageIcon(thisClass .getResource("germany.gif"))), new Double(1.8191804), new Double(1.8223421), null }, { new DataWithIcon("Japanese Yen", new ImageIcon(thisClass .getResource("japan.gif"))), new Double(141.0815412), new Double(121.0040432), null } };
} class FractionCellRenderer extends DefaultTableCellRenderer {
public FractionCellRenderer(int integer, int fraction, int align) { this.integer = integer; // maximum integer digits this.fraction = fraction; // exact number of fraction digits this.align = align; // alignment (LEFT, CENTER, RIGHT) } protected void setValue(Object value) { if (value != null && value instanceof Number) { formatter.setMaximumIntegerDigits(integer); formatter.setMaximumFractionDigits(fraction); formatter.setMinimumFractionDigits(fraction); setText(formatter.format(((Number) value).doubleValue())); } else { super.setValue(value); } setHorizontalAlignment(align); } protected int integer; protected int fraction; protected int align; protected static NumberFormat formatter = NumberFormat.getInstance();
} class StripedTableCellRenderer implements TableCellRenderer {
public StripedTableCellRenderer(TableCellRenderer targetRenderer, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { this.targetRenderer = targetRenderer; this.evenBack = evenBack; this.evenFore = evenFore; this.oddBack = oddBack; this.oddFore = oddFore; } // Implementation of TableCellRenderer interface public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { TableCellRenderer renderer = targetRenderer; if (renderer == null) { // Get default renderer from the table renderer = table.getDefaultRenderer(table.getColumnClass(column)); } // Let the real renderer create the component Component comp = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); // Now apply the stripe effect if (isSelected == false && hasFocus == false) { if ((row & 1) == 0) { comp.setBackground(evenBack != null ? evenBack : table .getBackground()); comp.setForeground(evenFore != null ? evenFore : table .getForeground()); } else { comp.setBackground(oddBack != null ? oddBack : table .getBackground()); comp.setForeground(oddFore != null ? oddFore : table .getForeground()); } } return comp; } // Convenience method to apply this renderer to single column public static void installInColumn(JTable table, int columnIndex, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { TableColumn tc = table.getColumnModel().getColumn(columnIndex); // Get the cell renderer for this column, if any TableCellRenderer targetRenderer = tc.getCellRenderer(); // Create a new StripedTableCellRenderer and install it tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } // Convenience method to apply this renderer to an entire table public static void installInTable(JTable table, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { StripedTableCellRenderer sharedInstance = null; int columns = table.getColumnCount(); for (int i = 0; i < columns; i++) { TableColumn tc = table.getColumnModel().getColumn(i); TableCellRenderer targetRenderer = tc.getCellRenderer(); if (targetRenderer != null) { // This column has a specific renderer tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } else { // This column uses a class renderer - use a shared renderer if (sharedInstance == null) { sharedInstance = new StripedTableCellRenderer(null, evenBack, evenFore, oddBack, oddFore); } tc.setCellRenderer(sharedInstance); } } } protected TableCellRenderer targetRenderer; protected Color evenBack; protected Color evenFore; protected Color oddBack; protected Color oddFore;
} class TextWithIconCellRenderer extends DefaultTableCellRenderer {
protected void setValue(Object value) { if (value instanceof DataWithIcon) { if (value != null) { DataWithIcon d = (DataWithIcon) value; Object dataValue = d.getData(); setText(dataValue == null ? "" : dataValue.toString()); setIcon(d.getIcon()); setHorizontalTextPosition(SwingConstants.RIGHT); setVerticalTextPosition(SwingConstants.CENTER); setHorizontalAlignment(SwingConstants.LEFT); setVerticalAlignment(SwingConstants.CENTER); } else { setText(""); setIcon(null); } } else { super.setValue(value); } }
} class HighlightRenderer implements TableCellRenderer {
public HighlightRenderer(Comparator cmp, TableCellRenderer targetRenderer, Color backColor, Color foreColor, Color highlightBack, Color highlightFore) { this.cmp = cmp; this.targetRenderer = targetRenderer; this.backColor = backColor; this.foreColor = foreColor; this.highlightBack = highlightBack; this.highlightFore = highlightFore; } public Component getTableCellRendererComponent(JTable tbl, Object value, boolean isSelected, boolean hasFocus, int row, int column) { TableCellRenderer renderer = targetRenderer; if (renderer == null) { renderer = tbl.getDefaultRenderer(tbl.getColumnClass(column)); } Component comp = renderer.getTableCellRendererComponent(tbl, value, isSelected, hasFocus, row, column); if (isSelected == false && hasFocus == false && value != null) { if (cmp.shouldHighlight(tbl, value, row, column)) { comp.setForeground(highlightFore); comp.setBackground(highlightBack); } else { comp.setForeground(foreColor); comp.setBackground(backColor); } } return comp; } protected Comparator cmp; protected TableCellRenderer targetRenderer; protected Color backColor; protected Color foreColor; protected Color highlightBack; protected Color highlightFore;
} interface Comparator {
public abstract boolean shouldHighlight(JTable tbl, Object value, int row, int column);
}
</source>
Highlight Currency Table 2
<source lang="java">
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall
- /
import java.awt.Color; import java.awt.ruponent; import java.awt.Dimension; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.text.NumberFormat; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; public class HighlightCurrencyTable2 {
public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception evt) {} JFrame f = new JFrame("Highlighted Currency Table 2"); JTable tbl = new JTable(new CurrencyTableModel()); tbl.setDefaultRenderer(java.lang.Number.class, new FractionCellRenderer(10, 3, SwingConstants.RIGHT)); TableColumnModel tcm = tbl.getColumnModel(); tcm.getColumn(0).setPreferredWidth(150); tcm.getColumn(0).setMinWidth(150); TextWithIconCellRenderer renderer = new TextWithIconCellRenderer(); tcm.getColumn(0).setCellRenderer(renderer); tbl.setShowHorizontalLines(false); tbl.setIntercellSpacing(new Dimension(1, 0)); // Add the stripe renderer. StripedTableCellRenderer.installInTable(tbl, Color.lightGray, Color.white, null, null); // Add the highlight renderer to the last column. Comparator cmp = new Comparator() { public boolean shouldHighlight(JTable tbl, Object value, int row, int column) { if (value instanceof Number) { Object oldValueObj = tbl.getModel().getValueAt(row, 1); if (oldValueObj instanceof Number) { double oldValue = ((Number) oldValueObj).doubleValue(); double columnValue = ((Number) value).doubleValue(); return Math.abs(columnValue) > Math.abs(oldValue / (double) 10.0); } } return false; } }; tcm.getColumn(3).setCellRenderer( new HighlightRenderer(cmp, null, Color.pink, Color.black, Color.pink.darker(), Color.white)); tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tbl.setPreferredScrollableViewportSize(tbl.getPreferredSize()); JScrollPane sp = new JScrollPane(tbl); f.getContentPane().add(sp, "Center"); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); f.setVisible(true); }
} interface Comparator {
public abstract boolean shouldHighlight(JTable tbl, Object value, int row, int column);
} class DataWithIcon {
public DataWithIcon(Object data, Icon icon) { this.data = data; this.icon = icon; } public Icon getIcon() { return icon; } public Object getData() { return data; } public String toString() { return data.toString(); } protected Icon icon; protected Object data;
} class CurrencyTableModel extends AbstractTableModel {
protected String[] columnNames = { "Currency", "Yesterday", "Today", "Change" }; // Constructor: calculate currency change to create the last column public CurrencyTableModel() { for (int i = 0; i < data.length; i++) { data[i][DIFF_COLUMN] = new Double( ((Double) data[i][NEW_RATE_COLUMN]).doubleValue() - ((Double) data[i][OLD_RATE_COLUMN]).doubleValue()); } } // Implementation of TableModel interface public int getRowCount() { return data.length; } public int getColumnCount() { return COLUMN_COUNT; } public Object getValueAt(int row, int column) { return data[row][column]; } public Class getColumnClass(int column) { return (data[0][column]).getClass(); } public String getColumnName(int column) { return columnNames[column]; } protected static final int OLD_RATE_COLUMN = 1; protected static final int NEW_RATE_COLUMN = 2; protected static final int DIFF_COLUMN = 3; protected static final int COLUMN_COUNT = 4; protected static final Class thisClass = CurrencyTableModel.class; protected Object[][] data = new Object[][] { { new DataWithIcon("Belgian Franc", new ImageIcon(thisClass .getResource("belgium.gif"))), new Double(37.6460110), new Double(37.6508921), null }, { new DataWithIcon("British Pound", new ImageIcon(thisClass .getResource("gb.gif"))), new Double(0.6213051), new Double(0.6104102), null }, { new DataWithIcon("Canadian Dollar", new ImageIcon(thisClass .getResource("canada.gif"))), new Double(1.4651209), new Double(1.5011104), null }, { new DataWithIcon("French Franc", new ImageIcon(thisClass .getResource("france.gif"))), new Double(6.1060001), new Double(6.0100101), null }, { new DataWithIcon("Italian Lire", new ImageIcon(thisClass .getResource("italy.gif"))), new Double(1181.3668977), new Double(1182.104), null }, { new DataWithIcon("German Mark", new ImageIcon(thisClass .getResource("germany.gif"))), new Double(1.8191804), new Double(1.8223421), null }, { new DataWithIcon("Japanese Yen", new ImageIcon(thisClass .getResource("japan.gif"))), new Double(141.0815412), new Double(121.0040432), null } };
} class FractionCellRenderer extends DefaultTableCellRenderer {
public FractionCellRenderer(int integer, int fraction, int align) { this.integer = integer; // maximum integer digits this.fraction = fraction; // exact number of fraction digits this.align = align; // alignment (LEFT, CENTER, RIGHT) } protected void setValue(Object value) { if (value != null && value instanceof Number) { formatter.setMaximumIntegerDigits(integer); formatter.setMaximumFractionDigits(fraction); formatter.setMinimumFractionDigits(fraction); setText(formatter.format(((Number) value).doubleValue())); } else { super.setValue(value); } setHorizontalAlignment(align); } protected int integer; protected int fraction; protected int align; protected static NumberFormat formatter = NumberFormat.getInstance();
} class StripedTableCellRenderer implements TableCellRenderer {
public StripedTableCellRenderer(TableCellRenderer targetRenderer, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { this.targetRenderer = targetRenderer; this.evenBack = evenBack; this.evenFore = evenFore; this.oddBack = oddBack; this.oddFore = oddFore; } // Implementation of TableCellRenderer interface public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { TableCellRenderer renderer = targetRenderer; if (renderer == null) { // Get default renderer from the table renderer = table.getDefaultRenderer(table.getColumnClass(column)); } // Let the real renderer create the component Component comp = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); // Now apply the stripe effect if (isSelected == false && hasFocus == false) { if ((row & 1) == 0) { comp.setBackground(evenBack != null ? evenBack : table .getBackground()); comp.setForeground(evenFore != null ? evenFore : table .getForeground()); } else { comp.setBackground(oddBack != null ? oddBack : table .getBackground()); comp.setForeground(oddFore != null ? oddFore : table .getForeground()); } } return comp; } // Convenience method to apply this renderer to single column public static void installInColumn(JTable table, int columnIndex, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { TableColumn tc = table.getColumnModel().getColumn(columnIndex); // Get the cell renderer for this column, if any TableCellRenderer targetRenderer = tc.getCellRenderer(); // Create a new StripedTableCellRenderer and install it tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } // Convenience method to apply this renderer to an entire table public static void installInTable(JTable table, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { StripedTableCellRenderer sharedInstance = null; int columns = table.getColumnCount(); for (int i = 0; i < columns; i++) { TableColumn tc = table.getColumnModel().getColumn(i); TableCellRenderer targetRenderer = tc.getCellRenderer(); if (targetRenderer != null) { // This column has a specific renderer tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } else { // This column uses a class renderer - use a shared renderer if (sharedInstance == null) { sharedInstance = new StripedTableCellRenderer(null, evenBack, evenFore, oddBack, oddFore); } tc.setCellRenderer(sharedInstance); } } } protected TableCellRenderer targetRenderer; protected Color evenBack; protected Color evenFore; protected Color oddBack; protected Color oddFore;
} class TextWithIconCellRenderer extends DefaultTableCellRenderer {
protected void setValue(Object value) { if (value instanceof DataWithIcon) { if (value != null) { DataWithIcon d = (DataWithIcon) value; Object dataValue = d.getData(); setText(dataValue == null ? "" : dataValue.toString()); setIcon(d.getIcon()); setHorizontalTextPosition(SwingConstants.RIGHT); setVerticalTextPosition(SwingConstants.CENTER); setHorizontalAlignment(SwingConstants.LEFT); setVerticalAlignment(SwingConstants.CENTER); } else { setText(""); setIcon(null); } } else { super.setValue(value); } }
} class HighlightRenderer implements TableCellRenderer {
public HighlightRenderer(Comparator cmp, TableCellRenderer targetRenderer, Color backColor, Color foreColor, Color highlightBack, Color highlightFore) { this.cmp = cmp; this.targetRenderer = targetRenderer; this.backColor = backColor; this.foreColor = foreColor; this.highlightBack = highlightBack; this.highlightFore = highlightFore; } public Component getTableCellRendererComponent(JTable tbl, Object value, boolean isSelected, boolean hasFocus, int row, int column) { TableCellRenderer renderer = targetRenderer; if (renderer == null) { renderer = tbl.getDefaultRenderer(tbl.getColumnClass(column)); } Component comp = renderer.getTableCellRendererComponent(tbl, value, isSelected, hasFocus, row, column); if (isSelected == false && hasFocus == false && value != null) { if (cmp.shouldHighlight(tbl, value, row, column)) { comp.setForeground(highlightFore); comp.setBackground(highlightBack); } else { comp.setForeground(foreColor); comp.setBackground(backColor); } } return comp; } protected Comparator cmp; protected TableCellRenderer targetRenderer; protected Color backColor; protected Color foreColor; protected Color highlightBack; protected Color highlightFore;
}
</source>
Icon Currency Table
<source lang="java">
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall
- /
import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.text.NumberFormat; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableColumnModel; public class IconCurrencyTable {
public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception evt) {} JFrame f = new JFrame("Icon Currency Table"); JTable tbl = new JTable(new CurrencyTableModel()); tbl.setDefaultRenderer(java.lang.Number.class, new FractionCellRenderer(10, 3, SwingConstants.RIGHT)); TableColumnModel tcm = tbl.getColumnModel(); tcm.getColumn(0).setPreferredWidth(150); tcm.getColumn(0).setMinWidth(150); TextWithIconCellRenderer renderer = new TextWithIconCellRenderer(); tcm.getColumn(0).setCellRenderer(renderer); tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tbl.setPreferredScrollableViewportSize(tbl.getPreferredSize()); JScrollPane sp = new JScrollPane(tbl); f.getContentPane().add(sp, "Center"); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); f.setVisible(true); }
} class CurrencyTableModel extends AbstractTableModel {
protected String[] columnNames = { "Currency", "Yesterday", "Today", "Change" }; // Constructor: calculate currency change to create the last column public CurrencyTableModel() { for (int i = 0; i < data.length; i++) { data[i][DIFF_COLUMN] = new Double( ((Double) data[i][NEW_RATE_COLUMN]).doubleValue() - ((Double) data[i][OLD_RATE_COLUMN]).doubleValue()); } } // Implementation of TableModel interface public int getRowCount() { return data.length; } public int getColumnCount() { return COLUMN_COUNT; } public Object getValueAt(int row, int column) { return data[row][column]; } public Class getColumnClass(int column) { return (data[0][column]).getClass(); } public String getColumnName(int column) { return columnNames[column]; } protected static final int OLD_RATE_COLUMN = 1; protected static final int NEW_RATE_COLUMN = 2; protected static final int DIFF_COLUMN = 3; protected static final int COLUMN_COUNT = 4; protected static final Class thisClass = CurrencyTableModel.class; protected Object[][] data = new Object[][] { { new DataWithIcon("Belgian Franc", new ImageIcon(thisClass .getResource("belgium.gif"))), new Double(37.6460110), new Double(37.6508921), null }, { new DataWithIcon("British Pound", new ImageIcon(thisClass .getResource("gb.gif"))), new Double(0.6213051), new Double(0.6104102), null }, { new DataWithIcon("Canadian Dollar", new ImageIcon(thisClass .getResource("canada.gif"))), new Double(1.4651209), new Double(1.5011104), null }, { new DataWithIcon("French Franc", new ImageIcon(thisClass .getResource("france.gif"))), new Double(6.1060001), new Double(6.0100101), null }, { new DataWithIcon("Italian Lire", new ImageIcon(thisClass .getResource("italy.gif"))), new Double(1181.3668977), new Double(1182.104), null }, { new DataWithIcon("German Mark", new ImageIcon(thisClass .getResource("germany.gif"))), new Double(1.8191804), new Double(1.8223421), null }, { new DataWithIcon("Japanese Yen", new ImageIcon(thisClass .getResource("japan.gif"))), new Double(141.0815412), new Double(121.0040432), null } };
} class DataWithIcon {
public DataWithIcon(Object data, Icon icon) { this.data = data; this.icon = icon; } public Icon getIcon() { return icon; } public Object getData() { return data; } public String toString() { return data.toString(); } protected Icon icon; protected Object data;
} class FractionCellRenderer extends DefaultTableCellRenderer {
public FractionCellRenderer(int integer, int fraction, int align) { this.integer = integer; // maximum integer digits this.fraction = fraction; // exact number of fraction digits this.align = align; // alignment (LEFT, CENTER, RIGHT) } protected void setValue(Object value) { if (value != null && value instanceof Number) { formatter.setMaximumIntegerDigits(integer); formatter.setMaximumFractionDigits(fraction); formatter.setMinimumFractionDigits(fraction); setText(formatter.format(((Number) value).doubleValue())); } else { super.setValue(value); } setHorizontalAlignment(align); } protected int integer; protected int fraction; protected int align; protected static NumberFormat formatter = NumberFormat.getInstance();
} class TextWithIconCellRenderer extends DefaultTableCellRenderer {
protected void setValue(Object value) { if (value instanceof DataWithIcon) { if (value != null) { DataWithIcon d = (DataWithIcon)value; Object dataValue = d.getData(); setText(dataValue == null ? "" : dataValue.toString()); setIcon(d.getIcon()); setHorizontalTextPosition(SwingConstants.RIGHT); setVerticalTextPosition(SwingConstants.CENTER); setHorizontalAlignment(SwingConstants.LEFT); setVerticalAlignment(SwingConstants.CENTER); } else { setText(""); setIcon(null); } } else { super.setValue(value); } }
}
</source>
Indicator Table Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html
/* (swing1.1) */
import java.awt.BorderLayout; import java.awt.Color; import java.awt.ruponent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Enumeration; import java.util.Hashtable; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableModel; /**
* @version 1.0 03/03/99 */
public class IndicatorTableExample extends JPanel {
private static final int MAX = 100; private static final int MIN = 0; public IndicatorTableExample() { setLayout(new BorderLayout()); DefaultTableModel dm = new DefaultTableModel() { public Class getColumnClass(int col) { switch (col) { case 0: return String.class; case 1: return Integer.class; case 2: return Integer.class; default: return Object.class; } } public boolean isCellEditable(int row, int col) { switch (col) { case 2: return false; default: return true; } } public void setValueAt(Object obj, int row, int col) { if (col != 1) { super.setValueAt(obj, row, col); return; } try { Integer integer = new Integer(obj.toString()); super.setValueAt(checkMinMax(integer), row, col); } catch (NumberFormatException ex) { ex.printStackTrace(); } } }; dm.setDataVector(new Object[][] { { "not human", new Integer(100), new Integer(100) }, { "hard worker", new Integer(76), new Integer(76) }, { "ordinary guy", new Integer(51), new Integer(51) }, { "lazy fellow", new Integer(12), new Integer(12) } }, new Object[] { "Name", "Result", "Indicator" }); JTable table = new JTable(dm); IndicatorCellRenderer renderer = new IndicatorCellRenderer(MIN, MAX); renderer.setStringPainted(true); renderer.setBackground(table.getBackground()); // set limit value and fill color Hashtable limitColors = new Hashtable(); limitColors.put(new Integer(0), Color.green); limitColors.put(new Integer(60), Color.yellow); limitColors.put(new Integer(80), Color.red); renderer.setLimits(limitColors); table.getColumnModel().getColumn(2).setCellRenderer(renderer); table.getModel().addTableModelListener(new TableModelListener() { public void tableChanged(TableModelEvent e) { if (e.getType() == TableModelEvent.UPDATE) { int col = e.getColumn(); if (col == 1) { int row = e.getFirstRow(); TableModel model = (TableModel) e.getSource(); Integer value = (Integer) model.getValueAt(row, col); model.setValueAt(checkMinMax(value), row, ++col); } } } }); JScrollPane pane = new JScrollPane(table); add(pane, BorderLayout.CENTER); } public static void main(String[] args) { JFrame f = new JFrame("IndicatorTable Example"); f.getContentPane() .add(new IndicatorTableExample(), BorderLayout.CENTER); f.setSize(400, 120); f.setVisible(true); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } private Integer checkMinMax(Integer value) { int intValue = value.intValue(); if (intValue < MIN) { intValue = MIN; } else if (MAX < intValue) { intValue = MAX; } return new Integer(intValue); }
} /**
* @version 1.0 03/03/99 */
class IndicatorCellRenderer extends JProgressBar implements TableCellRenderer {
private Hashtable limitColors; private int[] limitValues; public IndicatorCellRenderer() { super(JProgressBar.HORIZONTAL); setBorderPainted(false); } public IndicatorCellRenderer(int min, int max) { super(JProgressBar.HORIZONTAL, min, max); setBorderPainted(false); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { int n = 0; if (!(value instanceof Number)) { String str; if (value instanceof String) { str = (String) value; } else { str = value.toString(); } try { n = Integer.valueOf(str).intValue(); } catch (NumberFormatException ex) { } } else { n = ((Number) value).intValue(); } Color color = getColor(n); if (color != null) { setForeground(color); } setValue(n); return this; } public void setLimits(Hashtable limitColors) { this.limitColors = limitColors; int i = 0; int n = limitColors.size(); limitValues = new int[n]; Enumeration e = limitColors.keys(); while (e.hasMoreElements()) { limitValues[i++] = ((Integer) e.nextElement()).intValue(); } sort(limitValues); } private Color getColor(int value) { Color color = null; if (limitValues != null) { int i; for (i = 0; i < limitValues.length; i++) { if (limitValues[i] < value) { color = (Color) limitColors .get(new Integer(limitValues[i])); } } } return color; } private void sort(int[] a) { int n = a.length; for (int i = 0; i < n - 1; i++) { int k = i; for (int j = i + 1; j < n; j++) { if (a[j] < a[k]) { k = j; } } int tmp = a[i]; a[i] = a[k]; a[k] = tmp; } }
}
</source>
JSortTable
<source lang="java">
package org.tn5250j.gui; /*
JSortTable.java Created by Claude Duguay Copyright (c) 2002 This was taken from a Java Pro magazine article http://www.fawcette.ru/javapro/codepage.asp?loccode=jp0208 I have NOT asked for permission to use this.
- /
import java.awt.Color; import java.awt.ruponent; import java.awt.Graphics; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.Collections; import java.util.ruparator; import java.util.Vector; import javax.swing.Icon; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.UIManager; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; import javax.swing.table.TableColumnModel; import javax.swing.table.TableModel; public class JSortTable extends JTable implements MouseListener {
protected int sortedColumnIndex = -1; protected boolean sortedColumnAscending = true; public JSortTable() { this(new DefaultSortTableModel()); } public JSortTable(int rows, int cols) { this(new DefaultSortTableModel(rows, cols)); } public JSortTable(Object[][] data, Object[] names) { this(new DefaultSortTableModel(data, names)); } public JSortTable(Vector data, Vector names) { this(new DefaultSortTableModel(data, names)); } public JSortTable(SortTableModel model) { super(model); initSortHeader(); } public JSortTable(SortTableModel model, TableColumnModel colModel) { super(model, colModel); initSortHeader(); } public JSortTable(SortTableModel model, TableColumnModel colModel, ListSelectionModel selModel) { super(model, colModel, selModel); initSortHeader(); } protected void initSortHeader() { JTableHeader header = getTableHeader(); header.setDefaultRenderer(new SortHeaderRenderer()); header.addMouseListener(this); } public int getSortedColumnIndex() { return sortedColumnIndex; } public boolean isSortedColumnAscending() { return sortedColumnAscending; } public void mouseReleased(MouseEvent event) { TableColumnModel colModel = getColumnModel(); int index = colModel.getColumnIndexAtX(event.getX()); int modelIndex = colModel.getColumn(index).getModelIndex(); SortTableModel model = (SortTableModel)getModel(); if (model.isSortable(modelIndex)) { // toggle ascension, if already sorted if (sortedColumnIndex == index) { sortedColumnAscending = !sortedColumnAscending; } sortedColumnIndex = index; model.sortColumn(modelIndex, sortedColumnAscending); } } public void mousePressed(MouseEvent event) {} public void mouseClicked(MouseEvent event) {} public void mouseEntered(MouseEvent event) {} public void mouseExited(MouseEvent event) {}
} /*
DefaultSortTableModel.java Created by Claude Duguay Copyright (c) 2002 This was taken from a Java Pro magazine article http://www.fawcette.ru/javapro/codepage.asp?loccode=jp0208 I have NOT asked for permission to use this.
- /
class DefaultSortTableModel extends DefaultTableModel implements SortTableModel { public DefaultSortTableModel() {} public DefaultSortTableModel(int rows, int cols) { super(rows, cols); } public DefaultSortTableModel(Object[][] data, Object[] names) { super(data, names); } public DefaultSortTableModel(Object[] names, int rows) { super(names, rows); } public DefaultSortTableModel(Vector names, int rows) { super(names, rows); } public DefaultSortTableModel(Vector data, Vector names) { super(data, names); } public boolean isSortable(int col) { return true; } public void sortColumn(int col, boolean ascending) { Collections.sort(getDataVector(), new ColumnComparator(col, ascending)); }
}
/* SortTableModel.java Created by Claude Duguay Copyright (c) 2002 This was taken from a Java Pro magazine article http://www.fawcette.ru/javapro/codepage.asp?loccode=jp0208 I have NOT asked for permission to use this. */ interface SortTableModel extends TableModel { public boolean isSortable(int col); public void sortColumn(int col, boolean ascending); } /* ColumnComparator.java Created by Claude Duguay Copyright (c) 2002 This was taken from a Java Pro magazine article http://www.fawcette.ru/javapro/codepage.asp?loccode=jp0208 I have NOT asked for permission to use this. */ class ColumnComparator implements Comparator { protected int index; protected boolean ascending; public ColumnComparator(int index, boolean ascending) { this.index = index; this.ascending = ascending; } public int compare(Object one, Object two) { if (one instanceof Vector && two instanceof Vector) { Vector vOne = (Vector)one; Vector vTwo = (Vector)two; Object oOne = vOne.elementAt(index); Object oTwo = vTwo.elementAt(index); if (oOne instanceof Comparable && oTwo instanceof Comparable) { Comparable cOne = (Comparable)oOne; Comparable cTwo = (Comparable)oTwo; if (ascending) { return cOne.rupareTo(cTwo); } else { return cTwo.rupareTo(cOne); } } } return 1; } }
/* SortHeaderRenderer.java Created by Claude Duguay Copyright (c) 2002 This was taken from a Java Pro magazine article http://www.fawcette.ru/javapro/codepage.asp?loccode=jp0208 I have NOT asked for permission to use this. */ class SortHeaderRenderer extends DefaultTableCellRenderer { public static Icon NONSORTED = new SortArrowIcon(SortArrowIcon.NONE); public static Icon ASCENDING = new SortArrowIcon(SortArrowIcon.ASCENDING); public static Icon DECENDING = new SortArrowIcon(SortArrowIcon.DECENDING); public SortHeaderRenderer() { setHorizontalTextPosition(LEFT); setHorizontalAlignment(CENTER); } public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) { int index = -1; boolean ascending = true; if (table instanceof JSortTable) { JSortTable sortTable = (JSortTable)table; index = sortTable.getSortedColumnIndex(); ascending = sortTable.isSortedColumnAscending(); } if (table != null) { JTableHeader header = table.getTableHeader(); if (header != null) { setForeground(header.getForeground()); setBackground(header.getBackground()); setFont(header.getFont()); } } Icon icon = ascending ? ASCENDING : DECENDING; setIcon(col == index ? icon : NONSORTED); setText((value == null) ? "" : value.toString()); setBorder(UIManager.getBorder("TableHeader.cellBorder")); return this; } }
/* SortArrowIcon.java Created by Claude Duguay Copyright (c) 2002 This was taken from a Java Pro magazine article http://www.fawcette.ru/javapro/codepage.asp?loccode=jp0208 I have NOT asked for permission to use this. */ class SortArrowIcon implements Icon { public static final int NONE = 0; public static final int DECENDING = 1; public static final int ASCENDING = 2; protected int direction; protected int width = 8; protected int height = 8; public SortArrowIcon(int direction) { this.direction = direction; } public int getIconWidth() { return width; } public int getIconHeight() { return height; } public void paintIcon(Component c, Graphics g, int x, int y) { Color bg = c.getBackground(); Color light = bg.brighter(); Color shade = bg.darker(); int w = width; int h = height; int m = w / 2; if (direction == ASCENDING) { g.setColor(shade); g.drawLine(x, y, x + w, y); g.drawLine(x, y, x + m, y + h); g.setColor(light); g.drawLine(x + w, y, x + m, y + h); } if (direction == DECENDING) { g.setColor(shade); g.drawLine(x + m, y, x, y + h); g.setColor(light); g.drawLine(x, y + h, x + w, y + h); g.drawLine(x + m, y, x + w, y + h); } } } </source>
Mixed Table Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /*
* (swing1.1beta3) */
import java.awt.BorderLayout; import java.awt.Color; import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Enumeration; import java.util.Vector; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JColorChooser; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.event.ListSelectionEvent; import javax.swing.event.TableModelEvent; import javax.swing.plaf.basic.BasicTableUI; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableModel; /**
* @version 1.0 11/22/98 */
public class MixedExample extends JFrame {
public MixedExample() { super("Mixed Example"); AttributiveCellTableModel ml = new AttributiveCellTableModel(20, 5) { public Object getValueAt(int row, int col) { return "" + row + "," + col; } }; CellAttribute cellAtt = ml.getCellAttribute(); MultiSpanCellTable table = new MultiSpanCellTable(ml); table.setCellSelectionEnabled(true); table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); table.setDefaultRenderer(Object.class, new AttributiveCellRenderer()); JScrollPane scroll = new JScrollPane(table); ColorPanel colorPanel = new ColorPanel(table, (ColoredCell) cellAtt); FontPanel fontPanel = new FontPanel(table, (CellFont) cellAtt); SpanPanel spanPanel = new SpanPanel(table, (CellSpan) cellAtt); Box boxAtt = new Box(BoxLayout.Y_AXIS); boxAtt.add(colorPanel); boxAtt.add(fontPanel); boxAtt.add(spanPanel); Box box = new Box(BoxLayout.X_AXIS); box.add(scroll); box.add(new JSeparator(SwingConstants.HORIZONTAL)); box.add(boxAtt); getContentPane().add(box); setSize(400, 300); setVisible(true); } class ColorPanel extends JPanel { JTable table; ColoredCell cellAtt; ColorPanel(final JTable table, final ColoredCell cellAtt) { this.table = table; this.cellAtt = cellAtt; setLayout(new GridLayout(2, 1)); setBorder(BorderFactory.createTitledBorder("Color")); JButton b_fore = new JButton("Foreground"); b_fore.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { changeColor(true); } }); JButton b_back = new JButton("Background"); b_back.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { changeColor(false); } }); JPanel p_buttons = new JPanel(); add(b_fore); add(b_back); } private final void changeColor(boolean isForeground) { int[] columns = table.getSelectedColumns(); int[] rows = table.getSelectedRows(); if ((rows == null) || (columns == null)) return; if ((rows.length < 1) || (columns.length < 1)) return; Color target = cellAtt.getForeground(rows[0], columns[0]); Color reference = cellAtt.getBackground(rows[0], columns[0]); for (int i = 0; i < rows.length; i++) { int row = rows[i]; for (int j = 0; j < columns.length; j++) { int column = columns[j]; target = (target != cellAtt.getForeground(row, column)) ? null : target; reference = (reference != cellAtt .getBackground(row, column)) ? null : reference; } } String title; if (isForeground) { target = (target != null) ? target : table.getForeground(); reference = (reference != null) ? reference : table .getBackground(); title = "Foreground Color"; } else { target = (reference != null) ? reference : table .getBackground(); reference = (target != null) ? target : table.getForeground(); title = "Foreground Color"; } TextColorChooser chooser = new TextColorChooser(target, reference, isForeground); Color color = chooser.showDialog(MixedExample.this, title); if (color != null) { if (isForeground) { cellAtt.setForeground(color, rows, columns); } else { cellAtt.setBackground(color, rows, columns); } table.clearSelection(); table.revalidate(); table.repaint(); } } } class FontPanel extends JPanel { String[] str_size = { "10", "12", "14", "16", "20" }; String[] str_style = { "PLAIN", "BOLD", "ITALIC" }; JComboBox name, style, size; FontPanel(final JTable table, final CellFont cellAtt) { setLayout(new BorderLayout()); setBorder(BorderFactory.createTitledBorder("Font")); Box box = new Box(BoxLayout.X_AXIS); JPanel p2 = new JPanel(new GridLayout(3, 1)); JPanel p3 = new JPanel(new GridLayout(3, 1)); JPanel p4 = new JPanel(new BorderLayout()); p2.add(new JLabel("Name:")); p2.add(new JLabel("Style:")); p2.add(new JLabel("Size:")); Toolkit toolkit = Toolkit.getDefaultToolkit(); name = new JComboBox(toolkit.getFontList()); style = new JComboBox(str_style); size = new JComboBox(str_size); size.setEditable(true); JButton b_apply = new JButton("Apply"); b_apply.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int[] columns = table.getSelectedColumns(); int[] rows = table.getSelectedRows(); if ((rows == null) || (columns == null)) return; if ((rows.length < 1) || (columns.length < 1)) return; Font font = new Font((String) name.getSelectedItem(), style .getSelectedIndex(), Integer.parseInt((String) size .getSelectedItem())); cellAtt.setFont(font, rows, columns); table.clearSelection(); table.revalidate(); table.repaint(); } }); p3.add(name); p3.add(style); p3.add(size); p4.add(BorderLayout.CENTER, b_apply); box.add(p2); box.add(p3); add(BorderLayout.CENTER, box); add(BorderLayout.SOUTH, p4); } } class SpanPanel extends JPanel { JTable table; CellSpan cellAtt; SpanPanel(final JTable table, final CellSpan cellAtt) { this.table = table; this.cellAtt = cellAtt; setLayout(new GridLayout(2, 1)); setBorder(BorderFactory.createTitledBorder("Span")); JButton b_one = new JButton("Combine"); b_one.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int[] columns = table.getSelectedColumns(); int[] rows = table.getSelectedRows(); cellAtt.rubine(rows, columns); table.clearSelection(); table.revalidate(); table.repaint(); } }); JButton b_split = new JButton("Split"); b_split.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int column = table.getSelectedColumn(); int row = table.getSelectedRow(); cellAtt.split(row, column); table.clearSelection(); table.revalidate(); table.repaint(); } }); add(b_one); add(b_split); } } public static void main(String[] args) { MixedExample frame = new MixedExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); }
} class AttributiveCellTableModel extends DefaultTableModel {
protected CellAttribute cellAtt; public AttributiveCellTableModel() { this((Vector) null, 0); } public AttributiveCellTableModel(int numRows, int numColumns) { Vector names = new Vector(numColumns); names.setSize(numColumns); setColumnIdentifiers(names); dataVector = new Vector(); setNumRows(numRows); cellAtt = new DefaultCellAttribute(numRows, numColumns); } public AttributiveCellTableModel(Vector columnNames, int numRows) { setColumnIdentifiers(columnNames); dataVector = new Vector(); setNumRows(numRows); cellAtt = new DefaultCellAttribute(numRows, columnNames.size()); } public AttributiveCellTableModel(Object[] columnNames, int numRows) { this(convertToVector(columnNames), numRows); } public AttributiveCellTableModel(Vector data, Vector columnNames) { setDataVector(data, columnNames); } public AttributiveCellTableModel(Object[][] data, Object[] columnNames) { setDataVector(data, columnNames); } public void setDataVector(Vector newData, Vector columnNames) { if (newData == null) throw new IllegalArgumentException( "setDataVector() - Null parameter"); dataVector = new Vector(0); setColumnIdentifiers(columnNames); dataVector = newData; // cellAtt = new DefaultCellAttribute(dataVector.size(), columnIdentifiers .size()); newRowsAdded(new TableModelEvent(this, 0, getRowCount() - 1, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } public void addColumn(Object columnName, Vector columnData) { if (columnName == null) throw new IllegalArgumentException("addColumn() - null parameter"); columnIdentifiers.addElement(columnName); int index = 0; Enumeration enumeration = dataVector.elements(); while (enumeration.hasMoreElements()) { Object value; if ((columnData != null) && (index < columnData.size())) value = columnData.elementAt(index); else value = null; ((Vector) enumeration.nextElement()).addElement(value); index++; } // cellAtt.addColumn(); fireTableStructureChanged(); } public void addRow(Vector rowData) { Vector newData = null; if (rowData == null) { newData = new Vector(getColumnCount()); } else { rowData.setSize(getColumnCount()); } dataVector.addElement(newData); // cellAtt.addRow(); newRowsAdded(new TableModelEvent(this, getRowCount() - 1, getRowCount() - 1, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } public void insertRow(int row, Vector rowData) { if (rowData == null) { rowData = new Vector(getColumnCount()); } else { rowData.setSize(getColumnCount()); } dataVector.insertElementAt(rowData, row); // cellAtt.insertRow(row); newRowsAdded(new TableModelEvent(this, row, row, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } public CellAttribute getCellAttribute() { return cellAtt; } public void setCellAttribute(CellAttribute newCellAtt) { int numColumns = getColumnCount(); int numRows = getRowCount(); if ((newCellAtt.getSize().width != numColumns) || (newCellAtt.getSize().height != numRows)) { newCellAtt.setSize(new Dimension(numRows, numColumns)); } cellAtt = newCellAtt; fireTableDataChanged(); } /* * public void changeCellAttribute(int row, int column, Object command) { * cellAtt.changeAttribute(row, column, command); } * * public void changeCellAttribute(int[] rows, int[] columns, Object * command) { cellAtt.changeAttribute(rows, columns, command); } */
} class DefaultCellAttribute //implements CellAttribute ,CellSpan {
implements CellAttribute, CellSpan, ColoredCell, CellFont { // // !!!! CAUTION !!!!! // these values must be synchronized to Table data // protected int rowSize; protected int columnSize; protected int[][][] span; // CellSpan protected Color[][] foreground; // ColoredCell protected Color[][] background; // protected Font[][] font; // CellFont public DefaultCellAttribute() { this(1, 1); } public DefaultCellAttribute(int numRows, int numColumns) { setSize(new Dimension(numColumns, numRows)); } protected void initValue() { for (int i = 0; i < span.length; i++) { for (int j = 0; j < span[i].length; j++) { span[i][j][CellSpan.COLUMN] = 1; span[i][j][CellSpan.ROW] = 1; } } } // // CellSpan // public int[] getSpan(int row, int column) { if (isOutOfBounds(row, column)) { int[] ret_code = { 1, 1 }; return ret_code; } return span[row][column]; } public void setSpan(int[] span, int row, int column) { if (isOutOfBounds(row, column)) return; this.span[row][column] = span; } public boolean isVisible(int row, int column) { if (isOutOfBounds(row, column)) return false; if ((span[row][column][CellSpan.COLUMN] < 1) || (span[row][column][CellSpan.ROW] < 1)) return false; return true; } public void combine(int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; int rowSpan = rows.length; int columnSpan = columns.length; int startRow = rows[0]; int startColumn = columns[0]; for (int i = 0; i < rowSpan; i++) { for (int j = 0; j < columnSpan; j++) { if ((span[startRow + i][startColumn + j][CellSpan.COLUMN] != 1) || (span[startRow + i][startColumn + j][CellSpan.ROW] != 1)) { //System.out.println("can"t combine"); return; } } } for (int i = 0, ii = 0; i < rowSpan; i++, ii--) { for (int j = 0, jj = 0; j < columnSpan; j++, jj--) { span[startRow + i][startColumn + j][CellSpan.COLUMN] = jj; span[startRow + i][startColumn + j][CellSpan.ROW] = ii; //System.out.println("r " +ii +" c " +jj); } } span[startRow][startColumn][CellSpan.COLUMN] = columnSpan; span[startRow][startColumn][CellSpan.ROW] = rowSpan; } public void split(int row, int column) { if (isOutOfBounds(row, column)) return; int columnSpan = span[row][column][CellSpan.COLUMN]; int rowSpan = span[row][column][CellSpan.ROW]; for (int i = 0; i < rowSpan; i++) { for (int j = 0; j < columnSpan; j++) { span[row + i][column + j][CellSpan.COLUMN] = 1; span[row + i][column + j][CellSpan.ROW] = 1; } } } // // ColoredCell // public Color getForeground(int row, int column) { if (isOutOfBounds(row, column)) return null; return foreground[row][column]; } public void setForeground(Color color, int row, int column) { if (isOutOfBounds(row, column)) return; foreground[row][column] = color; } public void setForeground(Color color, int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; setValues(foreground, color, rows, columns); } public Color getBackground(int row, int column) { if (isOutOfBounds(row, column)) return null; return background[row][column]; } public void setBackground(Color color, int row, int column) { if (isOutOfBounds(row, column)) return; background[row][column] = color; } public void setBackground(Color color, int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; setValues(background, color, rows, columns); } // // // CellFont // public Font getFont(int row, int column) { if (isOutOfBounds(row, column)) return null; return font[row][column]; } public void setFont(Font font, int row, int column) { if (isOutOfBounds(row, column)) return; this.font[row][column] = font; } public void setFont(Font font, int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; setValues(this.font, font, rows, columns); } // // // CellAttribute // public void addColumn() { int[][][] oldSpan = span; int numRows = oldSpan.length; int numColumns = oldSpan[0].length; span = new int[numRows][numColumns + 1][2]; System.arraycopy(oldSpan, 0, span, 0, numRows); for (int i = 0; i < numRows; i++) { span[i][numColumns][CellSpan.COLUMN] = 1; span[i][numColumns][CellSpan.ROW] = 1; } } public void addRow() { int[][][] oldSpan = span; int numRows = oldSpan.length; int numColumns = oldSpan[0].length; span = new int[numRows + 1][numColumns][2]; System.arraycopy(oldSpan, 0, span, 0, numRows); for (int i = 0; i < numColumns; i++) { span[numRows][i][CellSpan.COLUMN] = 1; span[numRows][i][CellSpan.ROW] = 1; } } public void insertRow(int row) { int[][][] oldSpan = span; int numRows = oldSpan.length; int numColumns = oldSpan[0].length; span = new int[numRows + 1][numColumns][2]; if (0 < row) { System.arraycopy(oldSpan, 0, span, 0, row - 1); } System.arraycopy(oldSpan, 0, span, row, numRows - row); for (int i = 0; i < numColumns; i++) { span[row][i][CellSpan.COLUMN] = 1; span[row][i][CellSpan.ROW] = 1; } } public Dimension getSize() { return new Dimension(rowSize, columnSize); } public void setSize(Dimension size) { columnSize = size.width; rowSize = size.height; span = new int[rowSize][columnSize][2]; // 2: COLUMN,ROW foreground = new Color[rowSize][columnSize]; background = new Color[rowSize][columnSize]; font = new Font[rowSize][columnSize]; initValue(); } /* * public void changeAttribute(int row, int column, Object command) { } * * public void changeAttribute(int[] rows, int[] columns, Object command) { } */ protected boolean isOutOfBounds(int row, int column) { if ((row < 0) || (rowSize <= row) || (column < 0) || (columnSize <= column)) { return true; } return false; } protected boolean isOutOfBounds(int[] rows, int[] columns) { for (int i = 0; i < rows.length; i++) { if ((rows[i] < 0) || (rowSize <= rows[i])) return true; } for (int i = 0; i < columns.length; i++) { if ((columns[i] < 0) || (columnSize <= columns[i])) return true; } return false; } protected void setValues(Object[][] target, Object value, int[] rows, int[] columns) { for (int i = 0; i < rows.length; i++) { int row = rows[i]; for (int j = 0; j < columns.length; j++) { int column = columns[j]; target[row][column] = value; } } }
} interface CellAttribute {
public void addColumn(); public void addRow(); public void insertRow(int row); public Dimension getSize(); public void setSize(Dimension size);
} interface ColoredCell {
public Color getForeground(int row, int column); public void setForeground(Color color, int row, int column); public void setForeground(Color color, int[] rows, int[] columns); public Color getBackground(int row, int column); public void setBackground(Color color, int row, int column); public void setBackground(Color color, int[] rows, int[] columns);
} interface CellFont {
public Font getFont(int row, int column); public void setFont(Font font, int row, int column); public void setFont(Font font, int[] rows, int[] columns);
} interface CellSpan {
public final int ROW = 0; public final int COLUMN = 1; public int[] getSpan(int row, int column); public void setSpan(int[] span, int row, int column); public boolean isVisible(int row, int column); public void combine(int[] rows, int[] columns); public void split(int row, int column);
} class MultiSpanCellTable extends JTable {
public MultiSpanCellTable(TableModel model) { super(model); setUI(new MultiSpanCellTableUI()); getTableHeader().setReorderingAllowed(false); setCellSelectionEnabled(true); setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); } public Rectangle getCellRect(int row, int column, boolean includeSpacing) { Rectangle sRect = super.getCellRect(row, column, includeSpacing); if ((row < 0) || (column < 0) || (getRowCount() <= row) || (getColumnCount() <= column)) { return sRect; } CellSpan cellAtt = (CellSpan) ((AttributiveCellTableModel) getModel()) .getCellAttribute(); if (!cellAtt.isVisible(row, column)) { int temp_row = row; int temp_column = column; row += cellAtt.getSpan(temp_row, temp_column)[CellSpan.ROW]; column += cellAtt.getSpan(temp_row, temp_column)[CellSpan.COLUMN]; } int[] n = cellAtt.getSpan(row, column); int index = 0; int columnMargin = getColumnModel().getColumnMargin(); Rectangle cellFrame = new Rectangle(); int aCellHeight = rowHeight + rowMargin; cellFrame.y = row * aCellHeight; cellFrame.height = n[CellSpan.ROW] * aCellHeight; Enumeration enumeration = getColumnModel().getColumns(); while (enumeration.hasMoreElements()) { TableColumn aColumn = (TableColumn) enumeration.nextElement(); cellFrame.width = aColumn.getWidth() + columnMargin; if (index == column) break; cellFrame.x += cellFrame.width; index++; } for (int i = 0; i < n[CellSpan.COLUMN] - 1; i++) { TableColumn aColumn = (TableColumn) enumeration.nextElement(); cellFrame.width += aColumn.getWidth() + columnMargin; } if (!includeSpacing) { Dimension spacing = getIntercellSpacing(); cellFrame.setBounds(cellFrame.x + spacing.width / 2, cellFrame.y + spacing.height / 2, cellFrame.width - spacing.width, cellFrame.height - spacing.height); } return cellFrame; } private int[] rowColumnAtPoint(Point point) { int[] retValue = { -1, -1 }; int row = point.y / (rowHeight + rowMargin); if ((row < 0) || (getRowCount() <= row)) return retValue; int column = getColumnModel().getColumnIndexAtX(point.x); CellSpan cellAtt = (CellSpan) ((AttributiveCellTableModel) getModel()) .getCellAttribute(); if (cellAtt.isVisible(row, column)) { retValue[CellSpan.COLUMN] = column; retValue[CellSpan.ROW] = row; return retValue; } retValue[CellSpan.COLUMN] = column + cellAtt.getSpan(row, column)[CellSpan.COLUMN]; retValue[CellSpan.ROW] = row + cellAtt.getSpan(row, column)[CellSpan.ROW]; return retValue; } public int rowAtPoint(Point point) { return rowColumnAtPoint(point)[CellSpan.ROW]; } public int columnAtPoint(Point point) { return rowColumnAtPoint(point)[CellSpan.COLUMN]; } public void columnSelectionChanged(ListSelectionEvent e) { repaint(); } public void valueChanged(ListSelectionEvent e) { int firstIndex = e.getFirstIndex(); int lastIndex = e.getLastIndex(); if (firstIndex == -1 && lastIndex == -1) { // Selection cleared. repaint(); } Rectangle dirtyRegion = getCellRect(firstIndex, 0, false); int numCoumns = getColumnCount(); int index = firstIndex; for (int i = 0; i < numCoumns; i++) { dirtyRegion.add(getCellRect(index, i, false)); } index = lastIndex; for (int i = 0; i < numCoumns; i++) { dirtyRegion.add(getCellRect(index, i, false)); } repaint(dirtyRegion.x, dirtyRegion.y, dirtyRegion.width, dirtyRegion.height); }
} class MultiSpanCellTableUI extends BasicTableUI {
public void paint(Graphics g, JComponent c) { Rectangle oldClipBounds = g.getClipBounds(); Rectangle clipBounds = new Rectangle(oldClipBounds); int tableWidth = table.getColumnModel().getTotalColumnWidth(); clipBounds.width = Math.min(clipBounds.width, tableWidth); g.setClip(clipBounds); int firstIndex = table.rowAtPoint(new Point(0, clipBounds.y)); int lastIndex = table.getRowCount() - 1; Rectangle rowRect = new Rectangle(0, 0, tableWidth, table .getRowHeight() + table.getRowMargin()); rowRect.y = firstIndex * rowRect.height; for (int index = firstIndex; index <= lastIndex; index++) { if (rowRect.intersects(clipBounds)) { //System.out.println(); // debug //System.out.print("" + index +": "); // row paintRow(g, index); } rowRect.y += rowRect.height; } g.setClip(oldClipBounds); } private void paintRow(Graphics g, int row) { Rectangle rect = g.getClipBounds(); boolean drawn = false; AttributiveCellTableModel tableModel = (AttributiveCellTableModel) table .getModel(); CellSpan cellAtt = (CellSpan) tableModel.getCellAttribute(); int numColumns = table.getColumnCount(); for (int column = 0; column < numColumns; column++) { Rectangle cellRect = table.getCellRect(row, column, true); int cellRow, cellColumn; if (cellAtt.isVisible(row, column)) { cellRow = row; cellColumn = column; // System.out.print(" "+column+" "); // debug } else { cellRow = row + cellAtt.getSpan(row, column)[CellSpan.ROW]; cellColumn = column + cellAtt.getSpan(row, column)[CellSpan.COLUMN]; // System.out.print(" ("+column+")"); // debug } if (cellRect.intersects(rect)) { drawn = true; paintCell(g, cellRect, cellRow, cellColumn); } else { if (drawn) break; } } } private void paintCell(Graphics g, Rectangle cellRect, int row, int column) { int spacingHeight = table.getRowMargin(); int spacingWidth = table.getColumnModel().getColumnMargin(); Color c = g.getColor(); g.setColor(table.getGridColor()); g.drawRect(cellRect.x, cellRect.y, cellRect.width - 1, cellRect.height - 1); g.setColor(c); cellRect.setBounds(cellRect.x + spacingWidth / 2, cellRect.y + spacingHeight / 2, cellRect.width - spacingWidth, cellRect.height - spacingHeight); if (table.isEditing() && table.getEditingRow() == row && table.getEditingColumn() == column) { Component component = table.getEditorComponent(); component.setBounds(cellRect); component.validate(); } else { TableCellRenderer renderer = table.getCellRenderer(row, column); Component component = table.prepareRenderer(renderer, row, column); if (component.getParent() == null) { rendererPane.add(component); } rendererPane.paintComponent(g, component, table, cellRect.x, cellRect.y, cellRect.width, cellRect.height, true); } }
} class AttributiveCellRenderer extends JLabel implements TableCellRenderer {
protected static Border noFocusBorder; public AttributiveCellRenderer() { noFocusBorder = new EmptyBorder(1, 2, 1, 2); setOpaque(true); setBorder(noFocusBorder); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Color foreground = null; Color background = null; Font font = null; TableModel model = table.getModel(); if (model instanceof AttributiveCellTableModel) { CellAttribute cellAtt = ((AttributiveCellTableModel) model) .getCellAttribute(); if (cellAtt instanceof ColoredCell) { foreground = ((ColoredCell) cellAtt).getForeground(row, column); background = ((ColoredCell) cellAtt).getBackground(row, column); } if (cellAtt instanceof CellFont) { font = ((CellFont) cellAtt).getFont(row, column); } } if (isSelected) { setForeground((foreground != null) ? foreground : table .getSelectionForeground()); setBackground(table.getSelectionBackground()); } else { setForeground((foreground != null) ? foreground : table .getForeground()); setBackground((background != null) ? background : table .getBackground()); } setFont((font != null) ? font : table.getFont()); if (hasFocus) { setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); if (table.isCellEditable(row, column)) { setForeground((foreground != null) ? foreground : UIManager .getColor("Table.focusCellForeground")); setBackground(UIManager.getColor("Table.focusCellBackground")); } } else { setBorder(noFocusBorder); } setValue(value); return this; } protected void setValue(Object value) { setText((value == null) ? "" : value.toString()); }
} class TextPreviewLabel extends JLabel {
private String sampleText = " Sample Text Sample Text "; boolean isForgroundSelection; public TextPreviewLabel() { this(Color.black, Color.white, true); } public TextPreviewLabel(Color fore, Color back, boolean isForgroundSelection) { setOpaque(true); setForeground(fore); setBackground(back); this.isForgroundSelection = isForgroundSelection; setText(sampleText); } public void setForeground(Color col) { if (isForgroundSelection) { super.setForeground(col); } else { super.setBackground(col); } }
} class ColorChooserDialog extends JDialog {
private Color initialColor; private Color retColor; private JColorChooser chooserPane; public ColorChooserDialog(Component c, String title, final JColorChooser chooserPane) { super(JOptionPane.getFrameForComponent(c), title, true); setResizable(false); this.chooserPane = chooserPane; String okString = UIManager.getString("ColorChooser.okText"); String cancelString = UIManager.getString("ColorChooser.cancelText"); String resetString = UIManager.getString("ColorChooser.resetText"); Container contentPane = getContentPane(); contentPane.setLayout(new BorderLayout()); contentPane.add(chooserPane, BorderLayout.CENTER); JPanel buttonPane = new JPanel(); buttonPane.setLayout(new FlowLayout(FlowLayout.CENTER)); JButton okButton = new JButton(okString); getRootPane().setDefaultButton(okButton); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { retColor = chooserPane.getColor(); setVisible(false); } }); buttonPane.add(okButton); JButton cancelButton = new JButton(cancelString); cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { retColor = null; setVisible(false); } }); buttonPane.add(cancelButton); JButton resetButton = new JButton(resetString); resetButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { chooserPane.setColor(initialColor); } }); buttonPane.add(resetButton); contentPane.add(buttonPane, BorderLayout.SOUTH); pack(); setLocationRelativeTo(c); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { setVisible(false); } }); } public Color getColor() { return retColor; }
} class TextColorChooser extends JColorChooser {
public TextColorChooser(Color target, Color reference, boolean isForgroundSelection) { super(target); if (isForgroundSelection) { setPreviewPanel(new TextPreviewLabel(target, reference, isForgroundSelection)); } else { setPreviewPanel(new TextPreviewLabel(reference, target, isForgroundSelection)); } updateUI(); } public Color showDialog(Component component, String title) { ColorChooserDialog dialog = new ColorChooserDialog(component, title, this); dialog.show(); Color col = dialog.getColor(); dialog.dispose(); return col; }
}
</source>
MultiLine Cell Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /*
* If You can accept all cells have same Height. */
/* (swing1.1beta3) */ import java.awt.ruponent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextArea; import javax.swing.UIManager; import javax.swing.border.EmptyBorder; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; /**
* @version 1.0 11/09/98 */
public class MultiLineCellExample extends JFrame {
MultiLineCellExample() { super("Multi-Line Cell Example"); DefaultTableModel dm = new DefaultTableModel() { public Class getColumnClass(int columnIndex) { return String.class; } }; dm.setDataVector(new Object[][] { { "a\na", "b\nb", "c\nc" }, { "A\nA", "B\nB", "C\nC" } }, new Object[] { "1", "2", "3" }); JTable table = new JTable(dm); int lines = 2; table.setRowHeight(table.getRowHeight() * lines); // // table.setRowHeight(0); // // I got "java.lang.IllegalArgumentException: New row height less than // 1" // table.setDefaultRenderer(String.class, new MultiLineCellRenderer()); JScrollPane scroll = new JScrollPane(table); getContentPane().add(scroll); setSize(400, 130); setVisible(true); } public static void main(String[] args) { MultiLineCellExample frame = new MultiLineCellExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); }
} /**
* @version 1.0 11/09/98 */
class MultiLineCellRenderer extends JTextArea implements TableCellRenderer {
public MultiLineCellRenderer() { setLineWrap(true); setWrapStyleWord(true); setOpaque(true); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (isSelected) { setForeground(table.getSelectionForeground()); setBackground(table.getSelectionBackground()); } else { setForeground(table.getForeground()); setBackground(table.getBackground()); } setFont(table.getFont()); if (hasFocus) { setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); if (table.isCellEditable(row, column)) { setForeground(UIManager.getColor("Table.focusCellForeground")); setBackground(UIManager.getColor("Table.focusCellBackground")); } } else { setBorder(new EmptyBorder(1, 2, 1, 2)); } setText((value == null) ? "" : value.toString()); return this; }
}
</source>
MultiLine Header Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1beta3) */ import java.awt.ruponent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; import java.util.Enumeration; import java.util.Vector; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.ListCellRenderer; import javax.swing.UIManager; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; /**
* @version 1.0 11/09/98 */
public class MultiLineHeaderExample extends JFrame {
MultiLineHeaderExample() { super("Multi-Line Header Example"); DefaultTableModel dm = new DefaultTableModel(); dm.setDataVector( new Object[][] { { "a", "b", "c" }, { "A", "B", "C" } }, new Object[] { "1st\nalpha", "2nd\nbeta", "3rd\ngamma" }); JTable table = new JTable(dm); MultiLineHeaderRenderer renderer = new MultiLineHeaderRenderer(); Enumeration e = table.getColumnModel().getColumns(); while (e.hasMoreElements()) { ((TableColumn) e.nextElement()).setHeaderRenderer(renderer); } JScrollPane scroll = new JScrollPane(table); getContentPane().add(scroll); setSize(400, 110); setVisible(true); } public static void main(String[] args) { MultiLineHeaderExample frame = new MultiLineHeaderExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); }
} /**
* @version 1.0 11/09/98 */
class MultiLineHeaderRenderer extends JList implements TableCellRenderer {
public MultiLineHeaderRenderer() { setOpaque(true); setForeground(UIManager.getColor("TableHeader.foreground")); setBackground(UIManager.getColor("TableHeader.background")); setBorder(UIManager.getBorder("TableHeader.cellBorder")); ListCellRenderer renderer = getCellRenderer(); ((JLabel) renderer).setHorizontalAlignment(JLabel.CENTER); setCellRenderer(renderer); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { setFont(table.getFont()); String str = (value == null) ? "" : value.toString(); BufferedReader br = new BufferedReader(new StringReader(str)); String line; Vector v = new Vector(); try { while ((line = br.readLine()) != null) { v.addElement(line); } } catch (IOException ex) { ex.printStackTrace(); } setListData(v); return this; }
}
</source>
MultiLine Header Table
<source lang="java">
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall
- /
import java.awt.Color; import java.awt.ruponent; import java.awt.Font; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.text.NumberFormat; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; public class MultiLineHeaderTable {
public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception evt) {} JFrame f = new JFrame("Multi-line Header Table"); JTable tbl = new JTable(new CurrencyTableModel()); tbl.setDefaultRenderer(java.lang.Number.class, new FractionCellRenderer(10, 3, SwingConstants.RIGHT)); TableColumnModel tcm = tbl.getColumnModel(); tcm.getColumn(0).setPreferredWidth(150); tcm.getColumn(0).setMinWidth(150); TextWithIconCellRenderer renderer = new TextWithIconCellRenderer(); tcm.getColumn(0).setCellRenderer(renderer); tcm.getColumn(1).setPreferredWidth(100); tcm.getColumn(1).setMinWidth(100); // Add the stripe renderer. StripedTableCellRenderer.installInTable(tbl, Color.lightGray, Color.white, null, null); // Add the custom header renderer MultiLineHeaderRenderer headerRenderer = new MultiLineHeaderRenderer( SwingConstants.CENTER, SwingConstants.BOTTOM); headerRenderer.setBackground(Color.blue); headerRenderer.setForeground(Color.white); headerRenderer.setFont(new Font("Dialog", Font.BOLD, 12)); int columns = tableHeaders.length; for (int i = 0; i < columns; i++) { tcm.getColumn(i).setHeaderRenderer(headerRenderer); tcm.getColumn(i).setHeaderValue(tableHeaders[i]); } tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tbl.setPreferredScrollableViewportSize(tbl.getPreferredSize()); JScrollPane sp = new JScrollPane(tbl); f.getContentPane().add(sp, "Center"); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); f.setVisible(true); } // Header values. Note the table model provides // string column names that are the default header // values. public static Object[][] tableHeaders = new Object[][] { new String[] { "Currency" }, new String[] { "Yesterday"s", "Rate" }, new String[] { "Today"s", "Rate" }, new String[] { "Rate", "Change" } };
} class CurrencyTableModel extends AbstractTableModel {
protected String[] columnNames = { "Currency", "Yesterday", "Today", "Change" }; // Constructor: calculate currency change to create the last column public CurrencyTableModel() { for (int i = 0; i < data.length; i++) { data[i][DIFF_COLUMN] = new Double( ((Double) data[i][NEW_RATE_COLUMN]).doubleValue() - ((Double) data[i][OLD_RATE_COLUMN]).doubleValue()); } } // Implementation of TableModel interface public int getRowCount() { return data.length; } public int getColumnCount() { return COLUMN_COUNT; } public Object getValueAt(int row, int column) { return data[row][column]; } public Class getColumnClass(int column) { return (data[0][column]).getClass(); } public String getColumnName(int column) { return columnNames[column]; } protected static final int OLD_RATE_COLUMN = 1; protected static final int NEW_RATE_COLUMN = 2; protected static final int DIFF_COLUMN = 3; protected static final int COLUMN_COUNT = 4; protected static final Class thisClass = CurrencyTableModel.class; protected Object[][] data = new Object[][] { { new DataWithIcon("Belgian Franc", new ImageIcon(thisClass .getResource("belgium.gif"))), new Double(37.6460110), new Double(37.6508921), null }, { new DataWithIcon("British Pound", new ImageIcon(thisClass .getResource("gb.gif"))), new Double(0.6213051), new Double(0.6104102), null }, { new DataWithIcon("Canadian Dollar", new ImageIcon(thisClass .getResource("canada.gif"))), new Double(1.4651209), new Double(1.5011104), null }, { new DataWithIcon("French Franc", new ImageIcon(thisClass .getResource("france.gif"))), new Double(6.1060001), new Double(6.0100101), null }, { new DataWithIcon("Italian Lire", new ImageIcon(thisClass .getResource("italy.gif"))), new Double(1181.3668977), new Double(1182.104), null }, { new DataWithIcon("German Mark", new ImageIcon(thisClass .getResource("germany.gif"))), new Double(1.8191804), new Double(1.8223421), null }, { new DataWithIcon("Japanese Yen", new ImageIcon(thisClass .getResource("japan.gif"))), new Double(141.0815412), new Double(121.0040432), null } };
} class DataWithIcon {
public DataWithIcon(Object data, Icon icon) { this.data = data; this.icon = icon; } public Icon getIcon() { return icon; } public Object getData() { return data; } public String toString() { return data.toString(); } protected Icon icon; protected Object data;
} class StripedTableCellRenderer implements TableCellRenderer {
public StripedTableCellRenderer(TableCellRenderer targetRenderer, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { this.targetRenderer = targetRenderer; this.evenBack = evenBack; this.evenFore = evenFore; this.oddBack = oddBack; this.oddFore = oddFore; } // Implementation of TableCellRenderer interface public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { TableCellRenderer renderer = targetRenderer; if (renderer == null) { // Get default renderer from the table renderer = table.getDefaultRenderer(table.getColumnClass(column)); } // Let the real renderer create the component Component comp = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); // Now apply the stripe effect if (isSelected == false && hasFocus == false) { if ((row & 1) == 0) { comp.setBackground(evenBack != null ? evenBack : table .getBackground()); comp.setForeground(evenFore != null ? evenFore : table .getForeground()); } else { comp.setBackground(oddBack != null ? oddBack : table .getBackground()); comp.setForeground(oddFore != null ? oddFore : table .getForeground()); } } return comp; } // Convenience method to apply this renderer to single column public static void installInColumn(JTable table, int columnIndex, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { TableColumn tc = table.getColumnModel().getColumn(columnIndex); // Get the cell renderer for this column, if any TableCellRenderer targetRenderer = tc.getCellRenderer(); // Create a new StripedTableCellRenderer and install it tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } // Convenience method to apply this renderer to an entire table public static void installInTable(JTable table, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { StripedTableCellRenderer sharedInstance = null; int columns = table.getColumnCount(); for (int i = 0; i < columns; i++) { TableColumn tc = table.getColumnModel().getColumn(i); TableCellRenderer targetRenderer = tc.getCellRenderer(); if (targetRenderer != null) { // This column has a specific renderer tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } else { // This column uses a class renderer - use a shared renderer if (sharedInstance == null) { sharedInstance = new StripedTableCellRenderer(null, evenBack, evenFore, oddBack, oddFore); } tc.setCellRenderer(sharedInstance); } } } protected TableCellRenderer targetRenderer; protected Color evenBack; protected Color evenFore; protected Color oddBack; protected Color oddFore;
} class FractionCellRenderer extends DefaultTableCellRenderer {
public FractionCellRenderer(int integer, int fraction, int align) { this.integer = integer; // maximum integer digits this.fraction = fraction; // exact number of fraction digits this.align = align; // alignment (LEFT, CENTER, RIGHT) } protected void setValue(Object value) { if (value != null && value instanceof Number) { formatter.setMaximumIntegerDigits(integer); formatter.setMaximumFractionDigits(fraction); formatter.setMinimumFractionDigits(fraction); setText(formatter.format(((Number) value).doubleValue())); } else { super.setValue(value); } setHorizontalAlignment(align); } protected int integer; protected int fraction; protected int align; protected static NumberFormat formatter = NumberFormat.getInstance();
} class TextWithIconCellRenderer extends DefaultTableCellRenderer {
protected void setValue(Object value) { if (value instanceof DataWithIcon) { if (value != null) { DataWithIcon d = (DataWithIcon) value; Object dataValue = d.getData(); setText(dataValue == null ? "" : dataValue.toString()); setIcon(d.getIcon()); setHorizontalTextPosition(SwingConstants.RIGHT); setVerticalTextPosition(SwingConstants.CENTER); setHorizontalAlignment(SwingConstants.LEFT); setVerticalAlignment(SwingConstants.CENTER); } else { setText(""); setIcon(null); } } else { super.setValue(value); } }
} class MultiLineHeaderRenderer extends JPanel implements TableCellRenderer {
public MultiLineHeaderRenderer(int horizontalAlignment, int verticalAlignment) { this.horizontalAlignment = horizontalAlignment; this.verticalAlignment = verticalAlignment; switch (horizontalAlignment) { case SwingConstants.LEFT: alignmentX = (float) 0.0; break; case SwingConstants.CENTER: alignmentX = (float) 0.5; break; case SwingConstants.RIGHT: alignmentX = (float) 1.0; break; default: throw new IllegalArgumentException( "Illegal horizontal alignment value"); } setBorder(headerBorder); setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); setOpaque(true); background = null; } public void setForeground(Color foreground) { this.foreground = foreground; super.setForeground(foreground); } public void setBackground(Color background) { this.background = background; super.setBackground(background); } public void setFont(Font font) { this.font = font; } // Implementation of TableCellRenderer interface public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { removeAll(); invalidate(); if (value == null) { // Do nothing if no value return this; } // Set the foreground and background colors // from the table header if they are not set if (table != null) { JTableHeader header = table.getTableHeader(); if (header != null) { if (foreground == null) { super.setForeground(header.getForeground()); } if (background == null) { super.setBackground(header.getBackground()); } } } if (verticalAlignment != SwingConstants.TOP) { add(Box.createVerticalGlue()); } Object[] values; int length; if (value instanceof Object[]) { // Input is an array - use it values = (Object[]) value; } else { // Not an array - turn it into one values = new Object[1]; values[0] = value; } length = values.length; // Configure each row of the header using // a separate JLabel. If a given row is // a JComponent, add it directly.. for (int i = 0; i < length; i++) { Object thisRow = values[i]; if (thisRow instanceof JComponent) { add((JComponent) thisRow); } else { JLabel l = new JLabel(); setValue(l, thisRow, i); add(l); } } if (verticalAlignment != SwingConstants.BOTTOM) { add(Box.createVerticalGlue()); } return this; } // Configures a label for one line of the header. // This can be overridden by derived classes protected void setValue(JLabel l, Object value, int lineNumber) { if (value != null && value instanceof Icon) { l.setIcon((Icon) value); } else { l.setText(value == null ? "" : value.toString()); } l.setHorizontalAlignment(horizontalAlignment); l.setAlignmentX(alignmentX); l.setOpaque(false); l.setForeground(foreground); l.setFont(font); } protected int verticalAlignment; protected int horizontalAlignment; protected float alignmentX; // These attributes may be explicitly set // They are defaulted to the colors and attributes // of the table header protected Color foreground; protected Color background; // These attributes have fixed defaults protected Border headerBorder = UIManager .getBorder("TableHeader.cellBorder"); protected Font font = UIManager.getFont("TableHeader.font");
}
</source>
MultiLine Table
<source lang="java">
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall
- /
import java.awt.Color; import java.awt.ruponent; import java.awt.Font; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.table.AbstractTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; public class MultiLineTable {
public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception evt) {} JFrame f = new JFrame("Multi-line Cell Table"); JTable tbl = new JTable(new MultiLineTableModel()); // Create the custom cell renderer MultiLineCellRenderer multiLineRenderer = new MultiLineCellRenderer( SwingConstants.LEFT, SwingConstants.CENTER); TableColumnModel tcm = tbl.getColumnModel(); tcm.getColumn(0).setPreferredWidth(75); tcm.getColumn(0).setMinWidth(75); tcm.getColumn(1).setPreferredWidth(150); tcm.getColumn(1).setMinWidth(150); // Install the multi-line renderer tcm.getColumn(0).setCellRenderer(multiLineRenderer); tcm.getColumn(1).setCellRenderer(multiLineRenderer); // Set the table row height tbl.setRowHeight(56); // Add the stripe renderer. StripedTableCellRenderer.installInTable(tbl, Color.lightGray, Color.white, null, null); tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tbl.setPreferredScrollableViewportSize(tbl.getPreferredSize()); JScrollPane sp = new JScrollPane(tbl); f.getContentPane().add(sp, "Center"); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); f.setVisible(true); }
} class MultiLineTableModel extends AbstractTableModel {
protected String[] columnNames = { "Flight", "Crew" }; // Implementation of TableModel interface public int getRowCount() { return data.length; } public int getColumnCount() { return 2; } public Object getValueAt(int row, int column) { return data[row][column]; } public Class getColumnClass(int column) { return (data[0][column]).getClass(); } public String getColumnName(int column) { return columnNames[column]; } protected Object[][] data = new Object[][] { { "Apollo 11", new String[] { "Neil Armstrong", "Buzz Aldrin", "Michael Collins" } }, { "Apollo 12", new String[] { "Pete Conrad", "Alan Bean", "Richard Gordon" } }, { "Apollo 13", new String[] { "James Lovell", "Fred Haise", "Jack Swigert" } }, { "Apollo 14", new String[] { "Alan Shepard", "Edgar Mitchell", "Stuart Roosa" } }, { "Apollo 15", new String[] { "Dave Scott", "Jim Irwin", "Al Worden" } }, { "Apollo 16", new String[] { "John Young", "Charlie Duke", "Ken Mattingly" } }, { "Apollo 17", new String[] { "Eugene Cernan", "Harrison Schmitt", "Ron Evans" } } };
} class MultiLineCellRenderer extends JPanel implements TableCellRenderer {
public MultiLineCellRenderer(int horizontalAlignment, int verticalAlignment) { this.horizontalAlignment = horizontalAlignment; this.verticalAlignment = verticalAlignment; switch (horizontalAlignment) { case SwingConstants.LEFT: alignmentX = (float) 0.0; break; case SwingConstants.CENTER: alignmentX = (float) 0.5; break; case SwingConstants.RIGHT: alignmentX = (float) 1.0; break; default: throw new IllegalArgumentException( "Illegal horizontal alignment value"); } setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); setOpaque(true); setBorder(border); background = null; foreground = null; } public void setForeground(Color foreground) { super.setForeground(foreground); Component[] comps = this.getComponents(); int ncomp = comps.length; for (int i = 0; i < ncomp; i++) { Component comp = comps[i]; if (comp instanceof JLabel) { comp.setForeground(foreground); } } } public void setBackground(Color background) { this.background = background; super.setBackground(background); } public void setFont(Font font) { this.font = font; } // Implementation of TableCellRenderer interface public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { removeAll(); invalidate(); if (value == null || table == null) { // Do nothing if no value return this; } Color cellForeground; Color cellBackground; // Set the foreground and background colors // from the table if they are not set cellForeground = (foreground == null ? table.getForeground() : foreground); cellBackground = (background == null ? table.getBackground() : background); // Handle selection and focus colors if (isSelected == true) { cellForeground = table.getSelectionForeground(); cellBackground = table.getSelectionBackground(); } if (hasFocus == true) { setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); if (table.isCellEditable(row, column)) { cellForeground = UIManager .getColor("Table.focusCellForeground"); cellBackground = UIManager .getColor("Table.focusCellBackground"); } } else { setBorder(border); } super.setForeground(cellForeground); super.setBackground(cellBackground); // Default the font from the table if (font == null) { font = table.getFont(); } if (verticalAlignment != SwingConstants.TOP) { add(Box.createVerticalGlue()); } Object[] values; int length; if (value instanceof Object[]) { // Input is an array - use it values = (Object[]) value; } else { // Not an array - turn it into one values = new Object[1]; values[0] = value; } length = values.length; // Configure each row of the cell using // a separate JLabel. If a given row is // a JComponent, add it directly.. for (int i = 0; i < length; i++) { Object thisRow = values[i]; if (thisRow instanceof JComponent) { add((JComponent) thisRow); } else { JLabel l = new JLabel(); setValue(l, thisRow, i, cellForeground); add(l); } } if (verticalAlignment != SwingConstants.BOTTOM) { add(Box.createVerticalGlue()); } return this; } // Configures a label for one line of the cell. // This can be overridden by derived classes protected void setValue(JLabel l, Object value, int lineNumber, Color cellForeground) { if (value != null && value instanceof Icon) { l.setIcon((Icon) value); } else { l.setText(value == null ? "" : value.toString()); } l.setHorizontalAlignment(horizontalAlignment); l.setAlignmentX(alignmentX); l.setOpaque(false); l.setForeground(cellForeground); l.setFont(font); } protected int verticalAlignment; protected int horizontalAlignment; protected float alignmentX; // These attributes may be explicitly set // They are defaulted to the colors and attributes // of the table protected Color foreground; protected Color background; protected Font font; protected static Border border = new EmptyBorder(1, 2, 1, 2);
} class StripedTableCellRenderer implements TableCellRenderer {
public StripedTableCellRenderer(TableCellRenderer targetRenderer, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { this.targetRenderer = targetRenderer; this.evenBack = evenBack; this.evenFore = evenFore; this.oddBack = oddBack; this.oddFore = oddFore; } // Implementation of TableCellRenderer interface public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { TableCellRenderer renderer = targetRenderer; if (renderer == null) { // Get default renderer from the table renderer = table.getDefaultRenderer(table.getColumnClass(column)); } // Let the real renderer create the component Component comp = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); // Now apply the stripe effect if (isSelected == false && hasFocus == false) { if ((row & 1) == 0) { comp.setBackground(evenBack != null ? evenBack : table .getBackground()); comp.setForeground(evenFore != null ? evenFore : table .getForeground()); } else { comp.setBackground(oddBack != null ? oddBack : table .getBackground()); comp.setForeground(oddFore != null ? oddFore : table .getForeground()); } } return comp; } // Convenience method to apply this renderer to single column public static void installInColumn(JTable table, int columnIndex, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { TableColumn tc = table.getColumnModel().getColumn(columnIndex); // Get the cell renderer for this column, if any TableCellRenderer targetRenderer = tc.getCellRenderer(); // Create a new StripedTableCellRenderer and install it tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } // Convenience method to apply this renderer to an entire table public static void installInTable(JTable table, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { StripedTableCellRenderer sharedInstance = null; int columns = table.getColumnCount(); for (int i = 0; i < columns; i++) { TableColumn tc = table.getColumnModel().getColumn(i); TableCellRenderer targetRenderer = tc.getCellRenderer(); if (targetRenderer != null) { // This column has a specific renderer tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } else { // This column uses a class renderer - use a shared renderer if (sharedInstance == null) { sharedInstance = new StripedTableCellRenderer(null, evenBack, evenFore, oddBack, oddFore); } tc.setCellRenderer(sharedInstance); } } } protected TableCellRenderer targetRenderer; protected Color evenBack; protected Color evenFore; protected Color oddBack; protected Color oddFore;
}
</source>
multiple Component Table 2: checkbox
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1beta3) */
import java.awt.ruponent; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.EventObject; import java.util.Hashtable; import javax.swing.DefaultCellEditor; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.UIManager; import javax.swing.event.CellEditorListener; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; /**
* @version 1.0 11/09/98 */
class CheckBoxRenderer extends JCheckBox implements TableCellRenderer {
CheckBoxRenderer() { setHorizontalAlignment(JLabel.CENTER); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (isSelected) { setForeground(table.getSelectionForeground()); //super.setBackground(table.getSelectionBackground()); setBackground(table.getSelectionBackground()); } else { setForeground(table.getForeground()); setBackground(table.getBackground()); } setSelected((value != null && ((Boolean) value).booleanValue())); return this; }
} public class MultiComponentTable2 extends JFrame {
public MultiComponentTable2() { super("MultiComponent Table"); DefaultTableModel dm = new DefaultTableModel() { public boolean isCellEditable(int row, int column) { if (column == 0) { return true; } return false; } }; dm.setDataVector(new Object[][] { { "true", "String", "JLabel", "JComboBox" }, { "false", "String", "JLabel", "JComboBox" }, { new Boolean(true), "Boolean", "JCheckBox", "JCheckBox" }, { new Boolean(false), "Boolean", "JCheckBox", "JCheckBox" }, { "true", "String", "JLabel", "JTextField" }, { "false", "String", "JLabel", "JTextField" } }, new Object[] { "Component", "Data", "Renderer", "Editor" }); CheckBoxRenderer checkBoxRenderer = new CheckBoxRenderer(); EachRowRenderer rowRenderer = new EachRowRenderer(); rowRenderer.add(2, checkBoxRenderer); rowRenderer.add(3, checkBoxRenderer); JComboBox comboBox = new JComboBox(); comboBox.addItem("true"); comboBox.addItem("false"); JCheckBox checkBox = new JCheckBox(); checkBox.setHorizontalAlignment(JLabel.CENTER); DefaultCellEditor comboBoxEditor = new DefaultCellEditor(comboBox); DefaultCellEditor checkBoxEditor = new DefaultCellEditor(checkBox); JTable table = new JTable(dm);
// modified by jexp.ru
EachRowEditor rowEditor = new EachRowEditor(table); rowEditor.setEditorAt(0, comboBoxEditor); rowEditor.setEditorAt(1, comboBoxEditor); rowEditor.setEditorAt(2, checkBoxEditor); rowEditor.setEditorAt(3, checkBoxEditor);
// end
table.getColumn("Component").setCellRenderer(rowRenderer); table.getColumn("Component").setCellEditor(rowEditor); JScrollPane scroll = new JScrollPane(table); getContentPane().add(scroll); setSize(400, 160); setVisible(true); } public static void main(String[] args) { MultiComponentTable2 frame = new MultiComponentTable2(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); }
} /**
* @version 1.0 11/09/98 */
class EachRowRenderer implements TableCellRenderer {
protected Hashtable renderers; protected TableCellRenderer renderer, defaultRenderer; public EachRowRenderer() { renderers = new Hashtable(); defaultRenderer = new DefaultTableCellRenderer(); } public void add(int row, TableCellRenderer renderer) { renderers.put(new Integer(row), renderer); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { renderer = (TableCellRenderer) renderers.get(new Integer(row)); if (renderer == null) { renderer = defaultRenderer; } return renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); }
} /**
* each row TableCellEditor * * @version 1.1 09/09/99 * @author Nobuo Tamemasa */
class EachRowEditor implements TableCellEditor {
protected Hashtable editors; protected TableCellEditor editor, defaultEditor; JTable table; /** * Constructs a EachRowEditor. create default editor * * @see TableCellEditor * @see DefaultCellEditor */ public EachRowEditor(JTable table) { this.table = table; editors = new Hashtable(); defaultEditor = new DefaultCellEditor(new JTextField()); } /** * @param row * table row * @param editor * table cell editor */ public void setEditorAt(int row, TableCellEditor editor) { editors.put(new Integer(row), editor); } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { //editor = (TableCellEditor)editors.get(new Integer(row)); //if (editor == null) { // editor = defaultEditor; //} return editor.getTableCellEditorComponent(table, value, isSelected, row, column); } public Object getCellEditorValue() { return editor.getCellEditorValue(); } public boolean stopCellEditing() { return editor.stopCellEditing(); } public void cancelCellEditing() { editor.cancelCellEditing(); } public boolean isCellEditable(EventObject anEvent) { selectEditor((MouseEvent) anEvent); return editor.isCellEditable(anEvent); } public void addCellEditorListener(CellEditorListener l) { editor.addCellEditorListener(l); } public void removeCellEditorListener(CellEditorListener l) { editor.removeCellEditorListener(l); } public boolean shouldSelectCell(EventObject anEvent) { selectEditor((MouseEvent) anEvent); return editor.shouldSelectCell(anEvent); } protected void selectEditor(MouseEvent e) { int row; if (e == null) { row = table.getSelectionModel().getAnchorSelectionIndex(); } else { row = table.rowAtPoint(e.getPoint()); } editor = (TableCellEditor) editors.get(new Integer(row)); if (editor == null) { editor = defaultEditor; } }
}
</source>
Multiple Component Table: Checkbox and Combobox
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1beta3) */
import java.awt.ruponent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.EventObject; import javax.swing.DefaultCellEditor; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.UIManager; import javax.swing.event.CellEditorListener; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellEditor; /**
* @version 1.0 11/09/98 */
class ComboString {
String str; ComboString(String str) { this.str = str; } public String toString() { return str; }
} class MultiRenderer extends DefaultTableCellRenderer {
JCheckBox checkBox = new JCheckBox(); public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (value instanceof Boolean) { // Boolean checkBox.setSelected(((Boolean) value).booleanValue()); checkBox.setHorizontalAlignment(JLabel.CENTER); return checkBox; } String str = (value == null) ? "" : value.toString(); return super.getTableCellRendererComponent(table, str, isSelected, hasFocus, row, column); }
} class MultiEditor implements TableCellEditor {
private final static int COMBO = 0; private final static int BOOLEAN = 1; private final static int STRING = 2; private final static int NUM_EDITOR = 3; DefaultCellEditor[] cellEditors; JComboBox comboBox; int flg; public MultiEditor() { cellEditors = new DefaultCellEditor[NUM_EDITOR]; comboBox = new JComboBox(); comboBox.addItem("true"); comboBox.addItem("false"); cellEditors[COMBO] = new DefaultCellEditor(comboBox); JCheckBox checkBox = new JCheckBox(); //checkBox.setOpaque( true ); checkBox.setHorizontalAlignment(JLabel.CENTER); cellEditors[BOOLEAN] = new DefaultCellEditor(checkBox); JTextField textField = new JTextField(); cellEditors[STRING] = new DefaultCellEditor(textField); flg = NUM_EDITOR; // nobody } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { if (value instanceof ComboString) { // ComboString flg = COMBO; String str = (value == null) ? "" : value.toString(); return cellEditors[COMBO].getTableCellEditorComponent(table, str, isSelected, row, column); } else if (value instanceof Boolean) { // Boolean flg = BOOLEAN; return cellEditors[BOOLEAN].getTableCellEditorComponent(table, value, isSelected, row, column); } else if (value instanceof String) { // String flg = STRING; return cellEditors[STRING].getTableCellEditorComponent(table, value, isSelected, row, column); } return null; } public Object getCellEditorValue() { switch (flg) { case COMBO: String str = (String) comboBox.getSelectedItem(); return new ComboString(str); case BOOLEAN: case STRING: return cellEditors[flg].getCellEditorValue(); default: return null; } } public Component getComponent() { return cellEditors[flg].getComponent(); } public boolean stopCellEditing() { return cellEditors[flg].stopCellEditing(); } public void cancelCellEditing() { cellEditors[flg].cancelCellEditing(); } public boolean isCellEditable(EventObject anEvent) { return cellEditors[flg].isCellEditable(anEvent); } public boolean shouldSelectCell(EventObject anEvent) { return cellEditors[flg].shouldSelectCell(anEvent); } public void addCellEditorListener(CellEditorListener l) { cellEditors[flg].addCellEditorListener(l); } public void removeCellEditorListener(CellEditorListener l) { cellEditors[flg].removeCellEditorListener(l); } public void setClickCountToStart(int n) { cellEditors[flg].setClickCountToStart(n); } public int getClickCountToStart() { return cellEditors[flg].getClickCountToStart(); }
} public class MultiComponentTable extends JFrame {
public MultiComponentTable() { super("MultiComponent Table"); DefaultTableModel dm = new DefaultTableModel() { public boolean isCellEditable(int row, int column) { if (column == 0) { return true; } return false; } }; dm.setDataVector( new Object[][] { { new ComboString("true"), "ComboString", "JLabel", "JComboBox" }, { new ComboString("false"), "ComboString", "JLabel", "JComboBox" }, { new Boolean(true), "Boolean", "JCheckBox", "JCheckBox" }, { new Boolean(false), "Boolean", "JCheckBox", "JCheckBox" }, { "true", "String", "JLabel", "JTextField" }, { "false", "String", "JLabel", "JTextField" } }, new Object[] { "Component", "Data", "Renderer", "Editor" }); JTable table = new JTable(dm); table.getColumn("Component").setCellRenderer(new MultiRenderer()); table.getColumn("Component").setCellEditor(new MultiEditor()); JScrollPane scroll = new JScrollPane(table); getContentPane().add(scroll); setSize(400, 160); setVisible(true); } public static void main(String[] args) { MultiComponentTable frame = new MultiComponentTable(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); }
}
</source>
multiple Font Cell Table Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html import java.awt.BorderLayout; import java.awt.Color; import java.awt.ruponent; import java.awt.Container; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; import java.awt.GridLayout; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Enumeration; import java.util.Vector; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JColorChooser; import javax.swing.JComboBox; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.event.TableModelEvent; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableModel; /**
* @version 1.0 11/22/98 */
public class MultiFontCellTableExample extends JFrame {
public MultiFontCellTableExample() { super("Multi-Font Cell Example"); AttributiveCellTableModel ml = new AttributiveCellTableModel(8, 3); CellFont cellAtt = (CellFont) ml.getCellAttribute(); JTable table = new JTable(ml); table.setRowHeight(26); table.setCellSelectionEnabled(true); table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); table.setDefaultRenderer(Object.class, new AttributiveCellRenderer()); JScrollPane scroll = new JScrollPane(table); FontPanel fontPanel = new FontPanel(table, cellAtt); Box box = new Box(BoxLayout.X_AXIS); box.add(scroll); box.add(new JSeparator(SwingConstants.HORIZONTAL)); box.add(fontPanel); getContentPane().add(box); setSize(400, 200); setVisible(true); } class FontPanel extends JPanel { String[] str_size = { "10", "12", "14", "16", "20", "24" }; String[] str_style = { "PLAIN", "BOLD", "ITALIC" }; JComboBox name, style, size; FontPanel(final JTable table, final CellFont cellAtt) { setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); Box box = new Box(BoxLayout.X_AXIS); JPanel p2 = new JPanel(new GridLayout(3, 1)); JPanel p3 = new JPanel(new GridLayout(3, 1)); JPanel p4 = new JPanel(new FlowLayout()); p2.add(new JLabel("Name:")); p2.add(new JLabel("Style:")); p2.add(new JLabel("Size:")); Toolkit toolkit = Toolkit.getDefaultToolkit(); name = new JComboBox(toolkit.getFontList()); style = new JComboBox(str_style); size = new JComboBox(str_size); size.setEditable(true); JButton b_apply = new JButton("Apply"); b_apply.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int[] columns = table.getSelectedColumns(); int[] rows = table.getSelectedRows(); if ((rows == null) || (columns == null)) return; if ((rows.length < 1) || (columns.length < 1)) return; Font font = new Font((String) name.getSelectedItem(), style .getSelectedIndex(), Integer.parseInt((String) size .getSelectedItem())); cellAtt.setFont(font, rows, columns); table.clearSelection(); table.revalidate(); table.repaint(); } }); p3.add(name); p3.add(style); p3.add(size); p4.add(b_apply); box.add(p2); box.add(p3); add(box); add(p4); } } public static void main(String[] args) { MultiFontCellTableExample frame = new MultiFontCellTableExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); }
} /**
* @version 1.0 11/22/98 */
class AttributiveCellTableModel extends DefaultTableModel {
protected CellAttribute cellAtt; public AttributiveCellTableModel() { this((Vector) null, 0); } public AttributiveCellTableModel(int numRows, int numColumns) { Vector names = new Vector(numColumns); names.setSize(numColumns); setColumnIdentifiers(names); dataVector = new Vector(); setNumRows(numRows); cellAtt = new DefaultCellAttribute(numRows, numColumns); } public AttributiveCellTableModel(Vector columnNames, int numRows) { setColumnIdentifiers(columnNames); dataVector = new Vector(); setNumRows(numRows); cellAtt = new DefaultCellAttribute(numRows, columnNames.size()); } public AttributiveCellTableModel(Object[] columnNames, int numRows) { this(convertToVector(columnNames), numRows); } public AttributiveCellTableModel(Vector data, Vector columnNames) { setDataVector(data, columnNames); } public AttributiveCellTableModel(Object[][] data, Object[] columnNames) { setDataVector(data, columnNames); } public void setDataVector(Vector newData, Vector columnNames) { if (newData == null) throw new IllegalArgumentException( "setDataVector() - Null parameter"); dataVector = new Vector(0); setColumnIdentifiers(columnNames); dataVector = newData; // cellAtt = new DefaultCellAttribute(dataVector.size(), columnIdentifiers .size()); newRowsAdded(new TableModelEvent(this, 0, getRowCount() - 1, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } public void addColumn(Object columnName, Vector columnData) { if (columnName == null) throw new IllegalArgumentException("addColumn() - null parameter"); columnIdentifiers.addElement(columnName); int index = 0; Enumeration eeration = dataVector.elements(); while (eeration.hasMoreElements()) { Object value; if ((columnData != null) && (index < columnData.size())) value = columnData.elementAt(index); else value = null; ((Vector) eeration.nextElement()).addElement(value); index++; } // cellAtt.addColumn(); fireTableStructureChanged(); } public void addRow(Vector rowData) { Vector newData = null; if (rowData == null) { newData = new Vector(getColumnCount()); } else { rowData.setSize(getColumnCount()); } dataVector.addElement(newData); // cellAtt.addRow(); newRowsAdded(new TableModelEvent(this, getRowCount() - 1, getRowCount() - 1, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } public void insertRow(int row, Vector rowData) { if (rowData == null) { rowData = new Vector(getColumnCount()); } else { rowData.setSize(getColumnCount()); } dataVector.insertElementAt(rowData, row); // cellAtt.insertRow(row); newRowsAdded(new TableModelEvent(this, row, row, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } public CellAttribute getCellAttribute() { return cellAtt; } public void setCellAttribute(CellAttribute newCellAtt) { int numColumns = getColumnCount(); int numRows = getRowCount(); if ((newCellAtt.getSize().width != numColumns) || (newCellAtt.getSize().height != numRows)) { newCellAtt.setSize(new Dimension(numRows, numColumns)); } cellAtt = newCellAtt; fireTableDataChanged(); } /* * public void changeCellAttribute(int row, int column, Object command) { * cellAtt.changeAttribute(row, column, command); } * * public void changeCellAttribute(int[] rows, int[] columns, Object * command) { cellAtt.changeAttribute(rows, columns, command); } */
} /**
* @version 1.0 11/22/98 */
class DefaultCellAttribute // implements CellAttribute ,CellSpan {
implements CellAttribute, CellSpan, ColoredCell, CellFont { // // !!!! CAUTION !!!!! // these values must be synchronized to Table data // protected int rowSize; protected int columnSize; protected int[][][] span; // CellSpan protected Color[][] foreground; // ColoredCell protected Color[][] background; // protected Font[][] font; // CellFont public DefaultCellAttribute() { this(1, 1); } public DefaultCellAttribute(int numRows, int numColumns) { setSize(new Dimension(numColumns, numRows)); } protected void initValue() { for (int i = 0; i < span.length; i++) { for (int j = 0; j < span[i].length; j++) { span[i][j][CellSpan.COLUMN] = 1; span[i][j][CellSpan.ROW] = 1; } } } // // CellSpan // public int[] getSpan(int row, int column) { if (isOutOfBounds(row, column)) { int[] ret_code = { 1, 1 }; return ret_code; } return span[row][column]; } public void setSpan(int[] span, int row, int column) { if (isOutOfBounds(row, column)) return; this.span[row][column] = span; } public boolean isVisible(int row, int column) { if (isOutOfBounds(row, column)) return false; if ((span[row][column][CellSpan.COLUMN] < 1) || (span[row][column][CellSpan.ROW] < 1)) return false; return true; } public void combine(int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; int rowSpan = rows.length; int columnSpan = columns.length; int startRow = rows[0]; int startColumn = columns[0]; for (int i = 0; i < rowSpan; i++) { for (int j = 0; j < columnSpan; j++) { if ((span[startRow + i][startColumn + j][CellSpan.COLUMN] != 1) || (span[startRow + i][startColumn + j][CellSpan.ROW] != 1)) { //System.out.println("can"t combine"); return; } } } for (int i = 0, ii = 0; i < rowSpan; i++, ii--) { for (int j = 0, jj = 0; j < columnSpan; j++, jj--) { span[startRow + i][startColumn + j][CellSpan.COLUMN] = jj; span[startRow + i][startColumn + j][CellSpan.ROW] = ii; //System.out.println("r " +ii +" c " +jj); } } span[startRow][startColumn][CellSpan.COLUMN] = columnSpan; span[startRow][startColumn][CellSpan.ROW] = rowSpan; } public void split(int row, int column) { if (isOutOfBounds(row, column)) return; int columnSpan = span[row][column][CellSpan.COLUMN]; int rowSpan = span[row][column][CellSpan.ROW]; for (int i = 0; i < rowSpan; i++) { for (int j = 0; j < columnSpan; j++) { span[row + i][column + j][CellSpan.COLUMN] = 1; span[row + i][column + j][CellSpan.ROW] = 1; } } } // // ColoredCell // public Color getForeground(int row, int column) { if (isOutOfBounds(row, column)) return null; return foreground[row][column]; } public void setForeground(Color color, int row, int column) { if (isOutOfBounds(row, column)) return; foreground[row][column] = color; } public void setForeground(Color color, int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; setValues(foreground, color, rows, columns); } public Color getBackground(int row, int column) { if (isOutOfBounds(row, column)) return null; return background[row][column]; } public void setBackground(Color color, int row, int column) { if (isOutOfBounds(row, column)) return; background[row][column] = color; } public void setBackground(Color color, int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; setValues(background, color, rows, columns); } // // // CellFont // public Font getFont(int row, int column) { if (isOutOfBounds(row, column)) return null; return font[row][column]; } public void setFont(Font font, int row, int column) { if (isOutOfBounds(row, column)) return; this.font[row][column] = font; } public void setFont(Font font, int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; setValues(this.font, font, rows, columns); } // // // CellAttribute // public void addColumn() { int[][][] oldSpan = span; int numRows = oldSpan.length; int numColumns = oldSpan[0].length; span = new int[numRows][numColumns + 1][2]; System.arraycopy(oldSpan, 0, span, 0, numRows); for (int i = 0; i < numRows; i++) { span[i][numColumns][CellSpan.COLUMN] = 1; span[i][numColumns][CellSpan.ROW] = 1; } } public void addRow() { int[][][] oldSpan = span; int numRows = oldSpan.length; int numColumns = oldSpan[0].length; span = new int[numRows + 1][numColumns][2]; System.arraycopy(oldSpan, 0, span, 0, numRows); for (int i = 0; i < numColumns; i++) { span[numRows][i][CellSpan.COLUMN] = 1; span[numRows][i][CellSpan.ROW] = 1; } } public void insertRow(int row) { int[][][] oldSpan = span; int numRows = oldSpan.length; int numColumns = oldSpan[0].length; span = new int[numRows + 1][numColumns][2]; if (0 < row) { System.arraycopy(oldSpan, 0, span, 0, row - 1); } System.arraycopy(oldSpan, 0, span, row, numRows - row); for (int i = 0; i < numColumns; i++) { span[row][i][CellSpan.COLUMN] = 1; span[row][i][CellSpan.ROW] = 1; } } public Dimension getSize() { return new Dimension(rowSize, columnSize); } public void setSize(Dimension size) { columnSize = size.width; rowSize = size.height; span = new int[rowSize][columnSize][2]; // 2: COLUMN,ROW foreground = new Color[rowSize][columnSize]; background = new Color[rowSize][columnSize]; font = new Font[rowSize][columnSize]; initValue(); } /* * public void changeAttribute(int row, int column, Object command) { } * * public void changeAttribute(int[] rows, int[] columns, Object command) { } */ protected boolean isOutOfBounds(int row, int column) { if ((row < 0) || (rowSize <= row) || (column < 0) || (columnSize <= column)) { return true; } return false; } protected boolean isOutOfBounds(int[] rows, int[] columns) { for (int i = 0; i < rows.length; i++) { if ((rows[i] < 0) || (rowSize <= rows[i])) return true; } for (int i = 0; i < columns.length; i++) { if ((columns[i] < 0) || (columnSize <= columns[i])) return true; } return false; } protected void setValues(Object[][] target, Object value, int[] rows, int[] columns) { for (int i = 0; i < rows.length; i++) { int row = rows[i]; for (int j = 0; j < columns.length; j++) { int column = columns[j]; target[row][column] = value; } } }
} /**
* @version 1.0 11/22/98 */
/*
* (swing1.1beta3) * */
/**
* @version 1.0 11/22/98 */
interface CellAttribute {
public void addColumn(); public void addRow(); public void insertRow(int row); public Dimension getSize(); public void setSize(Dimension size);
} interface ColoredCell {
public Color getForeground(int row, int column); public void setForeground(Color color, int row, int column); public void setForeground(Color color, int[] rows, int[] columns); public Color getBackground(int row, int column); public void setBackground(Color color, int row, int column); public void setBackground(Color color, int[] rows, int[] columns);
} /**
* @version 1.0 11/22/98 */
class AttributiveCellRenderer extends JLabel implements TableCellRenderer {
protected static Border noFocusBorder; public AttributiveCellRenderer() { noFocusBorder = new EmptyBorder(1, 2, 1, 2); setOpaque(true); setBorder(noFocusBorder); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Color foreground = null; Color background = null; Font font = null; TableModel model = table.getModel(); if (model instanceof AttributiveCellTableModel) { CellAttribute cellAtt = ((AttributiveCellTableModel) model) .getCellAttribute(); if (cellAtt instanceof ColoredCell) { foreground = ((ColoredCell) cellAtt).getForeground(row, column); background = ((ColoredCell) cellAtt).getBackground(row, column); } if (cellAtt instanceof CellFont) { font = ((CellFont) cellAtt).getFont(row, column); } } if (isSelected) { setForeground((foreground != null) ? foreground : table .getSelectionForeground()); setBackground(table.getSelectionBackground()); } else { setForeground((foreground != null) ? foreground : table .getForeground()); setBackground((background != null) ? background : table .getBackground()); } setFont((font != null) ? font : table.getFont()); if (hasFocus) { setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); if (table.isCellEditable(row, column)) { setForeground((foreground != null) ? foreground : UIManager .getColor("Table.focusCellForeground")); setBackground(UIManager.getColor("Table.focusCellBackground")); } } else { setBorder(noFocusBorder); } setValue(value); return this; } protected void setValue(Object value) { setText((value == null) ? "" : value.toString()); }
} /**
* @version 1.0 11/22/98 */
class TextPreviewLabel extends JLabel {
private String sampleText = " Sample Text Sample Text "; boolean isForgroundSelection; public TextPreviewLabel() { this(Color.black, Color.white, true); } public TextPreviewLabel(Color fore, Color back, boolean isForgroundSelection) { setOpaque(true); setForeground(fore); setBackground(back); this.isForgroundSelection = isForgroundSelection; setText(sampleText); } public void setForeground(Color col) { if (isForgroundSelection) { super.setForeground(col); } else { super.setBackground(col); } }
} class ColorChooserDialog extends JDialog {
private Color initialColor; private Color retColor; private JColorChooser chooserPane; public ColorChooserDialog(Component c, String title, final JColorChooser chooserPane) { super(JOptionPane.getFrameForComponent(c), title, true); setResizable(false); this.chooserPane = chooserPane; String okString = UIManager.getString("ColorChooser.okText"); String cancelString = UIManager.getString("ColorChooser.cancelText"); String resetString = UIManager.getString("ColorChooser.resetText"); Container contentPane = getContentPane(); contentPane.setLayout(new BorderLayout()); contentPane.add(chooserPane, BorderLayout.CENTER); JPanel buttonPane = new JPanel(); buttonPane.setLayout(new FlowLayout(FlowLayout.CENTER)); JButton okButton = new JButton(okString); getRootPane().setDefaultButton(okButton); okButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { retColor = chooserPane.getColor(); setVisible(false); } }); buttonPane.add(okButton); JButton cancelButton = new JButton(cancelString); cancelButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { retColor = null; setVisible(false); } }); buttonPane.add(cancelButton); JButton resetButton = new JButton(resetString); resetButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { chooserPane.setColor(initialColor); } }); buttonPane.add(resetButton); contentPane.add(buttonPane, BorderLayout.SOUTH); pack(); setLocationRelativeTo(c); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { setVisible(false); } }); } public Color getColor() { return retColor; }
} class TextColorChooser extends JColorChooser {
public TextColorChooser(Color target, Color reference, boolean isForgroundSelection) { super(target); if (isForgroundSelection) { setPreviewPanel(new TextPreviewLabel(target, reference, isForgroundSelection)); } else { setPreviewPanel(new TextPreviewLabel(reference, target, isForgroundSelection)); } updateUI(); } public Color showDialog(Component component, String title) { ColorChooserDialog dialog = new ColorChooserDialog(component, title, this); dialog.show(); Color col = dialog.getColor(); dialog.dispose(); return col; }
} interface CellFont {
public Font getFont(int row, int column); public void setFont(Font font, int row, int column); public void setFont(Font font, int[] rows, int[] columns);
} interface CellSpan {
public final int ROW = 0; public final int COLUMN = 1; public int[] getSpan(int row, int column); public void setSpan(int[] span, int row, int column); public boolean isVisible(int row, int column); public void combine(int[] rows, int[] columns); public void split(int row, int column);
}
</source>
multiple Row Header Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1) (swing#1356,#1454) */ import java.awt.BorderLayout; import java.awt.Color; import java.awt.ruponent; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Enumeration; import java.util.Vector; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JViewport; import javax.swing.ListSelectionModel; import javax.swing.UIManager; import javax.swing.event.ListSelectionEvent; import javax.swing.event.TableModelEvent; import javax.swing.plaf.basic.BasicTableUI; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableModel; /* ----------------------------------------------
* | SNo. | * ---------------------------------------------- * | | 1 | * | Name |----------------------------------- * | | 2 | * ---------------------------------------------- * | | 1 | * | |----------------------------------- * | Language | 2 | * | |----------------------------------- * | | 3 | * ---------------------------------------------- */
/**
* @version 1.0 03/06/99 */
public class MultipleRowHeaderExample extends JFrame {
Object[][] data; Object[] column; JTable table; MultiSpanCellTable fixedTable; public MultipleRowHeaderExample() { super("Multiple Row Header Example"); setSize(400, 150); data = new Object[][] { { "SNo.", "" }, { "Name", "1" }, { "", "2" }, { "Language", "1" }, { "", "2" }, { "", "3" } }; column = new Object[] { "", "" }; AttributiveCellTableModel fixedModel = new AttributiveCellTableModel( data, column) { public boolean CellEditable(int row, int col) { return false; } }; CellSpan cellAtt = (CellSpan) fixedModel.getCellAttribute(); cellAtt.rubine(new int[] { 0 }, new int[] { 0, 1 }); cellAtt.rubine(new int[] { 1, 2 }, new int[] { 0 }); cellAtt.rubine(new int[] { 3, 4, 5 }, new int[] { 0 }); DefaultTableModel model = new DefaultTableModel(data.length, 3); fixedTable = new MultiSpanCellTable(fixedModel); table = new JTable(model); fixedTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); fixedTable.setDefaultRenderer(Object.class, new RowHeaderRenderer( fixedTable)); fixedTable.setGridColor(table.getTableHeader().getBackground()); JScrollPane scroll = new JScrollPane(table); JViewport viewport = new JViewport(); viewport.setView(fixedTable); viewport.setPreferredSize(fixedTable.getPreferredSize()); scroll.setRowHeaderView(viewport); getContentPane().add(scroll, BorderLayout.CENTER); } public static void main(String[] args) { MultipleRowHeaderExample frame = new MultipleRowHeaderExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); } class RowHeaderRenderer extends JLabel implements TableCellRenderer { RowHeaderRenderer(JTable table) { JTableHeader header = table.getTableHeader(); setOpaque(true); setBorder(UIManager.getBorder("TableHeader.cellBorder")); setHorizontalAlignment(CENTER); setForeground(header.getForeground()); setBackground(header.getBackground()); setFont(header.getFont()); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { setText((value == null) ? "" : value.toString()); return this; } }
} class AttributiveCellTableModel extends DefaultTableModel {
protected CellAttribute cellAtt; public AttributiveCellTableModel() { this((Vector) null, 0); } public AttributiveCellTableModel(int numRows, int numColumns) { Vector names = new Vector(numColumns); names.setSize(numColumns); setColumnIdentifiers(names); dataVector = new Vector(); setNumRows(numRows); cellAtt = new DefaultCellAttribute(numRows, numColumns); } public AttributiveCellTableModel(Vector columnNames, int numRows) { setColumnIdentifiers(columnNames); dataVector = new Vector(); setNumRows(numRows); cellAtt = new DefaultCellAttribute(numRows, columnNames.size()); } public AttributiveCellTableModel(Object[] columnNames, int numRows) { this(convertToVector(columnNames), numRows); } public AttributiveCellTableModel(Vector data, Vector columnNames) { setDataVector(data, columnNames); } public AttributiveCellTableModel(Object[][] data, Object[] columnNames) { setDataVector(data, columnNames); } public void setDataVector(Vector newData, Vector columnNames) { if (newData == null) throw new IllegalArgumentException( "setDataVector() - Null parameter"); dataVector = new Vector(0); setColumnIdentifiers(columnNames); dataVector = newData; // cellAtt = new DefaultCellAttribute(dataVector.size(), columnIdentifiers .size()); newRowsAdded(new TableModelEvent(this, 0, getRowCount() - 1, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } public void addColumn(Object columnName, Vector columnData) { if (columnName == null) throw new IllegalArgumentException("addColumn() - null parameter"); columnIdentifiers.addElement(columnName); int index = 0; Enumeration enumeration = dataVector.elements(); while (enumeration.hasMoreElements()) { Object value; if ((columnData != null) && (index < columnData.size())) value = columnData.elementAt(index); else value = null; ((Vector) enumeration.nextElement()).addElement(value); index++; } // cellAtt.addColumn(); fireTableStructureChanged(); } public void addRow(Vector rowData) { Vector newData = null; if (rowData == null) { newData = new Vector(getColumnCount()); } else { rowData.setSize(getColumnCount()); } dataVector.addElement(newData); // cellAtt.addRow(); newRowsAdded(new TableModelEvent(this, getRowCount() - 1, getRowCount() - 1, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } public void insertRow(int row, Vector rowData) { if (rowData == null) { rowData = new Vector(getColumnCount()); } else { rowData.setSize(getColumnCount()); } dataVector.insertElementAt(rowData, row); // cellAtt.insertRow(row); newRowsAdded(new TableModelEvent(this, row, row, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } public CellAttribute getCellAttribute() { return cellAtt; } public void setCellAttribute(CellAttribute newCellAtt) { int numColumns = getColumnCount(); int numRows = getRowCount(); if ((newCellAtt.getSize().width != numColumns) || (newCellAtt.getSize().height != numRows)) { newCellAtt.setSize(new Dimension(numRows, numColumns)); } cellAtt = newCellAtt; fireTableDataChanged(); } /* * public void changeCellAttribute(int row, int column, Object command) { * cellAtt.changeAttribute(row, column, command); } * * public void changeCellAttribute(int[] rows, int[] columns, Object * command) { cellAtt.changeAttribute(rows, columns, command); } */
} class DefaultCellAttribute //implements CellAttribute ,CellSpan {
implements CellAttribute, CellSpan, ColoredCell, CellFont { // // !!!! CAUTION !!!!! // these values must be synchronized to Table data // protected int rowSize; protected int columnSize; protected int[][][] span; // CellSpan protected Color[][] foreground; // ColoredCell protected Color[][] background; // protected Font[][] font; // CellFont public DefaultCellAttribute() { this(1, 1); } public DefaultCellAttribute(int numRows, int numColumns) { setSize(new Dimension(numColumns, numRows)); } protected void initValue() { for (int i = 0; i < span.length; i++) { for (int j = 0; j < span[i].length; j++) { span[i][j][CellSpan.COLUMN] = 1; span[i][j][CellSpan.ROW] = 1; } } } // // CellSpan // public int[] getSpan(int row, int column) { if (isOutOfBounds(row, column)) { int[] ret_code = { 1, 1 }; return ret_code; } return span[row][column]; } public void setSpan(int[] span, int row, int column) { if (isOutOfBounds(row, column)) return; this.span[row][column] = span; } public boolean isVisible(int row, int column) { if (isOutOfBounds(row, column)) return false; if ((span[row][column][CellSpan.COLUMN] < 1) || (span[row][column][CellSpan.ROW] < 1)) return false; return true; } public void combine(int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; int rowSpan = rows.length; int columnSpan = columns.length; int startRow = rows[0]; int startColumn = columns[0]; for (int i = 0; i < rowSpan; i++) { for (int j = 0; j < columnSpan; j++) { if ((span[startRow + i][startColumn + j][CellSpan.COLUMN] != 1) || (span[startRow + i][startColumn + j][CellSpan.ROW] != 1)) { //System.out.println("can"t combine"); return; } } } for (int i = 0, ii = 0; i < rowSpan; i++, ii--) { for (int j = 0, jj = 0; j < columnSpan; j++, jj--) { span[startRow + i][startColumn + j][CellSpan.COLUMN] = jj; span[startRow + i][startColumn + j][CellSpan.ROW] = ii; //System.out.println("r " +ii +" c " +jj); } } span[startRow][startColumn][CellSpan.COLUMN] = columnSpan; span[startRow][startColumn][CellSpan.ROW] = rowSpan; } public void split(int row, int column) { if (isOutOfBounds(row, column)) return; int columnSpan = span[row][column][CellSpan.COLUMN]; int rowSpan = span[row][column][CellSpan.ROW]; for (int i = 0; i < rowSpan; i++) { for (int j = 0; j < columnSpan; j++) { span[row + i][column + j][CellSpan.COLUMN] = 1; span[row + i][column + j][CellSpan.ROW] = 1; } } } // // ColoredCell // public Color getForeground(int row, int column) { if (isOutOfBounds(row, column)) return null; return foreground[row][column]; } public void setForeground(Color color, int row, int column) { if (isOutOfBounds(row, column)) return; foreground[row][column] = color; } public void setForeground(Color color, int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; setValues(foreground, color, rows, columns); } public Color getBackground(int row, int column) { if (isOutOfBounds(row, column)) return null; return background[row][column]; } public void setBackground(Color color, int row, int column) { if (isOutOfBounds(row, column)) return; background[row][column] = color; } public void setBackground(Color color, int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; setValues(background, color, rows, columns); } // // // CellFont // public Font getFont(int row, int column) { if (isOutOfBounds(row, column)) return null; return font[row][column]; } public void setFont(Font font, int row, int column) { if (isOutOfBounds(row, column)) return; this.font[row][column] = font; } public void setFont(Font font, int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; setValues(this.font, font, rows, columns); } // // // CellAttribute // public void addColumn() { int[][][] oldSpan = span; int numRows = oldSpan.length; int numColumns = oldSpan[0].length; span = new int[numRows][numColumns + 1][2]; System.arraycopy(oldSpan, 0, span, 0, numRows); for (int i = 0; i < numRows; i++) { span[i][numColumns][CellSpan.COLUMN] = 1; span[i][numColumns][CellSpan.ROW] = 1; } } public void addRow() { int[][][] oldSpan = span; int numRows = oldSpan.length; int numColumns = oldSpan[0].length; span = new int[numRows + 1][numColumns][2]; System.arraycopy(oldSpan, 0, span, 0, numRows); for (int i = 0; i < numColumns; i++) { span[numRows][i][CellSpan.COLUMN] = 1; span[numRows][i][CellSpan.ROW] = 1; } } public void insertRow(int row) { int[][][] oldSpan = span; int numRows = oldSpan.length; int numColumns = oldSpan[0].length; span = new int[numRows + 1][numColumns][2]; if (0 < row) { System.arraycopy(oldSpan, 0, span, 0, row - 1); } System.arraycopy(oldSpan, 0, span, row, numRows - row); for (int i = 0; i < numColumns; i++) { span[row][i][CellSpan.COLUMN] = 1; span[row][i][CellSpan.ROW] = 1; } } public Dimension getSize() { return new Dimension(rowSize, columnSize); } public void setSize(Dimension size) { columnSize = size.width; rowSize = size.height; span = new int[rowSize][columnSize][2]; // 2: COLUMN,ROW foreground = new Color[rowSize][columnSize]; background = new Color[rowSize][columnSize]; font = new Font[rowSize][columnSize]; initValue(); } /* * public void changeAttribute(int row, int column, Object command) { } * * public void changeAttribute(int[] rows, int[] columns, Object command) { } */ protected boolean isOutOfBounds(int row, int column) { if ((row < 0) || (rowSize <= row) || (column < 0) || (columnSize <= column)) { return true; } return false; } protected boolean isOutOfBounds(int[] rows, int[] columns) { for (int i = 0; i < rows.length; i++) { if ((rows[i] < 0) || (rowSize <= rows[i])) return true; } for (int i = 0; i < columns.length; i++) { if ((columns[i] < 0) || (columnSize <= columns[i])) return true; } return false; } protected void setValues(Object[][] target, Object value, int[] rows, int[] columns) { for (int i = 0; i < rows.length; i++) { int row = rows[i]; for (int j = 0; j < columns.length; j++) { int column = columns[j]; target[row][column] = value; } } }
} interface CellAttribute {
public void addColumn(); public void addRow(); public void insertRow(int row); public Dimension getSize(); public void setSize(Dimension size);
} interface ColoredCell {
public Color getForeground(int row, int column); public void setForeground(Color color, int row, int column); public void setForeground(Color color, int[] rows, int[] columns); public Color getBackground(int row, int column); public void setBackground(Color color, int row, int column); public void setBackground(Color color, int[] rows, int[] columns);
} interface CellFont {
public Font getFont(int row, int column); public void setFont(Font font, int row, int column); public void setFont(Font font, int[] rows, int[] columns);
} interface CellSpan {
public final int ROW = 0; public final int COLUMN = 1; public int[] getSpan(int row, int column); public void setSpan(int[] span, int row, int column); public boolean isVisible(int row, int column); public void combine(int[] rows, int[] columns); public void split(int row, int column);
} class MultiSpanCellTable extends JTable {
public MultiSpanCellTable(TableModel model) { super(model); setUI(new MultiSpanCellTableUI()); getTableHeader().setReorderingAllowed(false); setCellSelectionEnabled(true); setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); } public Rectangle getCellRect(int row, int column, boolean includeSpacing) { Rectangle sRect = super.getCellRect(row, column, includeSpacing); if ((row < 0) || (column < 0) || (getRowCount() <= row) || (getColumnCount() <= column)) { return sRect; } CellSpan cellAtt = (CellSpan) ((AttributiveCellTableModel) getModel()) .getCellAttribute(); if (!cellAtt.isVisible(row, column)) { int temp_row = row; int temp_column = column; row += cellAtt.getSpan(temp_row, temp_column)[CellSpan.ROW]; column += cellAtt.getSpan(temp_row, temp_column)[CellSpan.COLUMN]; } int[] n = cellAtt.getSpan(row, column); int index = 0; int columnMargin = getColumnModel().getColumnMargin(); Rectangle cellFrame = new Rectangle(); int aCellHeight = rowHeight + rowMargin; cellFrame.y = row * aCellHeight; cellFrame.height = n[CellSpan.ROW] * aCellHeight; Enumeration enumeration = getColumnModel().getColumns(); while (enumeration.hasMoreElements()) { TableColumn aColumn = (TableColumn) enumeration.nextElement(); cellFrame.width = aColumn.getWidth() + columnMargin; if (index == column) break; cellFrame.x += cellFrame.width; index++; } for (int i = 0; i < n[CellSpan.COLUMN] - 1; i++) { TableColumn aColumn = (TableColumn) enumeration.nextElement(); cellFrame.width += aColumn.getWidth() + columnMargin; } if (!includeSpacing) { Dimension spacing = getIntercellSpacing(); cellFrame.setBounds(cellFrame.x + spacing.width / 2, cellFrame.y + spacing.height / 2, cellFrame.width - spacing.width, cellFrame.height - spacing.height); } return cellFrame; } private int[] rowColumnAtPoint(Point point) { int[] retValue = { -1, -1 }; int row = point.y / (rowHeight + rowMargin); if ((row < 0) || (getRowCount() <= row)) return retValue; int column = getColumnModel().getColumnIndexAtX(point.x); CellSpan cellAtt = (CellSpan) ((AttributiveCellTableModel) getModel()) .getCellAttribute(); if (cellAtt.isVisible(row, column)) { retValue[CellSpan.COLUMN] = column; retValue[CellSpan.ROW] = row; return retValue; } retValue[CellSpan.COLUMN] = column + cellAtt.getSpan(row, column)[CellSpan.COLUMN]; retValue[CellSpan.ROW] = row + cellAtt.getSpan(row, column)[CellSpan.ROW]; return retValue; } public int rowAtPoint(Point point) { return rowColumnAtPoint(point)[CellSpan.ROW]; } public int columnAtPoint(Point point) { return rowColumnAtPoint(point)[CellSpan.COLUMN]; } public void columnSelectionChanged(ListSelectionEvent e) { repaint(); } public void valueChanged(ListSelectionEvent e) { int firstIndex = e.getFirstIndex(); int lastIndex = e.getLastIndex(); if (firstIndex == -1 && lastIndex == -1) { // Selection cleared. repaint(); } Rectangle dirtyRegion = getCellRect(firstIndex, 0, false); int numCoumns = getColumnCount(); int index = firstIndex; for (int i = 0; i < numCoumns; i++) { dirtyRegion.add(getCellRect(index, i, false)); } index = lastIndex; for (int i = 0; i < numCoumns; i++) { dirtyRegion.add(getCellRect(index, i, false)); } repaint(dirtyRegion.x, dirtyRegion.y, dirtyRegion.width, dirtyRegion.height); }
} class MultiSpanCellTableUI extends BasicTableUI {
public void paint(Graphics g, JComponent c) { Rectangle oldClipBounds = g.getClipBounds(); Rectangle clipBounds = new Rectangle(oldClipBounds); int tableWidth = table.getColumnModel().getTotalColumnWidth(); clipBounds.width = Math.min(clipBounds.width, tableWidth); g.setClip(clipBounds); int firstIndex = table.rowAtPoint(new Point(0, clipBounds.y)); int lastIndex = table.getRowCount() - 1; Rectangle rowRect = new Rectangle(0, 0, tableWidth, table .getRowHeight() + table.getRowMargin()); rowRect.y = firstIndex * rowRect.height; for (int index = firstIndex; index <= lastIndex; index++) { if (rowRect.intersects(clipBounds)) { //System.out.println(); // debug //System.out.print("" + index +": "); // row paintRow(g, index); } rowRect.y += rowRect.height; } g.setClip(oldClipBounds); } private void paintRow(Graphics g, int row) { Rectangle rect = g.getClipBounds(); boolean drawn = false; AttributiveCellTableModel tableModel = (AttributiveCellTableModel) table .getModel(); CellSpan cellAtt = (CellSpan) tableModel.getCellAttribute(); int numColumns = table.getColumnCount(); for (int column = 0; column < numColumns; column++) { Rectangle cellRect = table.getCellRect(row, column, true); int cellRow, cellColumn; if (cellAtt.isVisible(row, column)) { cellRow = row; cellColumn = column; // System.out.print(" "+column+" "); // debug } else { cellRow = row + cellAtt.getSpan(row, column)[CellSpan.ROW]; cellColumn = column + cellAtt.getSpan(row, column)[CellSpan.COLUMN]; // System.out.print(" ("+column+")"); // debug } if (cellRect.intersects(rect)) { drawn = true; paintCell(g, cellRect, cellRow, cellColumn); } else { if (drawn) break; } } } private void paintCell(Graphics g, Rectangle cellRect, int row, int column) { int spacingHeight = table.getRowMargin(); int spacingWidth = table.getColumnModel().getColumnMargin(); Color c = g.getColor(); g.setColor(table.getGridColor()); g.drawRect(cellRect.x, cellRect.y, cellRect.width - 1, cellRect.height - 1); g.setColor(c); cellRect.setBounds(cellRect.x + spacingWidth / 2, cellRect.y + spacingHeight / 2, cellRect.width - spacingWidth, cellRect.height - spacingHeight); if (table.isEditing() && table.getEditingRow() == row && table.getEditingColumn() == column) { Component component = table.getEditorComponent(); component.setBounds(cellRect); component.validate(); } else { TableCellRenderer renderer = table.getCellRenderer(row, column); Component component = table.prepareRenderer(renderer, row, column); if (component.getParent() == null) { rendererPane.add(component); } rendererPane.paintComponent(g, component, table, cellRect.x, cellRect.y, cellRect.width, cellRect.height, true); } }
}
</source>
Multi Span Cell Table Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html import java.awt.Color; import java.awt.ruponent; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.GridLayout; import java.awt.Point; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Enumeration; import java.util.Vector; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.event.ListSelectionEvent; import javax.swing.event.TableModelEvent; import javax.swing.plaf.basic.BasicTableUI; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableModel;
/**
* @version 1.0 11/26/98 */
public class MultiSpanCellTableExample extends JFrame {
MultiSpanCellTableExample() { super( "Multi-Span Cell Example" ); AttributiveCellTableModel ml = new AttributiveCellTableModel(10,6); /* AttributiveCellTableModel ml = new AttributiveCellTableModel(10,6) { public Object getValueAt(int row, int col) { return "" + row + ","+ col; } }; */ final CellSpan cellAtt =(CellSpan)ml.getCellAttribute(); final MultiSpanCellTable table = new MultiSpanCellTable( ml ); JScrollPane scroll = new JScrollPane( table ); JButton b_one = new JButton("Combine"); b_one.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int[] columns = table.getSelectedColumns(); int[] rows = table.getSelectedRows(); cellAtt.rubine(rows,columns); table.clearSelection(); table.revalidate(); table.repaint(); } }); JButton b_split = new JButton("Split"); b_split.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int column = table.getSelectedColumn(); int row = table.getSelectedRow(); cellAtt.split(row,column); table.clearSelection(); table.revalidate(); table.repaint(); } }); JPanel p_buttons = new JPanel(); p_buttons.setLayout(new GridLayout(2,1)); p_buttons.add(b_one); p_buttons.add(b_split); Box box = new Box(BoxLayout.X_AXIS); box.add(scroll); box.add(new JSeparator(SwingConstants.HORIZONTAL)); box.add(p_buttons); getContentPane().add( box ); setSize( 400, 200 ); setVisible(true); } public static void main(String[] args) { MultiSpanCellTableExample frame = new MultiSpanCellTableExample(); frame.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit(0); } }); }
}
/**
* @version 1.0 11/22/98 */
class AttributiveCellTableModel extends DefaultTableModel {
protected CellAttribute cellAtt; public AttributiveCellTableModel() { this((Vector)null, 0); } public AttributiveCellTableModel(int numRows, int numColumns) { Vector names = new Vector(numColumns); names.setSize(numColumns); setColumnIdentifiers(names); dataVector = new Vector(); setNumRows(numRows); cellAtt = new DefaultCellAttribute(numRows,numColumns); } public AttributiveCellTableModel(Vector columnNames, int numRows) { setColumnIdentifiers(columnNames); dataVector = new Vector(); setNumRows(numRows); cellAtt = new DefaultCellAttribute(numRows,columnNames.size()); } public AttributiveCellTableModel(Object[] columnNames, int numRows) { this(convertToVector(columnNames), numRows); } public AttributiveCellTableModel(Vector data, Vector columnNames) { setDataVector(data, columnNames); } public AttributiveCellTableModel(Object[][] data, Object[] columnNames) { setDataVector(data, columnNames); } public void setDataVector(Vector newData, Vector columnNames) { if (newData == null) throw new IllegalArgumentException("setDataVector() - Null parameter"); dataVector = new Vector(0); setColumnIdentifiers(columnNames); dataVector = newData; // cellAtt = new DefaultCellAttribute(dataVector.size(), columnIdentifiers.size()); newRowsAdded(new TableModelEvent(this, 0, getRowCount()-1, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } public void addColumn(Object columnName, Vector columnData) { if (columnName == null) throw new IllegalArgumentException("addColumn() - null parameter"); columnIdentifiers.addElement(columnName); int index = 0; Enumeration eeration = dataVector.elements(); while (eeration.hasMoreElements()) { Object value; if ((columnData != null) && (index < columnData.size())) value = columnData.elementAt(index); else value = null; ((Vector)eeration.nextElement()).addElement(value); index++; } // cellAtt.addColumn(); fireTableStructureChanged(); } public void addRow(Vector rowData) { Vector newData = null; if (rowData == null) { newData = new Vector(getColumnCount()); } else { rowData.setSize(getColumnCount()); } dataVector.addElement(newData); // cellAtt.addRow(); newRowsAdded(new TableModelEvent(this, getRowCount()-1, getRowCount()-1, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } public void insertRow(int row, Vector rowData) { if (rowData == null) { rowData = new Vector(getColumnCount()); } else { rowData.setSize(getColumnCount()); } dataVector.insertElementAt(rowData, row); // cellAtt.insertRow(row); newRowsAdded(new TableModelEvent(this, row, row, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT)); } public CellAttribute getCellAttribute() { return cellAtt; } public void setCellAttribute(CellAttribute newCellAtt) { int numColumns = getColumnCount(); int numRows = getRowCount(); if ((newCellAtt.getSize().width != numColumns) || (newCellAtt.getSize().height != numRows)) { newCellAtt.setSize(new Dimension(numRows, numColumns)); } cellAtt = newCellAtt; fireTableDataChanged(); } /* public void changeCellAttribute(int row, int column, Object command) { cellAtt.changeAttribute(row, column, command); } public void changeCellAttribute(int[] rows, int[] columns, Object command) { cellAtt.changeAttribute(rows, columns, command); } */
}
/**
* @version 1.0 11/22/98 */
class DefaultCellAttribute // implements CellAttribute ,CellSpan {
implements CellAttribute ,CellSpan ,ColoredCell ,CellFont { // // !!!! CAUTION !!!!! // these values must be synchronized to Table data // protected int rowSize; protected int columnSize; protected int[][][] span; // CellSpan protected Color[][] foreground; // ColoredCell protected Color[][] background; // protected Font[][] font; // CellFont public DefaultCellAttribute() { this(1,1); } public DefaultCellAttribute(int numRows, int numColumns) { setSize(new Dimension(numColumns, numRows)); } protected void initValue() { for(int i=0; i<span.length;i++) { for(int j=0; j<span[i].length; j++) { span[i][j][CellSpan.COLUMN] = 1; span[i][j][CellSpan.ROW] = 1; } } }
// // CellSpan // public int[] getSpan(int row, int column) { if (isOutOfBounds(row, column)) { int[] ret_code = {1,1}; return ret_code; } return span[row][column]; } public void setSpan(int[] span, int row, int column) { if (isOutOfBounds(row, column)) return; this.span[row][column] = span; } public boolean isVisible(int row, int column) { if (isOutOfBounds(row, column)) return false; if ((span[row][column][CellSpan.COLUMN] < 1) ||(span[row][column][CellSpan.ROW] < 1)) return false; return true; } public void combine(int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; int rowSpan = rows.length; int columnSpan = columns.length; int startRow = rows[0]; int startColumn = columns[0]; for (int i=0;i<rowSpan;i++) { for (int j=0;j<columnSpan;j++) { if ((span[startRow +i][startColumn +j][CellSpan.COLUMN] != 1) ||(span[startRow +i][startColumn +j][CellSpan.ROW] != 1)) { //System.out.println("can"t combine"); return ; } } } for (int i=0,ii=0;i<rowSpan;i++,ii--) { for (int j=0,jj=0;j<columnSpan;j++,jj--) { span[startRow +i][startColumn +j][CellSpan.COLUMN] = jj; span[startRow +i][startColumn +j][CellSpan.ROW] = ii; //System.out.println("r " +ii +" c " +jj); } } span[startRow][startColumn][CellSpan.COLUMN] = columnSpan; span[startRow][startColumn][CellSpan.ROW] = rowSpan; } public void split(int row, int column) { if (isOutOfBounds(row, column)) return; int columnSpan = span[row][column][CellSpan.COLUMN]; int rowSpan = span[row][column][CellSpan.ROW]; for (int i=0;i<rowSpan;i++) { for (int j=0;j<columnSpan;j++) { span[row +i][column +j][CellSpan.COLUMN] = 1; span[row +i][column +j][CellSpan.ROW] = 1; } } }
// // ColoredCell // public Color getForeground(int row, int column) { if (isOutOfBounds(row, column)) return null; return foreground[row][column]; } public void setForeground(Color color, int row, int column) { if (isOutOfBounds(row, column)) return; foreground[row][column] = color; } public void setForeground(Color color, int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; setValues(foreground, color, rows, columns); } public Color getBackground(int row, int column) { if (isOutOfBounds(row, column)) return null; return background[row][column]; } public void setBackground(Color color, int row, int column) { if (isOutOfBounds(row, column)) return; background[row][column] = color; } public void setBackground(Color color, int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; setValues(background, color, rows, columns); } //
// // CellFont // public Font getFont(int row, int column) { if (isOutOfBounds(row, column)) return null; return font[row][column]; } public void setFont(Font font, int row, int column) { if (isOutOfBounds(row, column)) return; this.font[row][column] = font; } public void setFont(Font font, int[] rows, int[] columns) { if (isOutOfBounds(rows, columns)) return; setValues(this.font, font, rows, columns); } //
// // CellAttribute // public void addColumn() { int[][][] oldSpan = span; int numRows = oldSpan.length; int numColumns = oldSpan[0].length; span = new int[numRows][numColumns + 1][2]; System.arraycopy(oldSpan,0,span,0,numRows); for (int i=0;i<numRows;i++) { span[i][numColumns][CellSpan.COLUMN] = 1; span[i][numColumns][CellSpan.ROW] = 1; } } public void addRow() { int[][][] oldSpan = span; int numRows = oldSpan.length; int numColumns = oldSpan[0].length; span = new int[numRows + 1][numColumns][2]; System.arraycopy(oldSpan,0,span,0,numRows); for (int i=0;i<numColumns;i++) { span[numRows][i][CellSpan.COLUMN] = 1; span[numRows][i][CellSpan.ROW] = 1; } } public void insertRow(int row) { int[][][] oldSpan = span; int numRows = oldSpan.length; int numColumns = oldSpan[0].length; span = new int[numRows + 1][numColumns][2]; if (0 < row) { System.arraycopy(oldSpan,0,span,0,row-1); } System.arraycopy(oldSpan,0,span,row,numRows - row); for (int i=0;i<numColumns;i++) { span[row][i][CellSpan.COLUMN] = 1; span[row][i][CellSpan.ROW] = 1; } } public Dimension getSize() { return new Dimension(rowSize, columnSize); } public void setSize(Dimension size) { columnSize = size.width; rowSize = size.height; span = new int[rowSize][columnSize][2]; // 2: COLUMN,ROW foreground = new Color[rowSize][columnSize]; background = new Color[rowSize][columnSize]; font = new Font[rowSize][columnSize]; initValue(); } /* public void changeAttribute(int row, int column, Object command) { } public void changeAttribute(int[] rows, int[] columns, Object command) { } */
protected boolean isOutOfBounds(int row, int column) { if ((row < 0)||(rowSize <= row) ||(column < 0)||(columnSize <= column)) { return true; } return false; } protected boolean isOutOfBounds(int[] rows, int[] columns) { for (int i=0;i<rows.length;i++) { if ((rows[i] < 0)||(rowSize <= rows[i])) return true; } for (int i=0;i<columns.length;i++) { if ((columns[i] < 0)||(columnSize <= columns[i])) return true; } return false; } protected void setValues(Object[][] target, Object value, int[] rows, int[] columns) { for (int i=0;i<rows.length;i++) { int row = rows[i]; for (int j=0;j<columns.length;j++) { int column = columns[j]; target[row][column] = value; } } }
} /*
* (swing1.1beta3) * */
/**
* @version 1.0 11/22/98 */
interface CellAttribute {
public void addColumn(); public void addRow(); public void insertRow(int row); public Dimension getSize(); public void setSize(Dimension size);
} /*
* (swing1.1beta3) * */
/**
* @version 1.0 11/22/98 */
interface CellSpan {
public final int ROW = 0; public final int COLUMN = 1; public int[] getSpan(int row, int column); public void setSpan(int[] span, int row, int column); public boolean isVisible(int row, int column); public void combine(int[] rows, int[] columns); public void split(int row, int column);
} /*
* (swing1.1beta3) * */
/**
* @version 1.0 11/26/98 */
class MultiSpanCellTable extends JTable {
public MultiSpanCellTable(TableModel model) { super(model); setUI(new MultiSpanCellTableUI()); getTableHeader().setReorderingAllowed(false); setCellSelectionEnabled(true); setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); } public Rectangle getCellRect(int row, int column, boolean includeSpacing) { Rectangle sRect = super.getCellRect(row,column,includeSpacing); if ((row <0) || (column<0) || (getRowCount() <= row) || (getColumnCount() <= column)) { return sRect; } CellSpan cellAtt = (CellSpan)((AttributiveCellTableModel)getModel()).getCellAttribute(); if (! cellAtt.isVisible(row,column)) { int temp_row = row; int temp_column = column; row += cellAtt.getSpan(temp_row,temp_column)[CellSpan.ROW]; column += cellAtt.getSpan(temp_row,temp_column)[CellSpan.COLUMN]; } int[] n = cellAtt.getSpan(row,column); int index = 0; int columnMargin = getColumnModel().getColumnMargin(); Rectangle cellFrame = new Rectangle(); int aCellHeight = rowHeight + rowMargin; cellFrame.y = row * aCellHeight; cellFrame.height = n[CellSpan.ROW] * aCellHeight; Enumeration eeration = getColumnModel().getColumns(); while (eeration.hasMoreElements()) { TableColumn aColumn = (TableColumn)eeration.nextElement(); cellFrame.width = aColumn.getWidth() + columnMargin; if (index == column) break; cellFrame.x += cellFrame.width; index++; } for (int i=0;i< n[CellSpan.COLUMN]-1;i++) { TableColumn aColumn = (TableColumn)eeration.nextElement(); cellFrame.width += aColumn.getWidth() + columnMargin; } if (!includeSpacing) { Dimension spacing = getIntercellSpacing(); cellFrame.setBounds(cellFrame.x + spacing.width/2, cellFrame.y + spacing.height/2, cellFrame.width - spacing.width, cellFrame.height - spacing.height); } return cellFrame; } private int[] rowColumnAtPoint(Point point) { int[] retValue = {-1,-1}; int row = point.y / (rowHeight + rowMargin); if ((row <0)||(getRowCount() <= row)) return retValue; int column = getColumnModel().getColumnIndexAtX(point.x); CellSpan cellAtt = (CellSpan)((AttributiveCellTableModel)getModel()).getCellAttribute(); if (cellAtt.isVisible(row,column)) { retValue[CellSpan.COLUMN] = column; retValue[CellSpan.ROW ] = row; return retValue; } retValue[CellSpan.COLUMN] = column + cellAtt.getSpan(row,column)[CellSpan.COLUMN]; retValue[CellSpan.ROW ] = row + cellAtt.getSpan(row,column)[CellSpan.ROW]; return retValue; } public int rowAtPoint(Point point) { return rowColumnAtPoint(point)[CellSpan.ROW]; } public int columnAtPoint(Point point) { return rowColumnAtPoint(point)[CellSpan.COLUMN]; } public void columnSelectionChanged(ListSelectionEvent e) { repaint(); } public void valueChanged(ListSelectionEvent e) { int firstIndex = e.getFirstIndex(); int lastIndex = e.getLastIndex(); if (firstIndex == -1 && lastIndex == -1) { // Selection cleared. repaint(); } Rectangle dirtyRegion = getCellRect(firstIndex, 0, false); int numCoumns = getColumnCount(); int index = firstIndex; for (int i=0;i<numCoumns;i++) { dirtyRegion.add(getCellRect(index, i, false)); } index = lastIndex; for (int i=0;i<numCoumns;i++) { dirtyRegion.add(getCellRect(index, i, false)); } repaint(dirtyRegion.x, dirtyRegion.y, dirtyRegion.width, dirtyRegion.height); }
}
/**
* @version 1.0 11/26/98 */
class MultiSpanCellTableUI extends BasicTableUI {
public void paint(Graphics g, JComponent c) { Rectangle oldClipBounds = g.getClipBounds(); Rectangle clipBounds = new Rectangle(oldClipBounds); int tableWidth = table.getColumnModel().getTotalColumnWidth(); clipBounds.width = Math.min(clipBounds.width, tableWidth); g.setClip(clipBounds); int firstIndex = table.rowAtPoint(new Point(0, clipBounds.y)); int lastIndex = table.getRowCount()-1; Rectangle rowRect = new Rectangle(0,0, tableWidth, table.getRowHeight() + table.getRowMargin()); rowRect.y = firstIndex*rowRect.height; for (int index = firstIndex; index <= lastIndex; index++) { if (rowRect.intersects(clipBounds)) { //System.out.println(); // debug //System.out.print("" + index +": "); // row paintRow(g, index); } rowRect.y += rowRect.height; } g.setClip(oldClipBounds); } private void paintRow(Graphics g, int row) { Rectangle rect = g.getClipBounds(); boolean drawn = false; AttributiveCellTableModel tableModel = (AttributiveCellTableModel)table.getModel(); CellSpan cellAtt = (CellSpan)tableModel.getCellAttribute(); int numColumns = table.getColumnCount(); for (int column = 0; column < numColumns; column++) { Rectangle cellRect = table.getCellRect(row,column,true); int cellRow,cellColumn; if (cellAtt.isVisible(row,column)) { cellRow = row; cellColumn = column; // System.out.print(" "+column+" "); // debug } else { cellRow = row + cellAtt.getSpan(row,column)[CellSpan.ROW]; cellColumn = column + cellAtt.getSpan(row,column)[CellSpan.COLUMN]; // System.out.print(" ("+column+")"); // debug } if (cellRect.intersects(rect)) { drawn = true; paintCell(g, cellRect, cellRow, cellColumn); } else { if (drawn) break; } } } private void paintCell(Graphics g, Rectangle cellRect, int row, int column) { int spacingHeight = table.getRowMargin(); int spacingWidth = table.getColumnModel().getColumnMargin(); Color c = g.getColor(); g.setColor(table.getGridColor()); g.drawRect(cellRect.x,cellRect.y,cellRect.width-1,cellRect.height-1); g.setColor(c); cellRect.setBounds(cellRect.x + spacingWidth/2, cellRect.y + spacingHeight/2, cellRect.width - spacingWidth, cellRect.height - spacingHeight); if (table.isEditing() && table.getEditingRow()==row && table.getEditingColumn()==column) { Component component = table.getEditorComponent(); component.setBounds(cellRect); component.validate(); } else { TableCellRenderer renderer = table.getCellRenderer(row, column); Component component = table.prepareRenderer(renderer, row, column); if (component.getParent() == null) { rendererPane.add(component); } rendererPane.paintComponent(g, component, table, cellRect.x, cellRect.y, cellRect.width, cellRect.height, true); } }
}
interface CellFont {
public Font getFont(int row, int column); public void setFont(Font font, int row, int column); public void setFont(Font font, int[] rows, int[] columns);
}
interface ColoredCell {
public Color getForeground(int row, int column); public void setForeground(Color color, int row, int column); public void setForeground(Color color, int[] rows, int[] columns); public Color getBackground(int row, int column); public void setBackground(Color color, int row, int column); public void setBackground(Color color, int[] rows, int[] columns);
}
</source>
MultiWidth Header Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /*
* (swing1.1beta3) * * |-----------------------------------------------------| * | 1st | 2nd | 3rd | * |-----------------------------------------------------| * | | | | | | | */
import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.*;
/**
* @version 1.0 11/09/98 */
public class MultiWidthHeaderExample extends JFrame {
MultiWidthHeaderExample() { super( "Multi-Width Header Example" ); DefaultTableModel dm = new DefaultTableModel(); dm.setDataVector(new Object[][]{ {"a","b","c","d","e","f"}, {"A","B","C","D","E","F"}}, new Object[]{"1 st","","","","",""}); JTable table = new JTable( dm ) { protected JTableHeader createDefaultTableHeader() { return new GroupableTableHeader(columnModel); } }; TableColumnModel cm = table.getColumnModel(); ColumnGroup g_2nd = new ColumnGroup("2 nd"); g_2nd.add(cm.getColumn(1)); g_2nd.add(cm.getColumn(2)); ColumnGroup g_3rd = new ColumnGroup("3 rd"); g_3rd.add(cm.getColumn(3)); g_3rd.add(cm.getColumn(4)); g_3rd.add(cm.getColumn(5)); GroupableTableHeader header = (GroupableTableHeader)table.getTableHeader(); header.addColumnGroup(g_2nd); header.addColumnGroup(g_3rd); JScrollPane scroll = new JScrollPane( table ); getContentPane().add( scroll ); setSize( 400, 100 ); header.revalidate(); } public static void main(String[] args) { MultiWidthHeaderExample frame = new MultiWidthHeaderExample(); frame.addWindowListener( new WindowAdapter() { public void windowClosing( WindowEvent e ) { System.exit(0); } }); frame.setVisible(true); }
} /*
* (swing1.1beta3) * */
import java.util.*; import java.awt.*; import javax.swing.*; import javax.swing.table.*;
/**
* ColumnGroup * * @version 1.0 10/20/98 * @author Nobuo Tamemasa */
public class ColumnGroup {
protected TableCellRenderer renderer; protected Vector v; protected String text; protected int margin=0; public ColumnGroup(String text) { this(null,text); } public ColumnGroup(TableCellRenderer renderer,String text) { if (renderer == null) { this.renderer = new DefaultTableCellRenderer() { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JTableHeader header = table.getTableHeader(); if (header != null) { setForeground(header.getForeground()); setBackground(header.getBackground()); setFont(header.getFont()); } setHorizontalAlignment(JLabel.CENTER); setText((value == null) ? "" : value.toString()); setBorder(UIManager.getBorder("TableHeader.cellBorder")); return this; } }; } else { this.renderer = renderer; } this.text = text; v = new Vector(); } /** * @param obj TableColumn or ColumnGroup */ public void add(Object obj) { if (obj == null) { return; } v.addElement(obj); } /** * @param c TableColumn * @param v ColumnGroups */ public Vector getColumnGroups(TableColumn c, Vector g) { g.addElement(this); if (v.contains(c)) return g; Enumeration e = v.elements(); while (e.hasMoreElements()) { Object obj = e.nextElement(); if (obj instanceof ColumnGroup) { Vector groups = (Vector)((ColumnGroup)obj).getColumnGroups(c,(Vector)g.clone()); if (groups != null) return groups; } } return null; } public TableCellRenderer getHeaderRenderer() { return renderer; } public void setHeaderRenderer(TableCellRenderer renderer) { if (renderer != null) { this.renderer = renderer; } } public Object getHeaderValue() { return text; } public Dimension getSize(JTable table) { Component comp = renderer.getTableCellRendererComponent( table, getHeaderValue(), false, false,-1, -1); int height = comp.getPreferredSize().height; int width = 0; Enumeration e = v.elements(); while (e.hasMoreElements()) { Object obj = e.nextElement(); if (obj instanceof TableColumn) { TableColumn aColumn = (TableColumn)obj; width += aColumn.getWidth(); width += margin; } else { width += ((ColumnGroup)obj).getSize(table).width; } } return new Dimension(width, height); } public void setColumnMargin(int margin) { this.margin = margin; Enumeration e = v.elements(); while (e.hasMoreElements()) { Object obj = e.nextElement(); if (obj instanceof ColumnGroup) { ((ColumnGroup)obj).setColumnMargin(margin); } } }
} /*
* (swing1.1beta3) * */
import java.util.*; import java.awt.*; import javax.swing.*; import javax.swing.table.*;
/**
* GroupableTableHeader * * @version 1.0 10/20/98 * @author Nobuo Tamemasa */
public class GroupableTableHeader extends JTableHeader {
private static final String uiClassID = "GroupableTableHeaderUI"; protected Vector columnGroups = null; public GroupableTableHeader(TableColumnModel model) { super(model); setUI(new GroupableTableHeaderUI()); setReorderingAllowed(false); } public void updateUI(){ setUI(new GroupableTableHeaderUI()); } public void setReorderingAllowed(boolean b) { reorderingAllowed = false; } public void addColumnGroup(ColumnGroup g) { if (columnGroups == null) { columnGroups = new Vector(); } columnGroups.addElement(g); } public Enumeration getColumnGroups(TableColumn col) { if (columnGroups == null) return null; Enumeration e = columnGroups.elements(); while (e.hasMoreElements()) { ColumnGroup cGroup = (ColumnGroup)e.nextElement(); Vector v_ret = (Vector)cGroup.getColumnGroups(col,new Vector()); if (v_ret != null) { return v_ret.elements(); } } return null; } public void setColumnMargin() { if (columnGroups == null) return; int columnMargin = getColumnModel().getColumnMargin(); Enumeration e = columnGroups.elements(); while (e.hasMoreElements()) { ColumnGroup cGroup = (ColumnGroup)e.nextElement(); cGroup.setColumnMargin(columnMargin); } }
} import java.util.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.table.*; import javax.swing.plaf.basic.BasicTableHeaderUI;
public class GroupableTableHeaderUI extends BasicTableHeaderUI {
public void paint(Graphics g, JComponent c) { Rectangle clipBounds = g.getClipBounds(); if (header.getColumnModel() == null) return; ((GroupableTableHeader)header).setColumnMargin(); int column = 0; Dimension size = header.getSize(); Rectangle cellRect = new Rectangle(0, 0, size.width, size.height); Hashtable h = new Hashtable(); int columnMargin = header.getColumnModel().getColumnMargin(); Enumeration enumeration = header.getColumnModel().getColumns(); while (enumeration.hasMoreElements()) { cellRect.height = size.height; cellRect.y = 0; TableColumn aColumn = (TableColumn)enumeration.nextElement(); Enumeration cGroups = ((GroupableTableHeader)header).getColumnGroups(aColumn); if (cGroups != null) { int groupHeight = 0; while (cGroups.hasMoreElements()) { ColumnGroup cGroup = (ColumnGroup)cGroups.nextElement(); Rectangle groupRect = (Rectangle)h.get(cGroup); if (groupRect == null) { groupRect = new Rectangle(cellRect); Dimension d = cGroup.getSize(header.getTable()); groupRect.width = d.width; groupRect.height = d.height; h.put(cGroup, groupRect); } paintCell(g, groupRect, cGroup); groupHeight += groupRect.height; cellRect.height = size.height - groupHeight; cellRect.y = groupHeight; } } cellRect.width = aColumn.getWidth() + columnMargin; if (cellRect.intersects(clipBounds)) { paintCell(g, cellRect, column); } cellRect.x += cellRect.width; column++; } } private void paintCell(Graphics g, Rectangle cellRect, int columnIndex) { TableColumn aColumn = header.getColumnModel().getColumn(columnIndex); TableCellRenderer renderer = aColumn.getHeaderRenderer(); //revised by jexp.ru renderer = new DefaultTableCellRenderer(){ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JLabel header = new JLabel(); header.setForeground(table.getTableHeader().getForeground()); header.setBackground(table.getTableHeader().getBackground()); header.setFont(table.getTableHeader().getFont()); header.setHorizontalAlignment(JLabel.CENTER); header.setText(value.toString()); header.setBorder(UIManager.getBorder("TableHeader.cellBorder")); return header; } }; Component c = renderer.getTableCellRendererComponent( header.getTable(), aColumn.getHeaderValue(),false, false, -1, columnIndex); rendererPane.add(c); rendererPane.paintComponent(g, c, header, cellRect.x, cellRect.y, cellRect.width, cellRect.height, true); } private void paintCell(Graphics g, Rectangle cellRect,ColumnGroup cGroup) { TableCellRenderer renderer = cGroup.getHeaderRenderer(); //revised by jexp.ru // if(renderer == null){
// return ;
// } Component component = renderer.getTableCellRendererComponent( header.getTable(), cGroup.getHeaderValue(),false, false, -1, -1); rendererPane.add(component); rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y, cellRect.width, cellRect.height, true); } private int getHeaderHeight() { int height = 0; TableColumnModel columnModel = header.getColumnModel(); for(int column = 0; column < columnModel.getColumnCount(); column++) { TableColumn aColumn = columnModel.getColumn(column); TableCellRenderer renderer = aColumn.getHeaderRenderer(); //revised by jexp.ru if(renderer == null){ return 16; } Component comp = renderer.getTableCellRendererComponent( header.getTable(), aColumn.getHeaderValue(), false, false,-1, column); int cHeight = comp.getPreferredSize().height; Enumeration e = ((GroupableTableHeader)header).getColumnGroups(aColumn); if (e != null) { while (e.hasMoreElements()) { ColumnGroup cGroup = (ColumnGroup)e.nextElement(); cHeight += cGroup.getSize(header.getTable()).height; } } height = Math.max(height, cHeight); } return height; } private Dimension createHeaderSize(long width) { TableColumnModel columnModel = header.getColumnModel(); width += columnModel.getColumnMargin() * columnModel.getColumnCount(); if (width > Integer.MAX_VALUE) { width = Integer.MAX_VALUE; } return new Dimension((int)width, getHeaderHeight()); } public Dimension getPreferredSize(JComponent c) { long width = 0; Enumeration enumeration = header.getColumnModel().getColumns(); while (enumeration.hasMoreElements()) { TableColumn aColumn = (TableColumn)enumeration.nextElement(); width = width + aColumn.getPreferredWidth(); } return createHeaderSize(width); }
}
</source>
Pushable Table Header Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html import java.awt.BorderLayout; import java.awt.ruponent; import java.awt.Insets; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumnModel; /**
* @version 1.0 02/25/99 */
public class PushableHeaderExample extends JPanel {
public PushableHeaderExample() { setLayout(new BorderLayout()); String[] headerStr = { "Push", "me", "here" }; DefaultTableModel dm = new DefaultTableModel(headerStr, 4); JTable table = new JTable(dm); ButtonHeaderRenderer renderer = new ButtonHeaderRenderer(); TableColumnModel model = table.getColumnModel(); int n = headerStr.length; for (int i = 0; i < n; i++) { model.getColumn(i).setHeaderRenderer(renderer); } JTableHeader header = table.getTableHeader(); header.addMouseListener(new HeaderListener(header, renderer)); JScrollPane pane = new JScrollPane(table); add(pane, BorderLayout.CENTER); } public static void main(String[] args) { JFrame f = new JFrame("PushableHeaderTable Example"); f.getContentPane() .add(new PushableHeaderExample(), BorderLayout.CENTER); f.setSize(400, 100); f.setVisible(true); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } class HeaderListener extends MouseAdapter { JTableHeader header; ButtonHeaderRenderer renderer; HeaderListener(JTableHeader header, ButtonHeaderRenderer renderer) { this.header = header; this.renderer = renderer; } public void mousePressed(MouseEvent e) { int col = header.columnAtPoint(e.getPoint()); renderer.setPressedColumn(col); header.repaint(); System.out.println("Ouch! " + col); } public void mouseReleased(MouseEvent e) { int col = header.columnAtPoint(e.getPoint()); renderer.setPressedColumn(-1); // clear header.repaint(); } } class ButtonHeaderRenderer extends JButton implements TableCellRenderer { int pushedColumn; public ButtonHeaderRenderer() { pushedColumn = -1; setMargin(new Insets(0, 0, 0, 0)); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { setText((value == null) ? "" : value.toString()); boolean isPressed = (column == pushedColumn); getModel().setPressed(isPressed); getModel().setArmed(isPressed); return this; } public void setPressedColumn(int col) { pushedColumn = col; } }
}
</source>
Radio Button Table Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /**
* @version 1.0 12/03/98 */
import java.awt.ruponent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.ButtonGroup; import javax.swing.DefaultCellEditor; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.UIDefaults; import javax.swing.UIManager; import javax.swing.event.TableModelEvent; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; class RadioButtonRenderer implements TableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (value == null) return null; return (Component) value; }
} class RadioButtonEditor extends DefaultCellEditor implements ItemListener {
private JRadioButton button; public RadioButtonEditor(JCheckBox checkBox) { super(checkBox); } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { if (value == null) return null; button = (JRadioButton) value; button.addItemListener(this); return (Component) value; } public Object getCellEditorValue() { button.removeItemListener(this); return button; } public void itemStateChanged(ItemEvent e) { super.fireEditingStopped(); }
} public class JRadioButtonTableExample extends JFrame {
public JRadioButtonTableExample() { super("JRadioButtonTable Example"); UIDefaults ui = UIManager.getLookAndFeel().getDefaults(); UIManager.put("RadioButton.focus", ui.getColor("control")); DefaultTableModel dm = new DefaultTableModel(); dm.setDataVector(new Object[][] { { "Group 1", new JRadioButton("A") }, { "Group 1", new JRadioButton("B") }, { "Group 1", new JRadioButton("C") }, { "Group 2", new JRadioButton("a") }, { "Group 2", new JRadioButton("b") } }, new Object[] { "String", "JRadioButton" }); JTable table = new JTable(dm) { public void tableChanged(TableModelEvent e) { super.tableChanged(e); repaint(); } }; ButtonGroup group1 = new ButtonGroup(); group1.add((JRadioButton) dm.getValueAt(0, 1)); group1.add((JRadioButton) dm.getValueAt(1, 1)); group1.add((JRadioButton) dm.getValueAt(2, 1)); ButtonGroup group2 = new ButtonGroup(); group2.add((JRadioButton) dm.getValueAt(3, 1)); group2.add((JRadioButton) dm.getValueAt(4, 1)); table.getColumn("JRadioButton").setCellRenderer( new RadioButtonRenderer()); table.getColumn("JRadioButton").setCellEditor( new RadioButtonEditor(new JCheckBox())); JScrollPane scroll = new JScrollPane(table); getContentPane().add(scroll); setSize(200, 140); setVisible(true); } public static void main(String[] args) { JRadioButtonTableExample frame = new JRadioButtonTableExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); }
}
</source>
RadioButton Table Example 2
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1.1) */
import java.awt.ruponent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; import javax.swing.DefaultCellEditor; import javax.swing.JCheckBox; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JRadioButton; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; /**
* @version 1.2 08/13/99 */
public class JRadioButtonTableExample2 extends JFrame {
public JRadioButtonTableExample2() { super("JRadioButtonTable Example"); DefaultTableModel dm = new DefaultTableModel(); dm.setDataVector(new Object[][] { { "1", new Integer(-1) }, { "2", new Integer(-1) }, { "3", new Integer(0) }, { "4", new Integer(1) }, { "5", new Integer(2) } }, new Object[] { "Question", "Answer" }); JTable table = new JTable(dm); String[] answer = { "A", "B", "C" }; table.getColumn("Answer").setCellRenderer( new RadioButtonRenderer(answer)); table.getColumn("Answer").setCellEditor( new RadioButtonEditor(new JCheckBox(), new RadioButtonPanel( answer))); JScrollPane scroll = new JScrollPane(table); getContentPane().add(scroll); } // Cell base class RadioButtonPanel extends JPanel { JRadioButton[] buttons; RadioButtonPanel(String[] str) { setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); buttons = new JRadioButton[str.length]; for (int i = 0; i < buttons.length; i++) { buttons[i] = new JRadioButton(str[i]); buttons[i].setFocusPainted(false); add(buttons[i]); } } public void setSelectedIndex(int index) { for (int i = 0; i < buttons.length; i++) { buttons[i].setSelected(i == index); } } public int getSelectedIndex() { for (int i = 0; i < buttons.length; i++) { if (buttons[i].isSelected()) { return i; } } return -1; } public JRadioButton[] getButtons() { return buttons; } } class RadioButtonRenderer extends RadioButtonPanel implements TableCellRenderer { RadioButtonRenderer(String[] strs) { super(strs); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (value instanceof Integer) { setSelectedIndex(((Integer) value).intValue()); } return this; } } class RadioButtonEditor extends DefaultCellEditor implements ItemListener { RadioButtonPanel panel; public RadioButtonEditor(JCheckBox checkBox, RadioButtonPanel panel) { super(checkBox); this.panel = panel; ButtonGroup buttonGroup = new ButtonGroup(); JRadioButton[] buttons = panel.getButtons(); for (int i = 0; i < buttons.length; i++) { buttonGroup.add(buttons[i]); buttons[i].addItemListener(this); } } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { if (value instanceof Integer) { panel.setSelectedIndex(((Integer) value).intValue()); } return panel; } public Object getCellEditorValue() { return new Integer(panel.getSelectedIndex()); } public void itemStateChanged(ItemEvent e) { super.fireEditingStopped(); } } public static void main(String[] args) { JRadioButtonTableExample2 frame = new JRadioButtonTableExample2(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setSize(230, 140); frame.setVisible(true); }
}
</source>
Sortable Table Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1) */
import java.awt.BorderLayout; import java.awt.Color; import java.awt.ruponent; import java.awt.Graphics; import java.awt.Insets; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.text.DateFormat; import java.text.ParseException; import java.util.Date; import java.util.Hashtable; import java.util.Locale; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumnModel; /**
* @version 1.0 02/25/99 */
public class SortableTableExample extends JPanel {
public SortableTableExample() { setLayout(new BorderLayout()); String[] headerStr = { "Name", "Date", "Size", "Dir" }; int[] columnWidth = { 100, 150, 100, 50 }; SortableTableModel dm = new SortableTableModel() { public Class getColumnClass(int col) { switch (col) { case 0: return String.class; case 1: return Date.class; case 2: return Integer.class; case 3: return Boolean.class; default: return Object.class; } } public boolean isCellEditable(int row, int col) { switch (col) { case 1: return false; default: return true; } } public void setValueAt(Object obj, int row, int col) { switch (col) { case 2: super.setValueAt(new Integer(obj.toString()), row, col); return; default: super.setValueAt(obj, row, col); return; } } }; dm .setDataVector( new Object[][] { { "b", getDate("98/12/02"), new Integer(14), new Boolean(false) }, { "a", getDate("99/01/01"), new Integer(67), new Boolean(false) }, { "d", getDate("99/02/11"), new Integer(2), new Boolean(false) }, { "c", getDate("99/02/27"), new Integer(7), new Boolean(false) }, { "foo", new Date(), new Integer(5), new Boolean(true) }, { "bar", new Date(), new Integer(10), new Boolean(true) } }, headerStr); JTable table = new JTable(dm); //table.setShowGrid(false); table.setShowVerticalLines(true); table.setShowHorizontalLines(false); SortButtonRenderer renderer = new SortButtonRenderer(); TableColumnModel model = table.getColumnModel(); int n = headerStr.length; for (int i = 0; i < n; i++) { model.getColumn(i).setHeaderRenderer(renderer); model.getColumn(i).setPreferredWidth(columnWidth[i]); } JTableHeader header = table.getTableHeader(); header.addMouseListener(new HeaderListener(header, renderer)); JScrollPane pane = new JScrollPane(table); add(pane, BorderLayout.CENTER); } public static void main(String[] args) { JFrame f = new JFrame("SortableTable Example"); f.getContentPane().add(new SortableTableExample(), BorderLayout.CENTER); f.setSize(400, 160); f.setVisible(true); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } private static DateFormat dateFormat = DateFormat.getDateInstance( DateFormat.SHORT, Locale.JAPAN); private static Date getDate(String dateString) { Date date = null; try { date = dateFormat.parse(dateString); } catch (ParseException ex) { date = new Date(); } return date; } class HeaderListener extends MouseAdapter { JTableHeader header; SortButtonRenderer renderer; HeaderListener(JTableHeader header, SortButtonRenderer renderer) { this.header = header; this.renderer = renderer; } public void mousePressed(MouseEvent e) { int col = header.columnAtPoint(e.getPoint()); int sortCol = header.getTable().convertColumnIndexToModel(col); renderer.setPressedColumn(col); renderer.setSelectedColumn(col); header.repaint(); if (header.getTable().isEditing()) { header.getTable().getCellEditor().stopCellEditing(); } boolean isAscent; if (SortButtonRenderer.DOWN == renderer.getState(col)) { isAscent = true; } else { isAscent = false; } ((SortableTableModel) header.getTable().getModel()).sortByColumn( sortCol, isAscent); } public void mouseReleased(MouseEvent e) { int col = header.columnAtPoint(e.getPoint()); renderer.setPressedColumn(-1); // clear header.repaint(); } }
} class SortableTableModel extends DefaultTableModel {
int[] indexes; TableSorter sorter; public SortableTableModel() { } public Object getValueAt(int row, int col) { int rowIndex = row; if (indexes != null) { rowIndex = indexes[row]; } return super.getValueAt(rowIndex, col); } public void setValueAt(Object value, int row, int col) { int rowIndex = row; if (indexes != null) { rowIndex = indexes[row]; } super.setValueAt(value, rowIndex, col); } public void sortByColumn(int column, boolean isAscent) { if (sorter == null) { sorter = new TableSorter(this); } sorter.sort(column, isAscent); fireTableDataChanged(); } public int[] getIndexes() { int n = getRowCount(); if (indexes != null) { if (indexes.length == n) { return indexes; } } indexes = new int[n]; for (int i = 0; i < n; i++) { indexes[i] = i; } return indexes; }
} class TableSorter {
SortableTableModel model; public TableSorter(SortableTableModel model) { this.model = model; } //n2 selection public void sort(int column, boolean isAscent) { int n = model.getRowCount(); int[] indexes = model.getIndexes(); for (int i = 0; i < n - 1; i++) { int k = i; for (int j = i + 1; j < n; j++) { if (isAscent) { if (compare(column, j, k) < 0) { k = j; } } else { if (compare(column, j, k) > 0) { k = j; } } } int tmp = indexes[i]; indexes[i] = indexes[k]; indexes[k] = tmp; } } // comparaters public int compare(int column, int row1, int row2) { Object o1 = model.getValueAt(row1, column); Object o2 = model.getValueAt(row2, column); if (o1 == null && o2 == null) { return 0; } else if (o1 == null) { return -1; } else if (o2 == null) { return 1; } else { Class type = model.getColumnClass(column); if (type.getSuperclass() == Number.class) { return compare((Number) o1, (Number) o2); } else if (type == String.class) { return ((String) o1).rupareTo((String) o2); } else if (type == Date.class) { return compare((Date) o1, (Date) o2); } else if (type == Boolean.class) { return compare((Boolean) o1, (Boolean) o2); } else { return ((String) o1).rupareTo((String) o2); } } } public int compare(Number o1, Number o2) { double n1 = o1.doubleValue(); double n2 = o2.doubleValue(); if (n1 < n2) { return -1; } else if (n1 > n2) { return 1; } else { return 0; } } public int compare(Date o1, Date o2) { long n1 = o1.getTime(); long n2 = o2.getTime(); if (n1 < n2) { return -1; } else if (n1 > n2) { return 1; } else { return 0; } } public int compare(Boolean o1, Boolean o2) { boolean b1 = o1.booleanValue(); boolean b2 = o2.booleanValue(); if (b1 == b2) { return 0; } else if (b1) { return 1; } else { return -1; } }
} class SortButtonRenderer extends JButton implements TableCellRenderer {
public static final int NONE = 0; public static final int DOWN = 1; public static final int UP = 2; int pushedColumn; Hashtable state; JButton downButton, upButton; public SortButtonRenderer() { pushedColumn = -1; state = new Hashtable(); setMargin(new Insets(0, 0, 0, 0)); setHorizontalTextPosition(LEFT); setIcon(new BlankIcon()); // perplexed // ArrowIcon(SwingConstants.SOUTH, true) // BevelArrowIcon (int direction, boolean isRaisedView, boolean // isPressedView) downButton = new JButton(); downButton.setMargin(new Insets(0, 0, 0, 0)); downButton.setHorizontalTextPosition(LEFT); downButton .setIcon(new BevelArrowIcon(BevelArrowIcon.DOWN, false, false)); downButton.setPressedIcon(new BevelArrowIcon(BevelArrowIcon.DOWN, false, true)); upButton = new JButton(); upButton.setMargin(new Insets(0, 0, 0, 0)); upButton.setHorizontalTextPosition(LEFT); upButton.setIcon(new BevelArrowIcon(BevelArrowIcon.UP, false, false)); upButton.setPressedIcon(new BevelArrowIcon(BevelArrowIcon.UP, false, true)); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { JButton button = this; Object obj = state.get(new Integer(column)); if (obj != null) { if (((Integer) obj).intValue() == DOWN) { button = downButton; } else { button = upButton; } } button.setText((value == null) ? "" : value.toString()); boolean isPressed = (column == pushedColumn); button.getModel().setPressed(isPressed); button.getModel().setArmed(isPressed); return button; } public void setPressedColumn(int col) { pushedColumn = col; } public void setSelectedColumn(int col) { if (col < 0) return; Integer value = null; Object obj = state.get(new Integer(col)); if (obj == null) { value = new Integer(DOWN); } else { if (((Integer) obj).intValue() == DOWN) { value = new Integer(UP); } else { value = new Integer(DOWN); } } state.clear(); state.put(new Integer(col), value); } public int getState(int col) { int retValue; Object obj = state.get(new Integer(col)); if (obj == null) { retValue = NONE; } else { if (((Integer) obj).intValue() == DOWN) { retValue = DOWN; } else { retValue = UP; } } return retValue; }
} class BevelArrowIcon implements Icon {
public static final int UP = 0; // direction public static final int DOWN = 1; private static final int DEFAULT_SIZE = 11; private Color edge1; private Color edge2; private Color fill; private int size; private int direction; public BevelArrowIcon(int direction, boolean isRaisedView, boolean isPressedView) { if (isRaisedView) { if (isPressedView) { init(UIManager.getColor("controlLtHighlight"), UIManager .getColor("controlDkShadow"), UIManager .getColor("controlShadow"), DEFAULT_SIZE, direction); } else { init(UIManager.getColor("controlHighlight"), UIManager .getColor("controlShadow"), UIManager .getColor("control"), DEFAULT_SIZE, direction); } } else { if (isPressedView) { init(UIManager.getColor("controlDkShadow"), UIManager .getColor("controlLtHighlight"), UIManager .getColor("controlShadow"), DEFAULT_SIZE, direction); } else { init(UIManager.getColor("controlShadow"), UIManager .getColor("controlHighlight"), UIManager .getColor("control"), DEFAULT_SIZE, direction); } } } public BevelArrowIcon(Color edge1, Color edge2, Color fill, int size, int direction) { init(edge1, edge2, fill, size, direction); } public void paintIcon(Component c, Graphics g, int x, int y) { switch (direction) { case DOWN: drawDownArrow(g, x, y); break; case UP: drawUpArrow(g, x, y); break; } } public int getIconWidth() { return size; } public int getIconHeight() { return size; } private void init(Color edge1, Color edge2, Color fill, int size, int direction) { this.edge1 = edge1; this.edge2 = edge2; this.fill = fill; this.size = size; this.direction = direction; } private void drawDownArrow(Graphics g, int xo, int yo) { g.setColor(edge1); g.drawLine(xo, yo, xo + size - 1, yo); g.drawLine(xo, yo + 1, xo + size - 3, yo + 1); g.setColor(edge2); g.drawLine(xo + size - 2, yo + 1, xo + size - 1, yo + 1); int x = xo + 1; int y = yo + 2; int dx = size - 6; while (y + 1 < yo + size) { g.setColor(edge1); g.drawLine(x, y, x + 1, y); g.drawLine(x, y + 1, x + 1, y + 1); if (0 < dx) { g.setColor(fill); g.drawLine(x + 2, y, x + 1 + dx, y); g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1); } g.setColor(edge2); g.drawLine(x + dx + 2, y, x + dx + 3, y); g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1); x += 1; y += 2; dx -= 2; } g.setColor(edge1); g.drawLine(xo + (size / 2), yo + size - 1, xo + (size / 2), yo + size - 1); } private void drawUpArrow(Graphics g, int xo, int yo) { g.setColor(edge1); int x = xo + (size / 2); g.drawLine(x, yo, x, yo); x--; int y = yo + 1; int dx = 0; while (y + 3 < yo + size) { g.setColor(edge1); g.drawLine(x, y, x + 1, y); g.drawLine(x, y + 1, x + 1, y + 1); if (0 < dx) { g.setColor(fill); g.drawLine(x + 2, y, x + 1 + dx, y); g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1); } g.setColor(edge2); g.drawLine(x + dx + 2, y, x + dx + 3, y); g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1); x -= 1; y += 2; dx += 2; } g.setColor(edge1); g.drawLine(xo, yo + size - 3, xo + 1, yo + size - 3); g.setColor(edge2); g.drawLine(xo + 2, yo + size - 2, xo + size - 1, yo + size - 2); g.drawLine(xo, yo + size - 1, xo + size, yo + size - 1); }
} class BlankIcon implements Icon {
private Color fillColor; private int size; public BlankIcon() { this(null, 11); } public BlankIcon(Color color, int size) { //UIManager.getColor("control") //UIManager.getColor("controlShadow") fillColor = color; this.size = size; } public void paintIcon(Component c, Graphics g, int x, int y) { if (fillColor != null) { g.setColor(fillColor); g.drawRect(x, y, size - 1, size - 1); } } public int getIconWidth() { return size; } public int getIconHeight() { return size; }
}
</source>
Striped Currency Table
<source lang="java">
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall
- /
import java.awt.Color; import java.awt.ruponent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.text.NumberFormat; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; public class StripedCurrencyTable {
public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception evt) {} JFrame f = new JFrame("Striped Currency Table"); JTable tbl = new JTable(new CurrencyTableModel()); tbl.setDefaultRenderer(java.lang.Number.class, new FractionCellRenderer(10, 3, SwingConstants.RIGHT)); TableColumnModel tcm = tbl.getColumnModel(); tcm.getColumn(0).setPreferredWidth(150); tcm.getColumn(0).setMinWidth(150); TextWithIconCellRenderer renderer = new TextWithIconCellRenderer(); tcm.getColumn(0).setCellRenderer(renderer); tbl.setShowHorizontalLines(false); // Add the stripe renderer. StripedTableCellRenderer.installInTable(tbl, Color.lightGray, Color.white, null, null); tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tbl.setPreferredScrollableViewportSize(tbl.getPreferredSize()); JScrollPane sp = new JScrollPane(tbl); f.getContentPane().add(sp, "Center"); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); f.setVisible(true); }
} class DataWithIcon {
public DataWithIcon(Object data, Icon icon) { this.data = data; this.icon = icon; } public Icon getIcon() { return icon; } public Object getData() { return data; } public String toString() { return data.toString(); } protected Icon icon; protected Object data;
} class CurrencyTableModel extends AbstractTableModel {
protected String[] columnNames = { "Currency", "Yesterday", "Today", "Change" }; // Constructor: calculate currency change to create the last column public CurrencyTableModel() { for (int i = 0; i < data.length; i++) { data[i][DIFF_COLUMN] = new Double( ((Double) data[i][NEW_RATE_COLUMN]).doubleValue() - ((Double) data[i][OLD_RATE_COLUMN]).doubleValue()); } } // Implementation of TableModel interface public int getRowCount() { return data.length; } public int getColumnCount() { return COLUMN_COUNT; } public Object getValueAt(int row, int column) { return data[row][column]; } public Class getColumnClass(int column) { return (data[0][column]).getClass(); } public String getColumnName(int column) { return columnNames[column]; } protected static final int OLD_RATE_COLUMN = 1; protected static final int NEW_RATE_COLUMN = 2; protected static final int DIFF_COLUMN = 3; protected static final int COLUMN_COUNT = 4; protected static final Class thisClass = CurrencyTableModel.class; protected Object[][] data = new Object[][] { { new DataWithIcon("Belgian Franc", new ImageIcon(thisClass .getResource("belgium.gif"))), new Double(37.6460110), new Double(37.6508921), null }, { new DataWithIcon("British Pound", new ImageIcon(thisClass .getResource("gb.gif"))), new Double(0.6213051), new Double(0.6104102), null }, { new DataWithIcon("Canadian Dollar", new ImageIcon(thisClass .getResource("canada.gif"))), new Double(1.4651209), new Double(1.5011104), null }, { new DataWithIcon("French Franc", new ImageIcon(thisClass .getResource("france.gif"))), new Double(6.1060001), new Double(6.0100101), null }, { new DataWithIcon("Italian Lire", new ImageIcon(thisClass .getResource("italy.gif"))), new Double(1181.3668977), new Double(1182.104), null }, { new DataWithIcon("German Mark", new ImageIcon(thisClass .getResource("germany.gif"))), new Double(1.8191804), new Double(1.8223421), null }, { new DataWithIcon("Japanese Yen", new ImageIcon(thisClass .getResource("japan.gif"))), new Double(141.0815412), new Double(121.0040432), null } };
} class StripedTableCellRenderer implements TableCellRenderer {
public StripedTableCellRenderer(TableCellRenderer targetRenderer, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { this.targetRenderer = targetRenderer; this.evenBack = evenBack; this.evenFore = evenFore; this.oddBack = oddBack; this.oddFore = oddFore; } // Implementation of TableCellRenderer interface public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { TableCellRenderer renderer = targetRenderer; if (renderer == null) { // Get default renderer from the table renderer = table.getDefaultRenderer(table.getColumnClass(column)); } // Let the real renderer create the component Component comp = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); // Now apply the stripe effect if (isSelected == false && hasFocus == false) { if ((row & 1) == 0) { comp.setBackground(evenBack != null ? evenBack : table .getBackground()); comp.setForeground(evenFore != null ? evenFore : table .getForeground()); } else { comp.setBackground(oddBack != null ? oddBack : table .getBackground()); comp.setForeground(oddFore != null ? oddFore : table .getForeground()); } } return comp; } // Convenience method to apply this renderer to single column public static void installInColumn(JTable table, int columnIndex, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { TableColumn tc = table.getColumnModel().getColumn(columnIndex); // Get the cell renderer for this column, if any TableCellRenderer targetRenderer = tc.getCellRenderer(); // Create a new StripedTableCellRenderer and install it tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } // Convenience method to apply this renderer to an entire table public static void installInTable(JTable table, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { StripedTableCellRenderer sharedInstance = null; int columns = table.getColumnCount(); for (int i = 0; i < columns; i++) { TableColumn tc = table.getColumnModel().getColumn(i); TableCellRenderer targetRenderer = tc.getCellRenderer(); if (targetRenderer != null) { // This column has a specific renderer tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } else { // This column uses a class renderer - use a shared renderer if (sharedInstance == null) { sharedInstance = new StripedTableCellRenderer(null, evenBack, evenFore, oddBack, oddFore); } tc.setCellRenderer(sharedInstance); } } } protected TableCellRenderer targetRenderer; protected Color evenBack; protected Color evenFore; protected Color oddBack; protected Color oddFore;
} class FractionCellRenderer extends DefaultTableCellRenderer {
public FractionCellRenderer(int integer, int fraction, int align) { this.integer = integer; // maximum integer digits this.fraction = fraction; // exact number of fraction digits this.align = align; // alignment (LEFT, CENTER, RIGHT) } protected void setValue(Object value) { if (value != null && value instanceof Number) { formatter.setMaximumIntegerDigits(integer); formatter.setMaximumFractionDigits(fraction); formatter.setMinimumFractionDigits(fraction); setText(formatter.format(((Number) value).doubleValue())); } else { super.setValue(value); } setHorizontalAlignment(align); } protected int integer; protected int fraction; protected int align; protected static NumberFormat formatter = NumberFormat.getInstance();
} class TextWithIconCellRenderer extends DefaultTableCellRenderer {
protected void setValue(Object value) { if (value instanceof DataWithIcon) { if (value != null) { DataWithIcon d = (DataWithIcon)value; Object dataValue = d.getData(); setText(dataValue == null ? "" : dataValue.toString()); setIcon(d.getIcon()); setHorizontalTextPosition(SwingConstants.RIGHT); setVerticalTextPosition(SwingConstants.CENTER); setHorizontalAlignment(SwingConstants.LEFT); setVerticalAlignment(SwingConstants.CENTER); } else { setText(""); setIcon(null); } } else { super.setValue(value); } }
}
</source>
Swing Table in ComboBox
<source lang="java">
(From http://swinglabs.org/downloads.jsp)
</source>
Tabbable Currency Table
<source lang="java">
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall
- /
import java.awt.Color; import java.awt.ruponent; import java.awt.Dimension; import java.awt.Font; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.text.NumberFormat; import java.util.EventObject; import java.util.Vector; import javax.swing.CellEditor; import javax.swing.FocusManager; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.event.CellEditorListener; import javax.swing.event.ChangeEvent; import javax.swing.event.EventListenerList; import javax.swing.event.TableColumnModelEvent; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import javax.swing.table.TableModel; public class TabbableCurrencyTable {
public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception evt) {} JFrame f = new JFrame("Tabbable Currency Table"); TabEditTable tbl = new TabEditTable( new TestUpdatableCurrencyTableModel()); tbl.setDefaultRenderer(java.lang.Number.class, new FractionCellRenderer(10, 3, SwingConstants.RIGHT)); TableColumnModel tcm = tbl.getColumnModel(); tcm.getColumn(0).setPreferredWidth(150); tcm.getColumn(0).setMinWidth(150); TextWithIconCellRenderer renderer = new TextWithIconCellRenderer(); tcm.getColumn(0).setCellRenderer(renderer); tbl.setShowHorizontalLines(false); tbl.setIntercellSpacing(new Dimension(1, 0)); // Add the stripe renderer in the leftmost four columns. StripedTableCellRenderer.installInColumn(tbl, 0, Color.lightGray, Color.white, null, null); StripedTableCellRenderer.installInColumn(tbl, 1, Color.lightGray, Color.white, null, null); StripedTableCellRenderer.installInColumn(tbl, 2, Color.lightGray, Color.white, null, null); StripedTableCellRenderer.installInColumn(tbl, 3, Color.lightGray, Color.white, null, null); // Add the highlight renderer to the difference column. // The following comparator makes it highlight // cells with negative numeric values. Comparator cmp = new Comparator() { public boolean shouldHighlight(JTable tbl, Object value, int row, int column) { if (value instanceof Number) { double columnValue = ((Number) value).doubleValue(); return columnValue < (double) 0.0; } return false; } }; tcm.getColumn(3).setCellRenderer( new HighlightRenderer(cmp, null, Color.pink, Color.black, Color.pink.darker(), Color.white)); // Install a button renderer in the last column ButtonRenderer buttonRenderer = new ButtonRenderer(); buttonRenderer.setForeground(Color.blue); buttonRenderer.setBackground(Color.lightGray); tcm.getColumn(4).setCellRenderer(buttonRenderer); // Install a button editor in the last column TableCellEditor editor = new ButtonEditor(new JButton()); tcm.getColumn(4).setCellEditor(editor); // Install the list of columns containing tabbable editors tbl.setEditingColumns(new int[] { 1, 2 }); // Make the rows wide enough to take the buttons tbl.setRowHeight(20); tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tbl.setPreferredScrollableViewportSize(tbl.getPreferredSize()); JScrollPane sp = new JScrollPane(tbl); f.getContentPane().add(sp, "Center"); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); f.setVisible(true); }
} class TabEditTable extends JTable {
public TabEditTable() { super(); } public TabEditTable(TableModel dm) { super(dm); } public TabEditTable(TableModel dm, TableColumnModel cm) { super(dm, cm); } public TabEditTable(TableModel dm, TableColumnModel cm, ListSelectionModel sm) { super(dm, cm, sm); } public TabEditTable(int numRows, int numColumns) { super(numRows, numColumns); } public TabEditTable(final Vector rowData, final Vector columnNames) { super(rowData, columnNames); } public TabEditTable(final Object[][] rowData, final Object[] columnNames) { super(rowData, columnNames); } // Set the columns that contain tabbable editors public void setEditingColumns(int[] columns) { editingColumns = columns; convertEditableColumnsToView(); } public int[] getEditingColumns() { return editingColumns; } // Overrides of JTable methods public boolean editCellAt(int row, int column, EventObject evt) { if (super.editCellAt(row, column, evt) == false) { return false; } if (viewEditingColumns != null) { // Note: column is specified in terms of the column model int length = viewEditingColumns.length; for (int i = 0; i < length; i++) { if (column == viewEditingColumns[i]) { Component comp = getEditorComponent(); comp.addKeyListener(tabKeyListener); this.addKeyListener(tabKeyListener); focusManager = FocusManager.getCurrentManager(); FocusManager.disableSwingFocusManager(); inTabbingEditor = true; comp.requestFocus(); break; } } } return true; } public void editingStopped(ChangeEvent evt) { if (inTabbingEditor == true) { Component comp = getEditorComponent(); comp.removeKeyListener(tabKeyListener); this.removeKeyListener(tabKeyListener); FocusManager.setCurrentManager(focusManager); inTabbingEditor = false; } super.editingStopped(evt); } protected void convertEditableColumnsToView() { // Convert the editable columns to view column numbers if (editingColumns == null) { viewEditingColumns = null; return; } // Create a set of editable columns in terms of view // column numbers in ascending order. Note that not all // editable columns in the data model need be visible. int length = editingColumns.length; viewEditingColumns = new int[length]; int nextSlot = 0; for (int i = 0; i < length; i++) { int viewIndex = convertColumnIndexToView(editingColumns[i]); if (viewIndex != -1) { viewEditingColumns[nextSlot++] = viewIndex; } } // Now create an array of the right length to hold the view indices if (nextSlot < length) { int[] tempArray = new int[nextSlot]; System.arraycopy(viewEditingColumns, 0, tempArray, 0, nextSlot); viewEditingColumns = tempArray; } // Finally, sort the view columns into order TableUtilities.sort(viewEditingColumns); } protected void moveToNextEditor(int row, int column, boolean forward) { // Column is specified in terms of the column model if (viewEditingColumns != null) { int length = viewEditingColumns.length; // Move left-to-right or right-to-left across the table for (int i = 0; i < length; i++) { if (viewEditingColumns[i] == column) { // Select the next column to edit if (forward == true) { if (++i == length) { // Reached end of row - wrap i = 0; row++; if (row == getRowCount()) { // End of table - wrap row = 0; } } } else { if (--i < 0) { i = length - 1; row--; if (row < 0) { row = getRowCount() - 1; } } } final int newRow = row; final int newColumn = viewEditingColumns[i]; // Start editing at new location SwingUtilities.invokeLater(new Runnable() { public void run() { editCellAt(newRow, newColumn); ListSelectionModel rowSel = getSelectionModel(); ListSelectionModel columnSel = getColumnModel() .getSelectionModel(); rowSel.setSelectionInterval(newRow, newRow); columnSel .setSelectionInterval(newColumn, newColumn); } }); break; } } } } // Catch changes to the table column model public void columnAdded(TableColumnModelEvent e) { super.columnAdded(e); convertEditableColumnsToView(); } public void columnRemoved(TableColumnModelEvent e) { super.columnRemoved(e); convertEditableColumnsToView(); } public void columnMoved(TableColumnModelEvent e) { super.columnMoved(e); convertEditableColumnsToView(); } public class TabKeyListener extends KeyAdapter { public void keyPressed(KeyEvent evt) { if (evt.getKeyCode() == KeyEvent.VK_TAB) { if (inTabbingEditor == true) { TableCellEditor editor = getCellEditor(); int editRow = getEditingRow(); int editColumn = getEditingColumn(); if (editor != null) { boolean stopped = editor.stopCellEditing(); if (stopped == true) { boolean forward = (evt.isShiftDown() == false); moveToNextEditor(editRow, editColumn, forward); } } } } } } protected boolean inTabbingEditor; protected FocusManager focusManager; protected int[] editingColumns; // Model columns protected int[] viewEditingColumns; // View columns protected TabKeyListener tabKeyListener = new TabKeyListener();
} class FractionCellRenderer extends DefaultTableCellRenderer {
public FractionCellRenderer(int integer, int fraction, int align) { this.integer = integer; // maximum integer digits this.fraction = fraction; // exact number of fraction digits this.align = align; // alignment (LEFT, CENTER, RIGHT) } protected void setValue(Object value) { if (value != null && value instanceof Number) { formatter.setMaximumIntegerDigits(integer); formatter.setMaximumFractionDigits(fraction); formatter.setMinimumFractionDigits(fraction); setText(formatter.format(((Number) value).doubleValue())); } else { super.setValue(value); } setHorizontalAlignment(align); } protected int integer; protected int fraction; protected int align; protected static NumberFormat formatter = NumberFormat.getInstance();
} class TextWithIconCellRenderer extends DefaultTableCellRenderer {
protected void setValue(Object value) { if (value instanceof DataWithIcon) { if (value != null) { DataWithIcon d = (DataWithIcon) value; Object dataValue = d.getData(); setText(dataValue == null ? "" : dataValue.toString()); setIcon(d.getIcon()); setHorizontalTextPosition(SwingConstants.RIGHT); setVerticalTextPosition(SwingConstants.CENTER); setHorizontalAlignment(SwingConstants.LEFT); setVerticalAlignment(SwingConstants.CENTER); } else { setText(""); setIcon(null); } } else { super.setValue(value); } }
} class DataWithIcon {
public DataWithIcon(Object data, Icon icon) { this.data = data; this.icon = icon; } public Icon getIcon() { return icon; } public Object getData() { return data; } public String toString() { return data.toString(); } protected Icon icon; protected Object data;
} class TableUtilities {
// Calculate the required width of a table column public static int calculateColumnWidth(JTable table, int columnIndex) { int width = 0; // The return value int rowCount = table.getRowCount(); for (int i = 0; i < rowCount; i++) { TableCellRenderer renderer = table.getCellRenderer(i, columnIndex); Component comp = renderer.getTableCellRendererComponent(table, table.getValueAt(i, columnIndex), false, false, i, columnIndex); int thisWidth = comp.getPreferredSize().width; if (thisWidth > width) { width = thisWidth; } } return width; } // Set the widths of every column in a table public static void setColumnWidths(JTable table, Insets insets, boolean setMinimum, boolean setMaximum) { int columnCount = table.getColumnCount(); TableColumnModel tcm = table.getColumnModel(); int spare = (insets == null ? 0 : insets.left + insets.right); for (int i = 0; i < columnCount; i++) { int width = calculateColumnWidth(table, i); width += spare; TableColumn column = tcm.getColumn(i); column.setPreferredWidth(width); if (setMinimum == true) { column.setMinWidth(width); } if (setMaximum == true) { column.setMaxWidth(width); } } } // Sort an array of integers in place public static void sort(int[] values) { int length = values.length; if (length > 1) { for (int i = 0; i < length - 1; i++) { for (int j = i + 1; j < length; j++) { if (values[j] < values[i]) { int temp = values[i]; values[i] = values[j]; values[j] = temp; } } } } }
} class StripedTableCellRenderer implements TableCellRenderer {
public StripedTableCellRenderer(TableCellRenderer targetRenderer, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { this.targetRenderer = targetRenderer; this.evenBack = evenBack; this.evenFore = evenFore; this.oddBack = oddBack; this.oddFore = oddFore; } // Implementation of TableCellRenderer interface public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { TableCellRenderer renderer = targetRenderer; if (renderer == null) { // Get default renderer from the table renderer = table.getDefaultRenderer(table.getColumnClass(column)); } // Let the real renderer create the component Component comp = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); // Now apply the stripe effect if (isSelected == false && hasFocus == false) { if ((row & 1) == 0) { comp.setBackground(evenBack != null ? evenBack : table .getBackground()); comp.setForeground(evenFore != null ? evenFore : table .getForeground()); } else { comp.setBackground(oddBack != null ? oddBack : table .getBackground()); comp.setForeground(oddFore != null ? oddFore : table .getForeground()); } } return comp; } // Convenience method to apply this renderer to single column public static void installInColumn(JTable table, int columnIndex, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { TableColumn tc = table.getColumnModel().getColumn(columnIndex); // Get the cell renderer for this column, if any TableCellRenderer targetRenderer = tc.getCellRenderer(); // Create a new StripedTableCellRenderer and install it tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } // Convenience method to apply this renderer to an entire table public static void installInTable(JTable table, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { StripedTableCellRenderer sharedInstance = null; int columns = table.getColumnCount(); for (int i = 0; i < columns; i++) { TableColumn tc = table.getColumnModel().getColumn(i); TableCellRenderer targetRenderer = tc.getCellRenderer(); if (targetRenderer != null) { // This column has a specific renderer tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } else { // This column uses a class renderer - use a shared renderer if (sharedInstance == null) { sharedInstance = new StripedTableCellRenderer(null, evenBack, evenFore, oddBack, oddFore); } tc.setCellRenderer(sharedInstance); } } } protected TableCellRenderer targetRenderer; protected Color evenBack; protected Color evenFore; protected Color oddBack; protected Color oddFore;
} class HighlightRenderer implements TableCellRenderer {
public HighlightRenderer(Comparator cmp, TableCellRenderer targetRenderer, Color backColor, Color foreColor, Color highlightBack, Color highlightFore) { this.cmp = cmp; this.targetRenderer = targetRenderer; this.backColor = backColor; this.foreColor = foreColor; this.highlightBack = highlightBack; this.highlightFore = highlightFore; } public Component getTableCellRendererComponent(JTable tbl, Object value, boolean isSelected, boolean hasFocus, int row, int column) { TableCellRenderer renderer = targetRenderer; if (renderer == null) { renderer = tbl.getDefaultRenderer(tbl.getColumnClass(column)); } Component comp = renderer.getTableCellRendererComponent(tbl, value, isSelected, hasFocus, row, column); if (isSelected == false && hasFocus == false && value != null) { if (cmp.shouldHighlight(tbl, value, row, column)) { comp.setForeground(highlightFore); comp.setBackground(highlightBack); } else { comp.setForeground(foreColor); comp.setBackground(backColor); } } return comp; } protected Comparator cmp; protected TableCellRenderer targetRenderer; protected Color backColor; protected Color foreColor; protected Color highlightBack; protected Color highlightFore;
} interface Comparator {
public abstract boolean shouldHighlight(JTable tbl, Object value, int row, int column);
} class ButtonRenderer extends JButton implements TableCellRenderer {
public ButtonRenderer() { this.border = getBorder(); this.setOpaque(true); } public void setForeground(Color foreground) { this.foreground = foreground; super.setForeground(foreground); } public void setBackground(Color background) { this.background = background; super.setBackground(background); } public void setFont(Font font) { this.font = font; super.setFont(font); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Color cellForeground = foreground != null ? foreground : table .getForeground(); Color cellBackground = background != null ? background : table .getBackground(); setFont(font != null ? font : table.getFont()); if (hasFocus) { setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); if (table.isCellEditable(row, column)) { cellForeground = UIManager .getColor("Table.focusCellForeground"); cellBackground = UIManager .getColor("Table.focusCellBackground"); } } else { setBorder(border); } super.setForeground(cellForeground); super.setBackground(cellBackground); // Customize the component"s appearance setValue(value); return this; } protected void setValue(Object value) { if (value == null) { setText(""); setIcon(null); } else if (value instanceof Icon) { setText(""); setIcon((Icon) value); } else if (value instanceof DataWithIcon) { DataWithIcon d = (DataWithIcon) value; setText(d.toString()); setIcon(d.getIcon()); } else { setText(value.toString()); setIcon(null); } } protected Color foreground; protected Color background; protected Font font; protected Border border;
} class ButtonEditor extends BasicCellEditor implements ActionListener,
TableCellEditor { public ButtonEditor(JButton button) { super(button); button.addActionListener(this); } public void setForeground(Color foreground) { this.foreground = foreground; editor.setForeground(foreground); } public void setBackground(Color background) { this.background = background; editor.setBackground(background); } public void setFont(Font font) { this.font = font; editor.setFont(font); } public Object getCellEditorValue() { return value; } public void editingStarted(EventObject event) { // Edit starting - click the button if necessary if (!(event instanceof MouseEvent)) { // Keyboard event - click the button SwingUtilities.invokeLater(new Runnable() { public void run() { ((JButton) editor).doClick(); } }); } } public Component getTableCellEditorComponent(JTable tbl, Object value, boolean isSelected, int row, int column) { editor.setForeground(foreground != null ? foreground : tbl .getForeground()); editor.setBackground(background != null ? background : tbl .getBackground()); editor.setFont(font != null ? font : tbl.getFont()); this.value = value; setValue(value); return editor; } protected void setValue(Object value) { JButton button = (JButton) editor; if (value == null) { button.setText(""); button.setIcon(null); } else if (value instanceof Icon) { button.setText(""); button.setIcon((Icon) value); } else if (value instanceof DataWithIcon) { DataWithIcon d = (DataWithIcon) value; button.setText(d.toString()); button.setIcon(d.getIcon()); } else { button.setText(value.toString()); button.setIcon(null); } } public void actionPerformed(ActionEvent evt) { // Button pressed - stop the edit stopCellEditing(); } protected Object value; protected Color foreground; protected Color background; protected Font font;
} class BasicCellEditor implements CellEditor, PropertyChangeListener {
public BasicCellEditor() { this.editor = null; } public BasicCellEditor(JComponent editor) { this.editor = editor; editor.addPropertyChangeListener(this); } public Object getCellEditorValue() { return null; } public boolean isCellEditable(EventObject evt) { editingEvent = evt; return true; } public boolean shouldSelectCell(EventObject evt) { return true; } public boolean stopCellEditing() { fireEditingStopped(); return true; } public void cancelCellEditing() { fireEditingCanceled(); } public void addCellEditorListener(CellEditorListener l) { listeners.add(CellEditorListener.class, l); } public void removeCellEditorListener(CellEditorListener l) { listeners.remove(CellEditorListener.class, l); } // Returns the editing component public JComponent getComponent() { return editor; } // Sets the editing component public void setComponent(JComponent comp) { editor = comp; } // Returns the event that triggered the edit public EventObject getEditingEvent() { return editingEvent; } // Method invoked when the editor is installed in the table. // Overridden in derived classes to take any convenient // action. public void editingStarted(EventObject event) { } protected void fireEditingStopped() { Object[] l = listeners.getListenerList(); for (int i = l.length - 2; i >= 0; i -= 2) { if (l[i] == CellEditorListener.class) { if (changeEvent == null) { changeEvent = new ChangeEvent(this); } ((CellEditorListener) l[i + 1]).editingStopped(changeEvent); } } } protected void fireEditingCanceled() { Object[] l = listeners.getListenerList(); for (int i = l.length - 2; i >= 0; i -= 2) { if (l[i] == CellEditorListener.class) { if (changeEvent == null) { changeEvent = new ChangeEvent(this); } ((CellEditorListener) l[i + 1]).editingCanceled(changeEvent); } } } // Implementation of the PropertyChangeListener interface public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals("ancestor") && evt.getNewValue() != null) { // Added to table - notify the editor editingStarted(editingEvent); } } protected static JCheckBox checkBox = new JCheckBox(); protected static ChangeEvent changeEvent; protected JComponent editor; protected EventListenerList listeners = new EventListenerList(); protected EventObject editingEvent;
} class TestUpdatableCurrencyTableModel extends UpdatableCurrencyTableModel {
public void updateTable(Object value, int row, int column) { System.out.println("Update for row " + row + " required."); System.out.println("Values are " + getValueAt(row, 1) + ", " + getValueAt(row, 2) + "; diff is " + getValueAt(row, 3)); }
} abstract class UpdatableCurrencyTableModel extends EditableCurrencyTableModel {
public int getColumnCount() { return super.getColumnCount() + 1; } public Object getValueAt(int row, int column) { if (column == BUTTON_COLUMN) { return "Update"; } return super.getValueAt(row, column); } public Class getColumnClass(int column) { if (column == BUTTON_COLUMN) { return String.class; } return super.getColumnClass(column); } public String getColumnName(int column) { if (column == BUTTON_COLUMN) { return ""; } return super.getColumnName(column); } public boolean isCellEditable(int row, int column) { return column == BUTTON_COLUMN || super.isCellEditable(row, column); } public void setValueAt(Object value, int row, int column) { if (column == BUTTON_COLUMN) { // Button press - do whatever is needed to update the table source updateTable(value, row, column); return; } // Other columns - use superclass super.setValueAt(value, row, column); } // Used to implement the table update protected abstract void updateTable(Object value, int row, int column); protected static final int BUTTON_COLUMN = 4;
} class EditableCurrencyTableModel extends CurrencyTableModel {
public boolean isCellEditable(int row, int column) { return column == OLD_RATE_COLUMN || column == NEW_RATE_COLUMN; } public void setValueAt(Object value, int row, int column) { try { if (column == OLD_RATE_COLUMN || column == NEW_RATE_COLUMN) { Double newObjectValue; // New value as an Object double newValue; // double, for validity checking if (value instanceof Number) { // Convert Number to Double newValue = ((Number) value).doubleValue(); newObjectValue = new Double(newValue); } else if (value instanceof String) { // Convert a String to a Double newObjectValue = new Double((String) value); newValue = newObjectValue.doubleValue(); } else { // Unrecognized - ignore return; } if (newValue > (double) 0.0) { // Store new value, but reject zero or negative values data[row][column] = newObjectValue; data[row][DIFF_COLUMN] = new Double( ((Double) data[row][NEW_RATE_COLUMN]).doubleValue() - ((Double) data[row][OLD_RATE_COLUMN]) .doubleValue()); fireTableRowsUpdated(row, row); } } } catch (NumberFormatException e) { // Ignore a badly-formatted number } }
} class CurrencyTableModel extends AbstractTableModel {
protected String[] columnNames = { "Currency", "Yesterday", "Today", "Change" }; // Constructor: calculate currency change to create the last column public CurrencyTableModel() { for (int i = 0; i < data.length; i++) { data[i][DIFF_COLUMN] = new Double( ((Double) data[i][NEW_RATE_COLUMN]).doubleValue() - ((Double) data[i][OLD_RATE_COLUMN]).doubleValue()); } } // Implementation of TableModel interface public int getRowCount() { return data.length; } public int getColumnCount() { return COLUMN_COUNT; } public Object getValueAt(int row, int column) { return data[row][column]; } public Class getColumnClass(int column) { return (data[0][column]).getClass(); } public String getColumnName(int column) { return columnNames[column]; } protected static final int OLD_RATE_COLUMN = 1; protected static final int NEW_RATE_COLUMN = 2; protected static final int DIFF_COLUMN = 3; protected static final int COLUMN_COUNT = 4; protected static final Class thisClass = CurrencyTableModel.class; protected Object[][] data = new Object[][] { { new DataWithIcon("Belgian Franc", new ImageIcon(thisClass .getResource("belgium.gif"))), new Double(37.6460110), new Double(37.6508921), null }, { new DataWithIcon("British Pound", new ImageIcon(thisClass .getResource("gb.gif"))), new Double(0.6213051), new Double(0.6104102), null }, { new DataWithIcon("Canadian Dollar", new ImageIcon(thisClass .getResource("canada.gif"))), new Double(1.4651209), new Double(1.5011104), null }, { new DataWithIcon("French Franc", new ImageIcon(thisClass .getResource("france.gif"))), new Double(6.1060001), new Double(6.0100101), null }, { new DataWithIcon("Italian Lire", new ImageIcon(thisClass .getResource("italy.gif"))), new Double(1181.3668977), new Double(1182.104), null }, { new DataWithIcon("German Mark", new ImageIcon(thisClass .getResource("germany.gif"))), new Double(1.8191804), new Double(1.8223421), null }, { new DataWithIcon("Japanese Yen", new ImageIcon(thisClass .getResource("japan.gif"))), new Double(141.0815412), new Double(121.0040432), null } };
}
</source>
Table Row Header Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1beta3) */ import java.awt.BorderLayout; import java.awt.ruponent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.AbstractListModel; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.ListCellRenderer; import javax.swing.ListModel; import javax.swing.UIManager; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; /**
* @version 1.0 11/09/98 */
class RowHeaderRenderer extends JLabel implements ListCellRenderer {
RowHeaderRenderer(JTable table) { JTableHeader header = table.getTableHeader(); setOpaque(true); setBorder(UIManager.getBorder("TableHeader.cellBorder")); setHorizontalAlignment(CENTER); setForeground(header.getForeground()); setBackground(header.getBackground()); setFont(header.getFont()); } public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { setText((value == null) ? "" : value.toString()); return this; }
} public class RowHeaderExample extends JFrame {
public RowHeaderExample() { super("Row Header Example"); setSize(300, 150); ListModel lm = new AbstractListModel() { String headers[] = { "a", "b", "c", "d", "e", "f", "g", "h", "i" }; public int getSize() { return headers.length; } public Object getElementAt(int index) { return headers[index]; } }; DefaultTableModel dm = new DefaultTableModel(lm.getSize(), 10); JTable table = new JTable(dm); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); JList rowHeader = new JList(lm); rowHeader.setFixedCellWidth(50); rowHeader.setFixedCellHeight(table.getRowHeight() + table.getRowMargin()); // + table.getIntercellSpacing().height); rowHeader.setCellRenderer(new RowHeaderRenderer(table)); JScrollPane scroll = new JScrollPane(table); scroll.setRowHeaderView(rowHeader); getContentPane().add(scroll, BorderLayout.CENTER); } public static void main(String[] args) { RowHeaderExample frame = new RowHeaderExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); }
}
</source>
Table Utilities
<source lang="java">
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall
- /
import javax.swing.*; import javax.swing.table.*; import java.awt.*; public class TableUtilities {
// Calculate the required width of a table column public static int calculateColumnWidth(JTable table, int columnIndex) { int width = 0; // The return value int rowCount = table.getRowCount(); for (int i = 0; i < rowCount ; i++) { TableCellRenderer renderer = table.getCellRenderer(i, columnIndex); Component comp = renderer.getTableCellRendererComponent( table, table.getValueAt(i, columnIndex), false, false, i, columnIndex); int thisWidth = comp.getPreferredSize().width; if (thisWidth > width) { width = thisWidth; } } return width; } // Set the widths of every column in a table public static void setColumnWidths(JTable table, Insets insets, boolean setMinimum, boolean setMaximum) { int columnCount = table.getColumnCount(); TableColumnModel tcm = table.getColumnModel(); int spare = (insets == null ? 0 : insets.left + insets.right); for (int i = 0; i < columnCount; i++) { int width = calculateColumnWidth(table, i); width += spare; TableColumn column = tcm.getColumn(i); column.setPreferredWidth(width); if (setMinimum == true) { column.setMinWidth(width); } if (setMaximum == true) { column.setMaxWidth(width); } } } // Sort an array of integers in place public static void sort(int[] values) { int length = values.length; if (length > 1) { for (int i = 0; i < length - 1 ; i++) { for (int j = i + 1; j < length; j++) { if (values[j] < values[i]) { int temp = values[i]; values[i] = values[j]; values[j] = temp; } } } } }
}
</source>
ToolTip Header Table Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1) */
import java.awt.BorderLayout; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; import javax.swing.table.TableColumnModel; /**
* @version 1.0 02/25/99 */
public class ToolTipHeaderTableExample extends JPanel {
public ToolTipHeaderTableExample() { setLayout(new BorderLayout()); String[] headerStr = { "default", "jw", "ja", "la", "unknown" }; String[] toolTipStr = { "", "Javanese", "Japanese", "Latin" }; DefaultTableModel dm = new DefaultTableModel(headerStr, 4); JTable table = new JTable(dm); ToolTipHeader header = new ToolTipHeader(table.getColumnModel()); header.setToolTipStrings(toolTipStr); header.setToolTipText("Default ToolTip TEXT"); table.setTableHeader(header); JScrollPane pane = new JScrollPane(table); add(pane, BorderLayout.CENTER); } public static void main(String[] args) { JFrame f = new JFrame("ToolTipHeaderTable Example"); f.getContentPane().add(new ToolTipHeaderTableExample(), BorderLayout.CENTER); f.setSize(400, 100); f.setVisible(true); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } class ToolTipHeader extends JTableHeader { String[] toolTips; public ToolTipHeader(TableColumnModel model) { super(model); } public String getToolTipText(MouseEvent e) { int col = columnAtPoint(e.getPoint()); int modelCol = getTable().convertColumnIndexToModel(col); String retStr; try { retStr = toolTips[modelCol]; } catch (NullPointerException ex) { retStr = ""; } catch (ArrayIndexOutOfBoundsException ex) { retStr = ""; } if (retStr.length() < 1) { retStr = super.getToolTipText(e); } return retStr; } public void setToolTipStrings(String[] toolTips) { this.toolTips = toolTips; } }
}
</source>
ToolTip Table
<source lang="java">
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall
- /
import java.awt.Color; import java.awt.ruponent; import java.awt.Font; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.text.NumberFormat; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.JTableHeader; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; public class ToolTipTable {
public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception evt) {} JFrame f = new JFrame("Tool Tip Table"); JTable tbl = new JTable(new CurrencyTableModel()); tbl .setDefaultRenderer(java.lang.Number.class, new ToolTipFractionCellRenderer(10, 3, 6, SwingConstants.RIGHT)); TableColumnModel tcm = tbl.getColumnModel(); tcm.getColumn(0).setPreferredWidth(150); tcm.getColumn(0).setMinWidth(150); TextWithIconCellRenderer renderer = new TextWithIconCellRenderer(); tcm.getColumn(0).setCellRenderer(renderer); tcm.getColumn(1).setPreferredWidth(100); tcm.getColumn(1).setMinWidth(100); // Add the stripe renderer. StripedTableCellRenderer.installInTable(tbl, Color.lightGray, Color.white, null, null); // Add the custom header renderer MultiLineHeaderRenderer headerRenderer = new MultiLineHeaderRenderer( SwingConstants.CENTER, SwingConstants.BOTTOM); headerRenderer.setBackground(Color.blue); headerRenderer.setForeground(Color.white); headerRenderer.setFont(new Font("Dialog", Font.BOLD, 12)); int columns = tableHeaders.length; for (int i = 0; i < columns; i++) { tcm.getColumn(i).setHeaderRenderer(headerRenderer); tcm.getColumn(i).setHeaderValue(tableHeaders[i]); } tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tbl.setPreferredScrollableViewportSize(tbl.getPreferredSize()); JScrollPane sp = new JScrollPane(tbl); f.getContentPane().add(sp, "Center"); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); f.setVisible(true); } // Header values. Note the table model provides // string column names that are the default header // values. public static Object[][] tableHeaders = new Object[][] { new String[] { "Currency" }, new String[] { "Yesterday"s", "Rate" }, new String[] { "Today"s", "Rate" }, new String[] { "Rate", "Change" } };
} class FractionCellRenderer extends DefaultTableCellRenderer {
public FractionCellRenderer(int integer, int fraction, int align) { this.integer = integer; // maximum integer digits this.fraction = fraction; // exact number of fraction digits this.align = align; // alignment (LEFT, CENTER, RIGHT) } protected void setValue(Object value) { if (value != null && value instanceof Number) { formatter.setMaximumIntegerDigits(integer); formatter.setMaximumFractionDigits(fraction); formatter.setMinimumFractionDigits(fraction); setText(formatter.format(((Number) value).doubleValue())); } else { super.setValue(value); } setHorizontalAlignment(align); } protected int integer; protected int fraction; protected int align; protected static NumberFormat formatter = NumberFormat.getInstance();
} class TextWithIconCellRenderer extends DefaultTableCellRenderer {
protected void setValue(Object value) { if (value instanceof DataWithIcon) { if (value != null) { DataWithIcon d = (DataWithIcon) value; Object dataValue = d.getData(); setText(dataValue == null ? "" : dataValue.toString()); setIcon(d.getIcon()); setHorizontalTextPosition(SwingConstants.RIGHT); setVerticalTextPosition(SwingConstants.CENTER); setHorizontalAlignment(SwingConstants.LEFT); setVerticalAlignment(SwingConstants.CENTER); } else { setText(""); setIcon(null); } } else { super.setValue(value); } }
} class MultiLineHeaderRenderer extends JPanel implements TableCellRenderer {
public MultiLineHeaderRenderer(int horizontalAlignment, int verticalAlignment) { this.horizontalAlignment = horizontalAlignment; this.verticalAlignment = verticalAlignment; switch (horizontalAlignment) { case SwingConstants.LEFT: alignmentX = (float) 0.0; break; case SwingConstants.CENTER: alignmentX = (float) 0.5; break; case SwingConstants.RIGHT: alignmentX = (float) 1.0; break; default: throw new IllegalArgumentException( "Illegal horizontal alignment value"); } setBorder(headerBorder); setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); setOpaque(true); background = null; } public void setForeground(Color foreground) { this.foreground = foreground; super.setForeground(foreground); } public void setBackground(Color background) { this.background = background; super.setBackground(background); } public void setFont(Font font) { this.font = font; } // Implementation of TableCellRenderer interface public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { removeAll(); invalidate(); if (value == null) { // Do nothing if no value return this; } // Set the foreground and background colors // from the table header if they are not set if (table != null) { JTableHeader header = table.getTableHeader(); if (header != null) { if (foreground == null) { super.setForeground(header.getForeground()); } if (background == null) { super.setBackground(header.getBackground()); } } } if (verticalAlignment != SwingConstants.TOP) { add(Box.createVerticalGlue()); } Object[] values; int length; if (value instanceof Object[]) { // Input is an array - use it values = (Object[]) value; } else { // Not an array - turn it into one values = new Object[1]; values[0] = value; } length = values.length; // Configure each row of the header using // a separate JLabel. If a given row is // a JComponent, add it directly.. for (int i = 0; i < length; i++) { Object thisRow = values[i]; if (thisRow instanceof JComponent) { add((JComponent) thisRow); } else { JLabel l = new JLabel(); setValue(l, thisRow, i); add(l); } } if (verticalAlignment != SwingConstants.BOTTOM) { add(Box.createVerticalGlue()); } return this; } // Configures a label for one line of the header. // This can be overridden by derived classes protected void setValue(JLabel l, Object value, int lineNumber) { if (value != null && value instanceof Icon) { l.setIcon((Icon) value); } else { l.setText(value == null ? "" : value.toString()); } l.setHorizontalAlignment(horizontalAlignment); l.setAlignmentX(alignmentX); l.setOpaque(false); l.setForeground(foreground); l.setFont(font); } protected int verticalAlignment; protected int horizontalAlignment; protected float alignmentX; // These attributes may be explicitly set // They are defaulted to the colors and attributes // of the table header protected Color foreground; protected Color background; // These attributes have fixed defaults protected Border headerBorder = UIManager .getBorder("TableHeader.cellBorder"); protected Font font = UIManager.getFont("TableHeader.font");
} class DataWithIcon {
public DataWithIcon(Object data, Icon icon) { this.data = data; this.icon = icon; } public Icon getIcon() { return icon; } public Object getData() { return data; } public String toString() { return data.toString(); } protected Icon icon; protected Object data;
} class CurrencyTableModel extends AbstractTableModel {
protected String[] columnNames = { "Currency", "Yesterday", "Today", "Change" }; // Constructor: calculate currency change to create the last column public CurrencyTableModel() { for (int i = 0; i < data.length; i++) { data[i][DIFF_COLUMN] = new Double( ((Double) data[i][NEW_RATE_COLUMN]).doubleValue() - ((Double) data[i][OLD_RATE_COLUMN]).doubleValue()); } } // Implementation of TableModel interface public int getRowCount() { return data.length; } public int getColumnCount() { return COLUMN_COUNT; } public Object getValueAt(int row, int column) { return data[row][column]; } public Class getColumnClass(int column) { return (data[0][column]).getClass(); } public String getColumnName(int column) { return columnNames[column]; } protected static final int OLD_RATE_COLUMN = 1; protected static final int NEW_RATE_COLUMN = 2; protected static final int DIFF_COLUMN = 3; protected static final int COLUMN_COUNT = 4; protected static final Class thisClass = CurrencyTableModel.class; protected Object[][] data = new Object[][] { { new DataWithIcon("Belgian Franc", new ImageIcon(thisClass .getResource("belgium.gif"))), new Double(37.6460110), new Double(37.6508921), null }, { new DataWithIcon("British Pound", new ImageIcon(thisClass .getResource("gb.gif"))), new Double(0.6213051), new Double(0.6104102), null }, { new DataWithIcon("Canadian Dollar", new ImageIcon(thisClass .getResource("canada.gif"))), new Double(1.4651209), new Double(1.5011104), null }, { new DataWithIcon("French Franc", new ImageIcon(thisClass .getResource("france.gif"))), new Double(6.1060001), new Double(6.0100101), null }, { new DataWithIcon("Italian Lire", new ImageIcon(thisClass .getResource("italy.gif"))), new Double(1181.3668977), new Double(1182.104), null }, { new DataWithIcon("German Mark", new ImageIcon(thisClass .getResource("germany.gif"))), new Double(1.8191804), new Double(1.8223421), null }, { new DataWithIcon("Japanese Yen", new ImageIcon(thisClass .getResource("japan.gif"))), new Double(141.0815412), new Double(121.0040432), null } };
} class ToolTipFractionCellRenderer extends FractionCellRenderer {
public ToolTipFractionCellRenderer(int integer, int fraction, int maxFraction, int align) { super(integer, fraction, align); this.maxFraction = maxFraction; // Number of tooltip fraction digits } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Component comp = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); if (value != null && value instanceof Number) { formatter.setMaximumIntegerDigits(integer); formatter.setMaximumFractionDigits(maxFraction); formatter.setMinimumFractionDigits(maxFraction); ((JComponent) comp).setToolTipText(formatter .format(((Number) value).doubleValue())); } return comp; } protected int maxFraction;
} class StripedTableCellRenderer implements TableCellRenderer {
public StripedTableCellRenderer(TableCellRenderer targetRenderer, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { this.targetRenderer = targetRenderer; this.evenBack = evenBack; this.evenFore = evenFore; this.oddBack = oddBack; this.oddFore = oddFore; } // Implementation of TableCellRenderer interface public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { TableCellRenderer renderer = targetRenderer; if (renderer == null) { // Get default renderer from the table renderer = table.getDefaultRenderer(table.getColumnClass(column)); } // Let the real renderer create the component Component comp = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); // Now apply the stripe effect if (isSelected == false && hasFocus == false) { if ((row & 1) == 0) { comp.setBackground(evenBack != null ? evenBack : table .getBackground()); comp.setForeground(evenFore != null ? evenFore : table .getForeground()); } else { comp.setBackground(oddBack != null ? oddBack : table .getBackground()); comp.setForeground(oddFore != null ? oddFore : table .getForeground()); } } return comp; } // Convenience method to apply this renderer to single column public static void installInColumn(JTable table, int columnIndex, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { TableColumn tc = table.getColumnModel().getColumn(columnIndex); // Get the cell renderer for this column, if any TableCellRenderer targetRenderer = tc.getCellRenderer(); // Create a new StripedTableCellRenderer and install it tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } // Convenience method to apply this renderer to an entire table public static void installInTable(JTable table, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { StripedTableCellRenderer sharedInstance = null; int columns = table.getColumnCount(); for (int i = 0; i < columns; i++) { TableColumn tc = table.getColumnModel().getColumn(i); TableCellRenderer targetRenderer = tc.getCellRenderer(); if (targetRenderer != null) { // This column has a specific renderer tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } else { // This column uses a class renderer - use a shared renderer if (sharedInstance == null) { sharedInstance = new StripedTableCellRenderer(null, evenBack, evenFore, oddBack, oddFore); } tc.setCellRenderer(sharedInstance); } } } protected TableCellRenderer targetRenderer; protected Color evenBack; protected Color evenFore; protected Color oddBack; protected Color oddFore;
}
</source>
Total(Calculate) Row Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /*
* (swing1.1beta3) swing#960 */
import java.awt.Container; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.text.DecimalFormat; import java.text.ParseException; import java.util.Vector; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.event.ChangeEvent; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableModel; /**
* @version 1.0 12/03/98 */
class DecimalRenderer extends DefaultTableCellRenderer {
DecimalFormat formatter; DecimalRenderer(String pattern) { this(new DecimalFormat(pattern)); } DecimalRenderer(DecimalFormat formatter) { this.formatter = formatter; setHorizontalAlignment(JLabel.RIGHT); } public void setValue(Object value) { setText((value == null) ? "" : formatter.format(((Double) value) .doubleValue())); }
} public class TotalRowExample extends JFrame {
final private int TOTAL_ROW = 3; final private int TOTAL_COLUMN = 1; TotalRowExample() { super("Total Row Example"); final DecimalFormat formatter = new DecimalFormat("###,##0.00"); DefaultTableModel dm = new DefaultTableModel() { public void setValueAt(Object value, int row, int col) { Vector rowVector = (Vector) dataVector.elementAt(row); if (col == TOTAL_COLUMN) { Double d = null; if (value instanceof Double) { d = (Double) value; } else { try { d = new Double(((Number) formatter .parse((String) value)).doubleValue()); } catch (ParseException ex) { d = new Double(0.0); } } rowVector.setElementAt(d, col); } else { rowVector.setElementAt(value, col); } } public boolean isCellEditable(int row, int col) { if (row == TOTAL_ROW) return false; return true; } public Class getColumnClass(int col) { if (col == TOTAL_COLUMN) return Number.class; return String.class; } }; dm.setDataVector(new Object[][] { { "coffee", new Double(0.0) }, { "tea", new Double(0.0) }, { "cocoa", new Double(0.0) }, { "total", new Double(0.0) } }, new Object[] { "Item", "Price" }); JTable table = new JTable(dm) { public void editingStopped(ChangeEvent e) { super.editingStopped(e); reCalcurate(getModel()); repaint(); } }; table.getColumn("Price") .setCellRenderer(new DecimalRenderer(formatter)); JScrollPane scroll = new JScrollPane(table); Container content = getContentPane(); content.add(scroll); setSize(300, 120); setVisible(true); } private void reCalcurate(TableModel ml) { if (ml == null) return; double total = 0.0; for (int i = 0; i < TOTAL_ROW; i++) { total += ((Double) ml.getValueAt(i, TOTAL_COLUMN)).doubleValue(); } ml.setValueAt(new Double(total), TOTAL_ROW, TOTAL_COLUMN); } public static void main(String[] args) { TotalRowExample frame = new TotalRowExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); }
}
</source>
Union Data Table Example
<source lang="java">
// Example from http://www.crionics.ru/products/opensource/faq/swing_ex/SwingExamples.html /* (swing1.1beta3) */
import java.awt.Container; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Vector; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.SwingConstants; import javax.swing.event.TableModelEvent; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableModel; /**
* @version 1.0 11/09/98 */
public class UnionDataExample extends JFrame {
UnionDataExample() { super("UnionData Example"); setSize(300, 200); final String[] headers = { "a", "b", "c", "d" }; final String[][] data = new String[6][headers.length]; final AbstractTableModel dmAB = new AbstractTableModel() { public int getRowCount() { return data.length; } public int getColumnCount() { return headers.length; } public String getColumnName(int col) { return headers[col]; } public Object getValueAt(int row, int col) { return data[row][col]; } }; final int rowCountA = 3; DefaultTableModel dmA = new DefaultTableModel(data, headers) { public int getRowCount() { return rowCountA; } public Object getValueAt(int row, int col) { Vector rowVector = (Vector) dataVector.elementAt(row); return rowVector.elementAt(col); } public void setValueAt(Object value, int row, int col) { data[row][col] = (String) value; Vector rowVector = (Vector) dataVector.elementAt(row); rowVector.setElementAt(value, col); TableModelEvent event = new TableModelEvent(this, row, row, col); fireTableChanged(event); dmAB.fireTableChanged(event); } }; DefaultTableModel dmB = new DefaultTableModel(data, headers) { public int getRowCount() { return rowCountA; } //public int getRowCount() { return data.length - rowCountA; } public Object getValueAt(int row, int col) {
// Vector rowVector = (Vector) dataVector.elementAt(row
// + rowCountA); Vector rowVector = (Vector) dataVector.elementAt(2); return rowVector.elementAt(col); } public void setValueAt(Object value, int row, int col) { int sRow = row + rowCountA; data[sRow][col] = (String) value; Vector rowVector = (Vector) dataVector.elementAt(sRow); rowVector.setElementAt(value, col); TableModelEvent event = new TableModelEvent(this, sRow, sRow, col); fireTableChanged(event); dmAB.fireTableChanged(event); } }; JScrollPane scrollA = new JScrollPane(new JTable(dmA)); JScrollPane scrollB = new JScrollPane(new JTable(dmB)); JScrollPane scrollAB = new JScrollPane(new JTable(dmAB)); Box box = new Box(BoxLayout.Y_AXIS); box.add(new JLabel("Table A")); box.add(scrollA); box.add(new JSeparator(SwingConstants.VERTICAL)); box.add(new JLabel("Table B")); box.add(scrollB); Box boxAB = new Box(BoxLayout.Y_AXIS); boxAB.add(new JLabel("Table A + B")); boxAB.add(scrollAB); Container content = getContentPane(); content.setLayout(new BoxLayout(content, BoxLayout.X_AXIS)); content.add(box); content.add(new JSeparator(SwingConstants.HORIZONTAL)); content.add(boxAB); } public static void main(String[] args) { UnionDataExample frame = new UnionDataExample(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setVisible(true); }
}
</source>
Updatable Highlight Currency Table
<source lang="java">
/* Core SWING Advanced Programming By Kim Topley ISBN: 0 13 083292 8 Publisher: Prentice Hall
- /
import java.awt.Color; import java.awt.ruponent; import java.awt.Dimension; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.text.NumberFormat; import java.util.EventObject; import javax.swing.CellEditor; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.border.Border; import javax.swing.event.CellEditorListener; import javax.swing.event.ChangeEvent; import javax.swing.event.EventListenerList; import javax.swing.table.AbstractTableModel; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; public class UpdatableHighlightCurrencyTable {
public static void main(String[] args) { try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); } catch (Exception evt) {} JFrame f = new JFrame("Updatable Highlighted Currency Table"); JTable tbl = new JTable(new TestUpdatableCurrencyTableModel()); tbl.setDefaultRenderer(java.lang.Number.class, new FractionCellRenderer(10, 3, SwingConstants.RIGHT)); TableColumnModel tcm = tbl.getColumnModel(); tcm.getColumn(0).setPreferredWidth(150); tcm.getColumn(0).setMinWidth(150); TextWithIconCellRenderer renderer = new TextWithIconCellRenderer(); tcm.getColumn(0).setCellRenderer(renderer); tbl.setShowHorizontalLines(false); tbl.setIntercellSpacing(new Dimension(1, 0)); // Add the stripe renderer in the leftmost four columns. StripedTableCellRenderer.installInColumn(tbl, 0, Color.lightGray, Color.white, null, null); StripedTableCellRenderer.installInColumn(tbl, 1, Color.lightGray, Color.white, null, null); StripedTableCellRenderer.installInColumn(tbl, 2, Color.lightGray, Color.white, null, null); StripedTableCellRenderer.installInColumn(tbl, 3, Color.lightGray, Color.white, null, null); // Add the highlight renderer to the difference column. // The following comparator makes it highlight // cells with negative numeric values. Comparator cmp = new Comparator() { public boolean shouldHighlight(JTable tbl, Object value, int row, int column) { if (value instanceof Number) { double columnValue = ((Number) value).doubleValue(); return columnValue < (double) 0.0; } return false; } }; tcm.getColumn(3).setCellRenderer( new HighlightRenderer(cmp, null, Color.pink, Color.black, Color.pink.darker(), Color.white)); // Install a button renderer in the last column ButtonRenderer buttonRenderer = new ButtonRenderer(); buttonRenderer.setForeground(Color.blue); buttonRenderer.setBackground(Color.lightGray); tcm.getColumn(4).setCellRenderer(buttonRenderer); // Install a button editor in the last column TableCellEditor editor = new ButtonEditor(new JButton()); tcm.getColumn(4).setCellEditor(editor); // Make the rows wide enough to take the buttons tbl.setRowHeight(20); tbl.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); tbl.setPreferredScrollableViewportSize(tbl.getPreferredSize()); JScrollPane sp = new JScrollPane(tbl); f.getContentPane().add(sp, "Center"); f.pack(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); f.setVisible(true); }
} class TestUpdatableCurrencyTableModel extends UpdatableCurrencyTableModel {
public void updateTable(Object value, int row, int column) { System.out.println("Update for row " + row + " required."); System.out.println("Values are " + getValueAt(row, 1) + ", " + getValueAt(row, 2) + "; diff is " + getValueAt(row, 3)); }
} class FractionCellRenderer extends DefaultTableCellRenderer {
public FractionCellRenderer(int integer, int fraction, int align) { this.integer = integer; // maximum integer digits this.fraction = fraction; // exact number of fraction digits this.align = align; // alignment (LEFT, CENTER, RIGHT) } protected void setValue(Object value) { if (value != null && value instanceof Number) { formatter.setMaximumIntegerDigits(integer); formatter.setMaximumFractionDigits(fraction); formatter.setMinimumFractionDigits(fraction); setText(formatter.format(((Number) value).doubleValue())); } else { super.setValue(value); } setHorizontalAlignment(align); } protected int integer; protected int fraction; protected int align; protected static NumberFormat formatter = NumberFormat.getInstance();
} class TextWithIconCellRenderer extends DefaultTableCellRenderer {
protected void setValue(Object value) { if (value instanceof DataWithIcon) { if (value != null) { DataWithIcon d = (DataWithIcon) value; Object dataValue = d.getData(); setText(dataValue == null ? "" : dataValue.toString()); setIcon(d.getIcon()); setHorizontalTextPosition(SwingConstants.RIGHT); setVerticalTextPosition(SwingConstants.CENTER); setHorizontalAlignment(SwingConstants.LEFT); setVerticalAlignment(SwingConstants.CENTER); } else { setText(""); setIcon(null); } } else { super.setValue(value); } }
} class DataWithIcon {
public DataWithIcon(Object data, Icon icon) { this.data = data; this.icon = icon; } public Icon getIcon() { return icon; } public Object getData() { return data; } public String toString() { return data.toString(); } protected Icon icon; protected Object data;
} class StripedTableCellRenderer implements TableCellRenderer {
public StripedTableCellRenderer(TableCellRenderer targetRenderer, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { this.targetRenderer = targetRenderer; this.evenBack = evenBack; this.evenFore = evenFore; this.oddBack = oddBack; this.oddFore = oddFore; } // Implementation of TableCellRenderer interface public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { TableCellRenderer renderer = targetRenderer; if (renderer == null) { // Get default renderer from the table renderer = table.getDefaultRenderer(table.getColumnClass(column)); } // Let the real renderer create the component Component comp = renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); // Now apply the stripe effect if (isSelected == false && hasFocus == false) { if ((row & 1) == 0) { comp.setBackground(evenBack != null ? evenBack : table .getBackground()); comp.setForeground(evenFore != null ? evenFore : table .getForeground()); } else { comp.setBackground(oddBack != null ? oddBack : table .getBackground()); comp.setForeground(oddFore != null ? oddFore : table .getForeground()); } } return comp; } // Convenience method to apply this renderer to single column public static void installInColumn(JTable table, int columnIndex, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { TableColumn tc = table.getColumnModel().getColumn(columnIndex); // Get the cell renderer for this column, if any TableCellRenderer targetRenderer = tc.getCellRenderer(); // Create a new StripedTableCellRenderer and install it tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } // Convenience method to apply this renderer to an entire table public static void installInTable(JTable table, Color evenBack, Color evenFore, Color oddBack, Color oddFore) { StripedTableCellRenderer sharedInstance = null; int columns = table.getColumnCount(); for (int i = 0; i < columns; i++) { TableColumn tc = table.getColumnModel().getColumn(i); TableCellRenderer targetRenderer = tc.getCellRenderer(); if (targetRenderer != null) { // This column has a specific renderer tc.setCellRenderer(new StripedTableCellRenderer(targetRenderer, evenBack, evenFore, oddBack, oddFore)); } else { // This column uses a class renderer - use a shared renderer if (sharedInstance == null) { sharedInstance = new StripedTableCellRenderer(null, evenBack, evenFore, oddBack, oddFore); } tc.setCellRenderer(sharedInstance); } } } protected TableCellRenderer targetRenderer; protected Color evenBack; protected Color evenFore; protected Color oddBack; protected Color oddFore;
} class HighlightRenderer implements TableCellRenderer {
public HighlightRenderer(Comparator cmp, TableCellRenderer targetRenderer, Color backColor, Color foreColor, Color highlightBack, Color highlightFore) { this.cmp = cmp; this.targetRenderer = targetRenderer; this.backColor = backColor; this.foreColor = foreColor; this.highlightBack = highlightBack; this.highlightFore = highlightFore; } public Component getTableCellRendererComponent(JTable tbl, Object value, boolean isSelected, boolean hasFocus, int row, int column) { TableCellRenderer renderer = targetRenderer; if (renderer == null) { renderer = tbl.getDefaultRenderer(tbl.getColumnClass(column)); } Component comp = renderer.getTableCellRendererComponent(tbl, value, isSelected, hasFocus, row, column); if (isSelected == false && hasFocus == false && value != null) { if (cmp.shouldHighlight(tbl, value, row, column)) { comp.setForeground(highlightFore); comp.setBackground(highlightBack); } else { comp.setForeground(foreColor); comp.setBackground(backColor); } } return comp; } protected Comparator cmp; protected TableCellRenderer targetRenderer; protected Color backColor; protected Color foreColor; protected Color highlightBack; protected Color highlightFore;
} interface Comparator {
public abstract boolean shouldHighlight(JTable tbl, Object value, int row, int column);
} abstract class UpdatableCurrencyTableModel extends EditableCurrencyTableModel {
public int getColumnCount() { return super.getColumnCount() + 1; } public Object getValueAt(int row, int column) { if (column == BUTTON_COLUMN) { return "Update"; } return super.getValueAt(row, column); } public Class getColumnClass(int column) { if (column == BUTTON_COLUMN) { return String.class; } return super.getColumnClass(column); } public String getColumnName(int column) { if (column == BUTTON_COLUMN) { return ""; } return super.getColumnName(column); } public boolean isCellEditable(int row, int column) { return column == BUTTON_COLUMN || super.isCellEditable(row, column); } public void setValueAt(Object value, int row, int column) { if (column == BUTTON_COLUMN) { // Button press - do whatever is needed to update the table source updateTable(value, row, column); return; } // Other columns - use superclass super.setValueAt(value, row, column); } // Used to implement the table update protected abstract void updateTable(Object value, int row, int column); protected static final int BUTTON_COLUMN = 4;
} class BasicCellEditor implements CellEditor, PropertyChangeListener {
public BasicCellEditor() { this.editor = null; } public BasicCellEditor(JComponent editor) { this.editor = editor; editor.addPropertyChangeListener(this); } public Object getCellEditorValue() { return null; } public boolean isCellEditable(EventObject evt) { editingEvent = evt; return true; } public boolean shouldSelectCell(EventObject evt) { return true; } public boolean stopCellEditing() { fireEditingStopped(); return true; } public void cancelCellEditing() { fireEditingCanceled(); } public void addCellEditorListener(CellEditorListener l) { listeners.add(CellEditorListener.class, l); } public void removeCellEditorListener(CellEditorListener l) { listeners.remove(CellEditorListener.class, l); } // Returns the editing component public JComponent getComponent() { return editor; } // Sets the editing component public void setComponent(JComponent comp) { editor = comp; } // Returns the event that triggered the edit public EventObject getEditingEvent() { return editingEvent; } // Method invoked when the editor is installed in the table. // Overridden in derived classes to take any convenient // action. public void editingStarted(EventObject event) { } protected void fireEditingStopped() { Object[] l = listeners.getListenerList(); for (int i = l.length - 2; i >= 0; i -= 2) { if (l[i] == CellEditorListener.class) { if (changeEvent == null) { changeEvent = new ChangeEvent(this); } ((CellEditorListener) l[i + 1]).editingStopped(changeEvent); } } } protected void fireEditingCanceled() { Object[] l = listeners.getListenerList(); for (int i = l.length - 2; i >= 0; i -= 2) { if (l[i] == CellEditorListener.class) { if (changeEvent == null) { changeEvent = new ChangeEvent(this); } ((CellEditorListener) l[i + 1]).editingCanceled(changeEvent); } } } // Implementation of the PropertyChangeListener interface public void propertyChange(PropertyChangeEvent evt) { if (evt.getPropertyName().equals("ancestor") && evt.getNewValue() != null) { // Added to table - notify the editor editingStarted(editingEvent); } } protected static JCheckBox checkBox = new JCheckBox(); protected static ChangeEvent changeEvent; protected JComponent editor; protected EventListenerList listeners = new EventListenerList(); protected EventObject editingEvent;
} class ButtonEditor extends BasicCellEditor implements ActionListener,
TableCellEditor { public ButtonEditor(JButton button) { super(button); button.addActionListener(this); } public void setForeground(Color foreground) { this.foreground = foreground; editor.setForeground(foreground); } public void setBackground(Color background) { this.background = background; editor.setBackground(background); } public void setFont(Font font) { this.font = font; editor.setFont(font); } public Object getCellEditorValue() { return value; } public void editingStarted(EventObject event) { // Edit starting - click the button if necessary if (!(event instanceof MouseEvent)) { // Keyboard event - click the button SwingUtilities.invokeLater(new Runnable() { public void run() { ((JButton) editor).doClick(); } }); } } public Component getTableCellEditorComponent(JTable tbl, Object value, boolean isSelected, int row, int column) { editor.setForeground(foreground != null ? foreground : tbl .getForeground()); editor.setBackground(background != null ? background : tbl .getBackground()); editor.setFont(font != null ? font : tbl.getFont()); this.value = value; setValue(value); return editor; } protected void setValue(Object value) { JButton button = (JButton) editor; if (value == null) { button.setText(""); button.setIcon(null); } else if (value instanceof Icon) { button.setText(""); button.setIcon((Icon) value); } else if (value instanceof DataWithIcon) { DataWithIcon d = (DataWithIcon) value; button.setText(d.toString()); button.setIcon(d.getIcon()); } else { button.setText(value.toString()); button.setIcon(null); } } public void actionPerformed(ActionEvent evt) { // Button pressed - stop the edit stopCellEditing(); } protected Object value; protected Color foreground; protected Color background; protected Font font;
} class EditableCurrencyTableModel extends CurrencyTableModel {
public boolean isCellEditable(int row, int column) { return column == OLD_RATE_COLUMN || column == NEW_RATE_COLUMN; } public void setValueAt(Object value, int row, int column) { try { if (column == OLD_RATE_COLUMN || column == NEW_RATE_COLUMN) { Double newObjectValue; // New value as an Object double newValue; // double, for validity checking if (value instanceof Number) { // Convert Number to Double newValue = ((Number) value).doubleValue(); newObjectValue = new Double(newValue); } else if (value instanceof String) { // Convert a String to a Double newObjectValue = new Double((String) value); newValue = newObjectValue.doubleValue(); } else { // Unrecognized - ignore return; } if (newValue > (double) 0.0) { // Store new value, but reject zero or negative values data[row][column] = newObjectValue; data[row][DIFF_COLUMN] = new Double( ((Double) data[row][NEW_RATE_COLUMN]).doubleValue() - ((Double) data[row][OLD_RATE_COLUMN]) .doubleValue()); fireTableRowsUpdated(row, row); } } } catch (NumberFormatException e) { // Ignore a badly-formatted number } }
} class CurrencyTableModel extends AbstractTableModel {
protected String[] columnNames = { "Currency", "Yesterday", "Today", "Change" }; // Constructor: calculate currency change to create the last column public CurrencyTableModel() { for (int i = 0; i < data.length; i++) { data[i][DIFF_COLUMN] = new Double( ((Double) data[i][NEW_RATE_COLUMN]).doubleValue() - ((Double) data[i][OLD_RATE_COLUMN]).doubleValue()); } } // Implementation of TableModel interface public int getRowCount() { return data.length; } public int getColumnCount() { return COLUMN_COUNT; } public Object getValueAt(int row, int column) { return data[row][column]; } public Class getColumnClass(int column) { return (data[0][column]).getClass(); } public String getColumnName(int column) { return columnNames[column]; } protected static final int OLD_RATE_COLUMN = 1; protected static final int NEW_RATE_COLUMN = 2; protected static final int DIFF_COLUMN = 3; protected static final int COLUMN_COUNT = 4; protected static final Class thisClass = CurrencyTableModel.class; protected Object[][] data = new Object[][] { { new DataWithIcon("Belgian Franc", new ImageIcon(thisClass .getResource("belgium.gif"))), new Double(37.6460110), new Double(37.6508921), null }, { new DataWithIcon("British Pound", new ImageIcon(thisClass .getResource("gb.gif"))), new Double(0.6213051), new Double(0.6104102), null }, { new DataWithIcon("Canadian Dollar", new ImageIcon(thisClass .getResource("canada.gif"))), new Double(1.4651209), new Double(1.5011104), null }, { new DataWithIcon("French Franc", new ImageIcon(thisClass .getResource("france.gif"))), new Double(6.1060001), new Double(6.0100101), null }, { new DataWithIcon("Italian Lire", new ImageIcon(thisClass .getResource("italy.gif"))), new Double(1181.3668977), new Double(1182.104), null }, { new DataWithIcon("German Mark", new ImageIcon(thisClass .getResource("germany.gif"))), new Double(1.8191804), new Double(1.8223421), null }, { new DataWithIcon("Japanese Yen", new ImageIcon(thisClass .getResource("japan.gif"))), new Double(141.0815412), new Double(121.0040432), null } };
} class ButtonRenderer extends JButton implements TableCellRenderer {
public ButtonRenderer() { this.border = getBorder(); this.setOpaque(true); } public void setForeground(Color foreground) { this.foreground = foreground; super.setForeground(foreground); } public void setBackground(Color background) { this.background = background; super.setBackground(background); } public void setFont(Font font) { this.font = font; super.setFont(font); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { Color cellForeground = foreground != null ? foreground : table .getForeground(); Color cellBackground = background != null ? background : table .getBackground(); setFont(font != null ? font : table.getFont()); if (hasFocus) { setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); if (table.isCellEditable(row, column)) { cellForeground = UIManager .getColor("Table.focusCellForeground"); cellBackground = UIManager .getColor("Table.focusCellBackground"); } } else { setBorder(border); } super.setForeground(cellForeground); super.setBackground(cellBackground); // Customize the component"s appearance setValue(value); return this; } protected void setValue(Object value) { if (value == null) { setText(""); setIcon(null); } else if (value instanceof Icon) { setText(""); setIcon((Icon) value); } else if (value instanceof DataWithIcon) { DataWithIcon d = (DataWithIcon) value; setText(d.toString()); setIcon(d.getIcon()); } else { setText(value.toString()); setIcon(null); } } protected Color foreground; protected Color background; protected Font font; protected Border border;
}
</source>