Java/Swing Components/Grid Table

Материал из Java эксперт
Перейти к: навигация, поиск

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>
   
  
 
  



Column popup menu

   <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>