Java/Swing JFC/Table Renderer Editor — различия между версиями

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

Текущая версия на 06:41, 1 июня 2010

A slider renderer for volume values in a table

 
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly 
*/
// MixerTest.java
//A test application for showing Volume data in a JTable using the
//custom VolumneRenderer class.
//
import java.awt.BorderLayout;
import java.awt.ruponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellRenderer;
public class MixerTest extends JFrame {
  public MixerTest() {
    super("Customer Editor Test");
    setSize(600, 160);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    MixerModel test = new MixerModel();
    test.dump();
    JTable jt = new JTable(test);
    jt.setDefaultRenderer(Volume.class, new VolumeRenderer());
    JScrollPane jsp = new JScrollPane(jt);
    getContentPane().add(jsp, BorderLayout.CENTER);
  }
  public static void main(String args[]) {
    MixerTest mt = new MixerTest();
    mt.setVisible(true);
  }
}
//MixerModel.java
//An audio mixer table data model. This model contains the following columns:
//<br> + Track name (String)
//<br> + Track start time (String)
//<br> + Track stop time (String)
//<br> + Left channel volume (Volume, 0 . . 100)
//<br> + Right channel volume (Volume, 0 . . 100)
//
class MixerModel extends AbstractTableModel {
  String headers[] = { "Track", "Start", "Stop", "Left Volume",
      "Right Volume" };
  Class columnClasses[] = { String.class, String.class, String.class,
      Volume.class, Volume.class };
  Object data[][] = {
      { "Bass", "0:00:000", "1:00:000", new Volume(56), new Volume(56) },
      { "Strings", "0:00:000", "0:52:010", new Volume(72), new Volume(52) },
      { "Brass", "0:08:000", "1:00:000", new Volume(99), new Volume(0) },
      { "Wind", "0:08:000", "1:00:000", new Volume(0), new Volume(99) }, };
  public int getRowCount() {
    return data.length;
  }
  public int getColumnCount() {
    return headers.length;
  }
  public Class getColumnClass(int c) {
    return columnClasses[c];
  }
  public String getColumnName(int c) {
    return headers[c];
  }
  public boolean isCellEditable(int r, int c) {
    return true;
  }
  public Object getValueAt(int r, int c) {
    return data[r][c];
  }
  // Ok, do something extra here so that if we get a String object back (from
  // a
  // text field editor) we can still store that as a valid Volume object. If
  // it"s just a string, then stick it directly into our data array.
  public void setValueAt(Object value, int r, int c) {
    if (c >= 3) {
      ((Volume) data[r][c]).setVolume(value);
    } else {
      data[r][c] = value;
    }
  }
  // A quick debugging utility to dump out the contents of our data structure
  public void dump() {
    for (int i = 0; i < data.length; i++) {
      System.out.print("|");
      for (int j = 0; j < data[0].length; j++) {
        System.out.print(data[i][j] + "|");
      }
      System.out.println();
    }
  }
}
//Volume.java
//A simple data structure for track volumes on a mixer.
//
class Volume {
  private int volume;
  public Volume(int v) {
    setVolume(v);
  }
  public Volume() {
    this(50);
  }
  public void setVolume(int v) {
    volume = (v < 0 ? 0 : v > 100 ? 100 : v);
  }
  public void setVolume(Object v) {
    if (v instanceof String) {
      setVolume(Integer.parseInt((String) v));
    } else if (v instanceof Number) {
      setVolume(((Number) v).intValue());
    } else if (v instanceof Volume) {
      setVolume(((Volume) v).getVolume());
    }
  }
  public int getVolume() {
    return volume;
  }
  public String toString() {
    return String.valueOf(volume);
  }
}
//VolumeRenderer.java
//A slider renderer for volume values in a table.
//
class VolumeRenderer extends JSlider implements TableCellRenderer {
  public VolumeRenderer() {
    super(SwingConstants.HORIZONTAL);
    // set a starting size...some 1.2/1.3 systems need this
    setSize(115, 15);
  }
  public Component getTableCellRendererComponent(JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) {
    if (value == null) {
      return this;
    }
    if (value instanceof Volume) {
      setValue(((Volume) value).getVolume());
    } else {
      setValue(0);
    }
    return this;
  }
}





A table that allows the user to pick a color from a pulldown list

 
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly 
*/
// ColorTable.java
//A table that allows the user to pick a color from a pulldown list. This
//is accomplished by using the DefaultCellRenderer and DefaultCellEditor
//classes.
//
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
public class ColorTable extends JFrame {
  ColorName colors[] = { new ColorName("Red"), new ColorName("Green"),
      new ColorName("Blue"), new ColorName("Black"),
      new ColorName("White") };
  public ColorTable() {
    super("Table With DefaultCellEditor Example");
    setSize(500, 300);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    JTable table = new JTable(new AbstractTableModel() {
      ColorName data[] = { colors[0], colors[1], colors[2], colors[3],
          colors[4], colors[0], colors[1], colors[2], colors[3],
          colors[4] };
      public int getColumnCount() {
        return 3;
      }
      public int getRowCount() {
        return 10;
      }
      public Object getValueAt(int r, int c) {
        switch (c) {
        case 0:
          return (r + 1) + ".";
        case 1:
          return "Some pithy quote #" + r;
        case 2:
          return data[r];
        }
        return "Bad Column";
      }
      public Class getColumnClass(int c) {
        if (c == 2)
          return ColorName.class;
        return String.class;
      }
      // Make Column 2 editable...
      public boolean isCellEditable(int r, int c) {
        return c == 2;
      }
      public void setValueAt(Object value, int r, int c) {
        data[r] = (ColorName) value;
      }
    });
    table.setDefaultEditor(ColorName.class, new DefaultCellEditor(
        new JComboBox(colors)));
    table.setDefaultRenderer(ColorName.class,
        new DefaultTableCellRenderer());
    table.setRowHeight(20);
    getContentPane().add(new JScrollPane(table));
  }
  public static void main(String args[]) {
    ColorTable ex = new ColorTable();
    ex.setVisible(true);
  }
  public class ColorName {
    String cname;
    public ColorName(String name) {
      cname = name;
    }
    public String toString() {
      return cname;
    }
  }
}





Change Table cell background with column renderer

 
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.ruparator;
import java.util.GregorianCalendar;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.event.TableModelEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
public class ColorTableColumnRenderer extends JFrame{
  protected JTable table;
  protected MyTableModel tableModel;
  public ColorTableColumnRenderer() {
    super("Stocks Table");
    setSize(300, 300);
    tableModel = new MyTableModel();
    table = new JTable();
    table.setModel(tableModel);
    DefaultTableCellRenderer renderer = new ColoredTableCellRenderer();
    TableColumn column = new TableColumn(0,190, renderer, null);
    table.addColumn(column);
    JScrollPane ps = new JScrollPane();
    ps.getViewport().add(table);
    getContentPane().add(ps, BorderLayout.CENTER);
    WindowListener wndCloser = new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    };
    addWindowListener(wndCloser);
    setVisible(true);
  }
  public static void main(String argv[]) {
    new ColorTableColumnRenderer();
  }
}
class MyTableModel extends AbstractTableModel {
  protected Vector vector;
  protected int columnsCount = 1;
  public MyTableModel() {
    vector = new Vector();
    vector.addElement("2146400");
    vector.addElement("554000");
    vector.addElement("24230");
  }
  public int getRowCount() {
    return vector == null ? 0 : vector.size();
  }
  public int getColumnCount() {
    return columnsCount;
  }
  public String getColumnName(int column) {
    return "data";
  }
  public boolean isCellEditable(int nRow, int nCol) {
    return false;
  }
  public Object getValueAt(int nRow, int nCol) {
    if (nRow < 0 || nRow >= getRowCount())
      return "";
    return vector.elementAt(nRow);
  }
  public String getTitle() {
    return "data ";
  }
}
class ColoredTableCellRenderer extends DefaultTableCellRenderer {
  public void setValue(Object value) {
    setForeground(Color.red);
    super.setValue(value);
  }
}





Colored Table CellRenderer

 
/*
Swing, Second Edition
by Matthew Robinson, Pavel Vorobiev
*/

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
public class StocksTable2 extends JFrame {
  protected JTable m_table;
  protected StockTableData m_data;
  protected JLabel m_title;
  public StocksTable2() {
    super("Stocks Table");
    setSize(600, 300);
    m_data = new StockTableData();
    m_title = new JLabel(m_data.getTitle(), new ImageIcon("money.gif"),
        SwingConstants.LEFT);
    m_title.setFont(new Font("TimesRoman", Font.BOLD, 24));
    m_title.setForeground(Color.black);
    getContentPane().add(m_title, BorderLayout.NORTH);
    m_table = new JTable();
    m_table.setAutoCreateColumnsFromModel(false);
    m_table.setModel(m_data);
    for (int k = 0; k < StockTableData.m_columns.length; k++) {
      DefaultTableCellRenderer renderer = new ColoredTableCellRenderer();
      renderer
          .setHorizontalAlignment(StockTableData.m_columns[k].m_alignment);
      TableColumn column = new TableColumn(k,
          StockTableData.m_columns[k].m_width, renderer, null);
      m_table.addColumn(column);
    }
    JTableHeader header = m_table.getTableHeader();
    header.setUpdateTableInRealTime(false);
    JScrollPane ps = new JScrollPane();
    ps.getViewport().add(m_table);
    getContentPane().add(ps, BorderLayout.CENTER);
    WindowListener wndCloser = new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    };
    addWindowListener(wndCloser);
    setVisible(true);
  }
  public static void main(String argv[]) {
    new StocksTable2();
  }
}
class ColoredTableCellRenderer extends DefaultTableCellRenderer {
  public void setValue(Object value) {
    if (value instanceof ColorData) {
      ColorData cvalue = (ColorData) value;
      setForeground(cvalue.m_color);
      setText(cvalue.m_data.toString());
    } else if (value instanceof IconData) {
      IconData ivalue = (IconData) value;
      setIcon(ivalue.m_icon);
      setText(ivalue.m_data.toString());
    } else
      super.setValue(value);
  }
}
class ColorData {
  public Color m_color;
  public Object m_data;
  public static Color GREEN = new Color(0, 128, 0);
  public static Color RED = Color.red;
  public ColorData(Color color, Object data) {
    m_color = color;
    m_data = data;
  }
  public ColorData(Double data) {
    m_color = data.doubleValue() >= 0 ? GREEN : RED;
    m_data = data;
  }
  public String toString() {
    return m_data.toString();
  }
}
class IconData {
  public ImageIcon m_icon;
  public Object m_data;
  public IconData(ImageIcon icon, Object data) {
    m_icon = icon;
    m_data = data;
  }
  public String toString() {
    return m_data.toString();
  }
}
class StockData {
  public static ImageIcon ICON_UP = new ImageIcon("ArrUp.gif");
  public static ImageIcon ICON_DOWN = new ImageIcon("ArrDown.gif");
  public static ImageIcon ICON_BLANK = new ImageIcon("blank.gif");
  public IconData m_symbol;
  public String m_name;
  public Double m_last;
  public Double m_open;
  public ColorData m_change;
  public ColorData m_changePr;
  public Long m_volume;
  public StockData(String symbol, String name, double last, double open,
      double change, double changePr, long volume) {
    m_symbol = new IconData(getIcon(change), symbol);
    m_name = name;
    m_last = new Double(last);
    m_open = new Double(open);
    m_change = new ColorData(new Double(change));
    m_changePr = new ColorData(new Double(changePr));
    m_volume = new Long(volume);
  }
  public static ImageIcon getIcon(double change) {
    return (change > 0 ? ICON_UP : (change < 0 ? ICON_DOWN : ICON_BLANK));
  }
}
class ColumnData {
  public String m_title;
  public int m_width;
  public int m_alignment;
  public ColumnData(String title, int width, int alignment) {
    m_title = title;
    m_width = width;
    m_alignment = alignment;
  }
}
class StockTableData extends AbstractTableModel {
  static final public ColumnData m_columns[] = {
      new ColumnData("Symbol", 100, JLabel.LEFT),
      new ColumnData("Name", 160, JLabel.LEFT),
      new ColumnData("Last", 100, JLabel.RIGHT),
      new ColumnData("Open", 100, JLabel.RIGHT),
      new ColumnData("Change", 100, JLabel.RIGHT),
      new ColumnData("Change %", 100, JLabel.RIGHT),
      new ColumnData("Volume", 100, JLabel.RIGHT) };
  protected SimpleDateFormat m_frm;
  protected Vector m_vector;
  protected Date m_date;
  public StockTableData() {
    m_frm = new SimpleDateFormat("MM/dd/yyyy");
    m_vector = new Vector();
    setDefaultData();
  }
  public void setDefaultData() {
    try {
      m_date = m_frm.parse("4/6/1999");
    } catch (java.text.ParseException ex) {
      m_date = null;
    }
    m_vector.removeAllElements();
    m_vector.addElement(new StockData("ORCL", "Oracle Corp.", 23.6875,
        25.375, -1.6875, -6.42, 24976600));
    m_vector.addElement(new StockData("EGGS", "Egghead.ru", 17.25,
        17.4375, -0.1875, -1.43, 2146400));
    m_vector.addElement(new StockData("T", "AT&T", 65.1875, 66, -0.8125,
        -0.10, 554000));
    m_vector.addElement(new StockData("LU", "Lucent Technology", 64.625,
        59.9375, 4.6875, 9.65, 29856300));
    m_vector.addElement(new StockData("FON", "Sprint", 104.5625, 106.375,
        -1.8125, -1.82, 1135100));
    m_vector.addElement(new StockData("ENML", "Enamelon Inc.", 4.875, 5,
        -0.125, 0, 35900));
    m_vector.addElement(new StockData("CPQ", "Compaq Computers", 30.875,
        31.25, -0.375, -2.18, 11853900));
    m_vector.addElement(new StockData("MSFT", "Microsoft Corp.", 94.0625,
        95.1875, -1.125, -0.92, 19836900));
    m_vector.addElement(new StockData("DELL", "Dell Computers", 46.1875,
        44.5, 1.6875, 6.24, 47310000));
    m_vector.addElement(new StockData("SUNW", "Sun Microsystems", 140.625,
        130.9375, 10, 10.625, 17734600));
    m_vector.addElement(new StockData("IBM", "Intl. Bus. Machines", 183,
        183.125, -0.125, -0.51, 4371400));
    m_vector.addElement(new StockData("HWP", "Hewlett-Packard", 70,
        71.0625, -1.4375, -2.01, 2410700));
    m_vector.addElement(new StockData("UIS", "Unisys Corp.", 28.25, 29,
        -0.75, -2.59, 2576200));
    m_vector.addElement(new StockData("SNE", "Sony Corp.", 96.1875, 95.625,
        1.125, 1.18, 330600));
    m_vector.addElement(new StockData("NOVL", "Novell Inc.", 24.0625,
        24.375, -0.3125, -3.02, 6047900));
    m_vector.addElement(new StockData("HIT", "Hitachi, Ltd.", 78.5, 77.625,
        0.875, 1.12, 49400));
  }
  public int getRowCount() {
    return m_vector == null ? 0 : m_vector.size();
  }
  public int getColumnCount() {
    return m_columns.length;
  }
  public String getColumnName(int column) {
    return m_columns[column].m_title;
  }
  public boolean isCellEditable(int nRow, int nCol) {
    return false;
  }
  public Object getValueAt(int nRow, int nCol) {
    if (nRow < 0 || nRow >= getRowCount())
      return "";
    StockData row = (StockData) m_vector.elementAt(nRow);
    switch (nCol) {
    case 0:
      return row.m_symbol;
    case 1:
      return row.m_name;
    case 2:
      return row.m_last;
    case 3:
      return row.m_open;
    case 4:
      return row.m_change;
    case 5:
      return row.m_changePr;
    case 6:
      return row.m_volume;
    }
    return "";
  }
  public String getTitle() {
    if (m_date == null)
      return "Stock Quotes";
    return "Stock Quotes at " + m_frm.format(m_date);
  }
}



Creating a Class-Based Custom Cell Renderer in a JTable Component

import java.awt.Color;
import java.awt.ruponent;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
public class Main {
  public static void main(String[] argv) {
    DefaultTableModel model = new DefaultTableModel() {
      public Class getColumnClass(int mColIndex) {
        int rowIndex = 0;
        Object o = getValueAt(rowIndex, mColIndex);
        if (o == null) {
          return Object.class;
        } else {
          return o.getClass();
        }
      }
    };
    JTable table = new JTable(model);
    model.addColumn("Col1", new Object[] { Color.red });
    model.addRow(new Object[] { Color.green });
    model.addRow(new Object[] { Color.blue });
    table.setDefaultRenderer(Color.class, new ColorTableCellRenderer());
    
    JFrame f = new JFrame();
    f.setSize(300,300);
    f.add(new JScrollPane(table));
    f.setVisible(true);
  }
}
class ColorTableCellRenderer extends JLabel implements TableCellRenderer {
  Color curColor;
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
      boolean hasFocus, int rowIndex, int vColIndex) {
    if (curColor instanceof Color) {
      curColor = (Color) value;
    } else {
      curColor = table.getBackground();
    }
    return this;
  }
  public void paint(Graphics g) {
    g.setColor(curColor);
    g.fillRect(0, 0, getWidth() - 1, getHeight() - 1);
  }
}





Creating a Custom Cell Renderer in a JTable Component

import java.awt.ruponent;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    int vColIndex = 0;
    TableColumn col = table.getColumnModel().getColumn(vColIndex);
    col.setCellRenderer(new MyTableCellRenderer());
  }
}
class MyTableCellRenderer extends JLabel implements TableCellRenderer {
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
      boolean hasFocus, int rowIndex, int vColIndex) {
    setText(value.toString());
    setToolTipText((String) value);
    return this;
  }
}





Creating a Custom Table Cell Editor in a JTable Component

import java.awt.ruponent;
import javax.swing.AbstractCellEditor;
import javax.swing.JComponent;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    TableColumn col = table.getColumnModel().getColumn(0);
    col.setCellEditor(new MyTableCellEditor());
  }
}
class MyTableCellEditor extends AbstractCellEditor implements TableCellEditor {
  JComponent component = new JTextField();
  public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected,
      int rowIndex, int vColIndex) {
    ((JTextField) component).setText((String) value);
    return component;
  }
  public Object getCellEditorValue() {
    return ((JTextField) component).getText();
  }
}





Get Default Cell Editor

import java.util.Date;
import java.util.Enumeration;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
public class Main {
  public static void main(String[] argv) {
    DefaultTableModel model = new DefaultTableModel() {
      public Class getColumnClass(int columnIndex) {
        Object o = getValueAt(0, columnIndex);
        if (o == null) {
          return Object.class;
        } else {
          return o.getClass();
        }
      }
    };
    JTable table = new JTable(model);
    model.addColumn("Boolean", new Object[] { Boolean.TRUE });
    model.addColumn("Date", new Object[] { new Date() });
    model.addColumn("Double", new Object[] { new Double(Math.PI) });
    model.addColumn("Float", new Object[] { new Float(1.2) });
    model.addColumn("Icon", new Object[] { new ImageIcon("icon.gif") });
    model.addColumn("Number", new Object[] { new Integer(1) });
    model.addColumn("Object", new Object[] { "object" });
    
    Enumeration e = table.getColumnModel().getColumns();
    TableColumn col = (TableColumn) e.nextElement();
    col.setCellRenderer(table.getDefaultRenderer(Boolean.class));
    col.setCellEditor(table.getDefaultEditor(Boolean.class));
    
    JFrame f = new JFrame();
    f.setSize(300,300);
    f.add(new JScrollPane(table));
    f.setVisible(true);
  }
}





Get Default cell Renderer

import java.util.Date;
import java.util.Enumeration;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
public class Main {
  public static void main(String[] argv) {
    DefaultTableModel model = new DefaultTableModel() {
      public Class getColumnClass(int columnIndex) {
        Object o = getValueAt(0, columnIndex);
        if (o == null) {
          return Object.class;
        } else {
          return o.getClass();
        }
      }
    };
    JTable table = new JTable(model);
    model.addColumn("Boolean", new Object[] { Boolean.TRUE });
    model.addColumn("Date", new Object[] { new Date() });
    model.addColumn("Double", new Object[] { new Double(Math.PI) });
    model.addColumn("Float", new Object[] { new Float(1.2) });
    model.addColumn("Icon", new Object[] { new ImageIcon("icon.gif") });
    model.addColumn("Number", new Object[] { new Integer(1) });
    model.addColumn("Object", new Object[] { "object" });
    
    Enumeration e = table.getColumnModel().getColumns();
    TableColumn col = (TableColumn) e.nextElement();
    col.setCellRenderer(table.getDefaultRenderer(Boolean.class));
    col.setCellEditor(table.getDefaultEditor(Boolean.class));
    
    JFrame f = new JFrame();
    f.setSize(300,300);
    f.add(new JScrollPane(table));
    f.setVisible(true);
  }
}





Install different Table Renderer for even and odd rows

 
/*
Definitive Guide to Swing for Java 2, Second Edition
By John Zukowski     
ISBN: 1-893115-78-X
Publisher: APress
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
public class RendererSample {
  public static void main(String args[]) {
    Object rows[][] = { { "one", "ichi - \u4E00" },
        { "two", "ni - \u4E8C" }, { "three", "san - \u4E09" },
        { "four", "shi - \u56DB" }, { "five", "go - \u4E94" },
        { "six", "roku - \u516D" }, { "seven", "shichi - \u4E03" },
        { "eight", "hachi - \u516B" }, { "nine", "kyu - \u4E5D" },
        { "ten", "ju - \u5341" } };
    Object headers[] = { "English", "Japanese" };
    JFrame frame = new JFrame("Renderer Sample");
    JTable table = new JTable(rows, headers);
    TableCellRenderer renderer = new EvenOddRenderer();
    table.setDefaultRenderer(Object.class, renderer);
    JScrollPane scrollPane = new JScrollPane(table);
    frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}
class EvenOddRenderer implements TableCellRenderer {
  public static final DefaultTableCellRenderer DEFAULT_RENDERER = new DefaultTableCellRenderer();
  public Component getTableCellRendererComponent(JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) {
    Component renderer = DEFAULT_RENDERER.getTableCellRendererComponent(
        table, value, isSelected, hasFocus, row, column);
    ((JLabel) renderer).setOpaque(true);
    Color foreground, background;
    if (isSelected) {
      foreground = Color.yellow;
      background = Color.green;
    } else {
      if (row % 2 == 0) {
        foreground = Color.blue;
        background = Color.white;
      } else {
        foreground = Color.white;
        background = Color.blue;
      }
    }
    renderer.setForeground(foreground);
    renderer.setBackground(background);
    return renderer;
  }
}





MixerModel and sliders for rendering volume values

 
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly 
*/
// MixerTest2.java
//A test of the MixerModel and sliders for rendering volume values.
//This version also includes adjustable sliders for editing the
//volume values.
//
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.EventObject;
import java.util.Vector;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTable;
import javax.swing.JWindow;
import javax.swing.SwingConstants;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
public class MixerTest2 extends JFrame {
  public MixerTest2() {
    super("Customer Editor Test");
    setSize(600, 160);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    MixerModel test = new MixerModel();
    test.dump();
    JTable jt = new JTable(test);
    jt.setDefaultRenderer(Volume.class, new VolumeRenderer());
    jt.setDefaultEditor(Volume.class, new VolumeEditor());
    JScrollPane jsp = new JScrollPane(jt);
    getContentPane().add(jsp, BorderLayout.CENTER);
  }
  public static void main(String args[]) {
    MixerTest2 mt = new MixerTest2();
    mt.setVisible(true);
  }
}
//MixerModel.java
//An audio mixer table data model. This model contains the following columns:
//<br> + Track name (String)
//<br> + Track start time (String)
//<br> + Track stop time (String)
//<br> + Left channel volume (Volume, 0 . . 100)
//<br> + Right channel volume (Volume, 0 . . 100)
//
class MixerModel extends AbstractTableModel {
  String headers[] = { "Track", "Start", "Stop", "Left Volume",
      "Right Volume" };
  Class columnClasses[] = { String.class, String.class, String.class,
      Volume.class, Volume.class };
  Object data[][] = {
      { "Bass", "0:00:000", "1:00:000", new Volume(56), new Volume(56) },
      { "Strings", "0:00:000", "0:52:010", new Volume(72), new Volume(52) },
      { "Brass", "0:08:000", "1:00:000", new Volume(99), new Volume(0) },
      { "Wind", "0:08:000", "1:00:000", new Volume(0), new Volume(99) }, };
  public int getRowCount() {
    return data.length;
  }
  public int getColumnCount() {
    return headers.length;
  }
  public Class getColumnClass(int c) {
    return columnClasses[c];
  }
  public String getColumnName(int c) {
    return headers[c];
  }
  public boolean isCellEditable(int r, int c) {
    return true;
  }
  public Object getValueAt(int r, int c) {
    return data[r][c];
  }
  // Ok, do something extra here so that if we get a String object back (from
  // a
  // text field editor) we can still store that as a valid Volume object. If
  // it"s just a string, then stick it directly into our data array.
  public void setValueAt(Object value, int r, int c) {
    if (c >= 3) {
      ((Volume) data[r][c]).setVolume(value);
    } else {
      data[r][c] = value;
    }
  }
  // A quick debugging utility to dump out the contents of our data structure
  public void dump() {
    for (int i = 0; i < data.length; i++) {
      System.out.print("|");
      for (int j = 0; j < data[0].length; j++) {
        System.out.print(data[i][j] + "|");
      }
      System.out.println();
    }
  }
}
//Volume.java
//A simple data structure for track volumes on a mixer.
//
class Volume {
  private int volume;
  public Volume(int v) {
    setVolume(v);
  }
  public Volume() {
    this(50);
  }
  public void setVolume(int v) {
    volume = (v < 0 ? 0 : v > 100 ? 100 : v);
  }
  public void setVolume(Object v) {
    if (v instanceof String) {
      setVolume(Integer.parseInt((String) v));
    } else if (v instanceof Number) {
      setVolume(((Number) v).intValue());
    } else if (v instanceof Volume) {
      setVolume(((Volume) v).getVolume());
    }
  }
  public int getVolume() {
    return volume;
  }
  public String toString() {
    return String.valueOf(volume);
  }
}
//VolumeRenderer.java
//A slider renderer for volume values in a table.
//
class VolumeRenderer extends JSlider implements TableCellRenderer {
  public VolumeRenderer() {
    super(SwingConstants.HORIZONTAL);
    // set a starting size...some 1.2/1.3 systems need this
    setSize(115, 15);
  }
  public Component getTableCellRendererComponent(JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) {
    if (value == null) {
      return this;
    }
    if (value instanceof Volume) {
      setValue(((Volume) value).getVolume());
    } else {
      setValue(0);
    }
    return this;
  }
}
//VolumeEditor.java
//A slider Editor for volume values in a table.
//
class VolumeEditor extends JSlider implements TableCellEditor {
  public OkCancel helper = new OkCancel();
  protected transient Vector listeners;
  protected transient int originalValue;
  protected transient boolean editing;
  public VolumeEditor() {
    super(SwingConstants.HORIZONTAL);
    listeners = new Vector();
  }
  // Inner class for the ok/cancel popup window that displays below the
  // active scrollbar. It"s position will have to be determined by the
  // editor when getTableCellEditorComponent() is called.
  public class OkCancel extends JWindow {
    private JButton okB = new JButton(new ImageIcon("accept.gif"));
    private JButton cancelB = new JButton(new ImageIcon("decline.gif"));
    private int w = 50;
    private int h = 24;
    public OkCancel() {
      setSize(w, h);
      setBackground(Color.yellow);
      JPanel p = new JPanel(new GridLayout(0, 2));
      //p.setBorder(BorderFactory.createLineBorder(Color.gray));
      //okB.setBorder(null);
      //cancelB.setBorder(null);
      p.add(okB);
      p.add(cancelB);
      setContentPane(p);
      okB.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
          stopCellEditing();
        }
      });
      cancelB.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
          cancelCellEditing();
        }
      });
    }
  }
  public Component getTableCellEditorComponent(JTable table, Object value,
      boolean isSelected, int row, int column) {
    if (value == null) {
      return this;
    }
    if (value instanceof Volume) {
      setValue(((Volume) value).getVolume());
    } else {
      setValue(0);
    }
    table.setRowSelectionInterval(row, row);
    table.setColumnSelectionInterval(column, column);
    originalValue = getValue();
    editing = true;
    Point p = table.getLocationOnScreen();
    Rectangle r = table.getCellRect(row, column, true);
    helper
        .setLocation(r.x + p.x + getWidth() - 50, r.y + p.y
            + getHeight());
    helper.setVisible(true);
    return this;
  }
  // CellEditor methods
  public void cancelCellEditing() {
    fireEditingCanceled();
    editing = false;
    helper.setVisible(false);
  }
  public Object getCellEditorValue() {
    return new Integer(getValue());
  }
  public boolean isCellEditable(EventObject eo) {
    return true;
  }
  public boolean shouldSelectCell(EventObject eo) {
    return true;
  }
  public boolean stopCellEditing() {
    fireEditingStopped();
    editing = false;
    helper.setVisible(false);
    return true;
  }
  public void addCellEditorListener(CellEditorListener cel) {
    listeners.addElement(cel);
  }
  public void removeCellEditorListener(CellEditorListener cel) {
    listeners.removeElement(cel);
  }
  protected void fireEditingCanceled() {
    setValue(originalValue);
    ChangeEvent ce = new ChangeEvent(this);
    for (int i = listeners.size() - 1; i >= 0; i--) {
      ((CellEditorListener) listeners.elementAt(i)).editingCanceled(ce);
    }
  }
  protected void fireEditingStopped() {
    ChangeEvent ce = new ChangeEvent(this);
    for (int i = listeners.size() - 1; i >= 0; i--) {
      ((CellEditorListener) listeners.elementAt(i)).editingStopped(ce);
    }
  }
}





Preventing Invalid Values in a Cell in a JTable Component

 
import java.awt.ruponent;
import javax.swing.AbstractCellEditor;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    TableColumn col = table.getColumnModel().getColumn(0);
    col.setCellEditor(new MyTableCellEditor());
  }
}
class MyTableCellEditor extends AbstractCellEditor implements TableCellEditor {
  public boolean stopCellEditing() {
    String s = (String) getCellEditorValue();
    return super.stopCellEditing();
  }
  JTextField field = new JTextField();
  public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
   
    return field;
  }
  public Object getCellEditorValue() {
    return null;
  }
}





Rendering an image in a JTable column

import java.awt.BorderLayout;
import java.awt.ruponent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
public class Main {
  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.getContentPane().setLayout(new BorderLayout());
    MyTableModel model = new MyTableModel();
    JTable table = new JTable(model);
    table.setRowHeight(80);
    table.getColumnModel().getColumn(0).setCellRenderer(new ImageRenderer());
    JScrollPane pane = new JScrollPane(table);
    frame.getContentPane().add(BorderLayout.CENTER, pane);
    frame.setSize(500, 400);
    frame.setVisible(true);
  }
}
class MyTableModel extends AbstractTableModel {
  public Object getValueAt(int row, int column) {
    return "" + (row * column);
  }
  public int getColumnCount() {
    return 4;
  }
  public int getRowCount() {
    return 5;
  }
}
class ImageRenderer extends DefaultTableCellRenderer {
  JLabel lbl = new JLabel();
  ImageIcon icon = new ImageIcon(getClass().getResource("sample.png"));
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    lbl.setText((String) value);
    lbl.setIcon(icon);
    return lbl;
  }
}





Setting the Activation Click Count for a Table Cell Editor in a JTable Component

    
    
import java.awt.ruponent;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import javax.swing.AbstractCellEditor;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    TableColumn col = table.getColumnModel().getColumn(0);
    col.setCellEditor(new MyTableCellEditor());
  }
}
class MyTableCellEditor extends AbstractCellEditor implements TableCellEditor {
  public boolean stopCellEditing() {
    String s = (String) getCellEditorValue();
    return super.stopCellEditing();
  }
  JTextField field = new JTextField();
  public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
   
    return field;
  }
  
  public boolean isCellEditable(EventObject evt) {
      if (evt instanceof MouseEvent) {
          int clickCount;
          clickCount = 2;
          return ((MouseEvent)evt).getClickCount() >= clickCount;
      }
      return true;
  }
  public Object getCellEditorValue() {
    return null;
  }
}





Shades every other column yellow

import java.awt.Color;
import java.awt.ruponent;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable() {
      public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int vColIndex) {
        Component c = super.prepareRenderer(renderer, rowIndex, vColIndex);
        if (vColIndex % 2 == 0 && !isCellSelected(rowIndex, vColIndex)) {
          c.setBackground(Color.yellow);
        } else {
          c.setBackground(getBackground());
        }
        return c;
      }
    };
  }
}





Shading Rows and Columns in a JTable Component

import java.awt.Color;
import java.awt.ruponent;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;
public class Main {
  public static void main(String[] argv) {
    JTable table = new JTable() {
      public Component prepareRenderer(TableCellRenderer renderer, int rowIndex, int vColIndex) {
        Component c = super.prepareRenderer(renderer, rowIndex, vColIndex);
        if (rowIndex % 2 == 0 && !isCellSelected(rowIndex, vColIndex)) {
          c.setBackground(Color.yellow);
        } else {
          c.setBackground(getBackground());
        }
        return c;
      }
    };
  }
}





StockTable 3: CellRenderer

 
/*
Swing, Second Edition
by Matthew Robinson, Pavel Vorobiev
*/
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import java.text.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class StocksTable3 extends JFrame 
{
  protected JTable m_table;
  protected StockTableData m_data;
  protected JLabel m_title;
  public StocksTable3() {
    super("Stocks Table");
    setSize(600, 300);
    m_data = new StockTableData();
    m_title = new JLabel(m_data.getTitle(), 
      new ImageIcon("money.gif"), SwingConstants.LEFT);
    m_title.setFont(new Font("TimesRoman",Font.BOLD,24));
    m_title.setForeground(Color.black);
    getContentPane().add(m_title, BorderLayout.NORTH);
    m_table = new JTable();
    m_table.setAutoCreateColumnsFromModel(false);
    m_table.setModel(m_data); 
        
    for (int k = 0; k < StockTableData.m_columns.length; k++) {
      DefaultTableCellRenderer renderer = new 
        ColoredTableCellRenderer();
      renderer.setHorizontalAlignment(
        StockTableData.m_columns[k].m_alignment);
      TableColumn column = new TableColumn(k, 
      StockTableData.m_columns[k].m_width, renderer, null);
      m_table.addColumn(column);   
    }
    JTableHeader header = m_table.getTableHeader();
    header.setUpdateTableInRealTime(false);
    JScrollPane ps = new JScrollPane();
    ps.getViewport().add(m_table);
    getContentPane().add(ps, BorderLayout.CENTER);
    WindowListener wndCloser = new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    };
    addWindowListener(wndCloser);
    setVisible(true);
  }
  public static void main(String argv[]) {
    new StocksTable3();
  }
}
class ColoredTableCellRenderer extends DefaultTableCellRenderer
{
  public void setValue(Object value) 
  {
    if (value instanceof ColorData) {
      ColorData cvalue = (ColorData)value;
      setForeground(cvalue.m_color);
      setText(cvalue.m_data.toString());
    }
    else if (value instanceof IconData) {
      IconData ivalue = (IconData)value;
      setIcon(ivalue.m_icon);
      setText(ivalue.m_data.toString());
    }
    else
      super.setValue(value);
  }
}
class Fraction
{
  public int m_whole;
  public int m_nom;
  public int m_den;
  public Fraction(double value) {
    int sign = value <0 ? -1 : 1;
    value = Math.abs(value);
    m_whole = (int)value;
    m_den = 32;
    m_nom = (int)((value-m_whole)*m_den);
    while (m_nom!=0 && m_nom%2==0) {
      m_nom /= 2;
      m_den /= 2;
    }
    if (m_whole==0)
      m_nom *= sign;
    else
      m_whole *= sign;
  }
  public double doubleValue() {
    return (double)m_whole + (double)m_nom/m_den;
  }
  public String toString() {
    if (m_nom==0)
      return ""+m_whole;
    else if (m_whole==0)
      return ""+m_nom+"/"+m_den;
    else
      return ""+m_whole+" "+m_nom+"/"+m_den;
  }
}
class SmartLong
{
  protected static NumberFormat FORMAT;
  static {
    FORMAT = NumberFormat.getInstance();
    FORMAT.setGroupingUsed(true);
  }
  public long m_value;
  public SmartLong(long value) { m_value = value; }
  public long longValue() { return m_value; }
  public String toString() { return FORMAT.format(m_value); }
}

class ColorData
{
  public Color  m_color;
  public Object m_data;
  public static Color GREEN = new Color(0, 128, 0);
  public static Color RED = Color.red;
  public ColorData(Fraction data) {
    m_color = data.doubleValue() >= 0 ? GREEN : RED;
    m_data  = data;
  }
  public ColorData(Color color, Object data) {
    m_color = color;
    m_data  = data;
  }
    
  public ColorData(Double data) {
    m_color = data.doubleValue() >= 0 ? GREEN : RED;
    m_data  = data;
  }
    
  public String toString() {
    return m_data.toString();
  }
}
class IconData
{
  public ImageIcon  m_icon;
  public Object m_data;
  public IconData(ImageIcon icon, Object data) {
    m_icon = icon;
    m_data = data;
  }
    
  public String toString() {
    return m_data.toString();
  }
}
class StockData
{
  public static ImageIcon ICON_UP = new ImageIcon("ArrUp.gif");
  public static ImageIcon ICON_DOWN = new ImageIcon("ArrDown.gif");
  public static ImageIcon ICON_BLANK = new ImageIcon("blank.gif");
  public IconData  m_symbol;
  public String  m_name;
  public Fraction  m_last;
  public Fraction  m_open;
  public ColorData  m_change;
  public ColorData  m_changePr;
  public SmartLong  m_volume;
  public StockData(String symbol, String name, double last, 
   double open, double change, double changePr, long volume) {
    m_symbol = new IconData(getIcon(change), symbol);
    m_name = name;
    m_last = new Fraction(last);
    m_open = new Fraction(open);
    m_change = new ColorData(new Fraction(change));
    m_changePr = new ColorData(new Double(changePr));
    m_volume = new SmartLong(volume);
  }
  public static ImageIcon getIcon(double change) {
    return (change>0 ? ICON_UP : (change<0 ? ICON_DOWN : 
      ICON_BLANK));
  }
}
class ColumnData
{
  public String  m_title;
  public int     m_width;
  public int     m_alignment;
  public ColumnData(String title, int width, int alignment) {
    m_title = title;
    m_width = width;
    m_alignment = alignment;
  }
}
class StockTableData extends AbstractTableModel 
{
  static final public ColumnData m_columns[] = {
    new ColumnData( "Symbol", 100, JLabel.LEFT ),
    new ColumnData( "Name", 160, JLabel.LEFT ),
    new ColumnData( "Last", 100, JLabel.RIGHT ),
    new ColumnData( "Open", 100, JLabel.RIGHT ),
    new ColumnData( "Change", 100, JLabel.RIGHT ),
    new ColumnData( "Change %", 100, JLabel.RIGHT ),
    new ColumnData( "Volume", 100, JLabel.RIGHT )
  };
  protected SimpleDateFormat m_frm;
  protected Vector m_vector;
  protected Date   m_date;
  public StockTableData() {
    m_frm = new SimpleDateFormat("MM/dd/yyyy");
    m_vector = new Vector();
    setDefaultData();
  }
  public void setDefaultData() {
    try { 
      m_date = m_frm.parse("4/6/1999"); 
    }
    catch (java.text.ParseException ex) { 
      m_date = null; 
    }
    m_vector.removeAllElements();
    m_vector.addElement(new StockData("ORCL", "Oracle Corp.", 
      23.6875, 25.375, -1.6875, -6.42, 24976600));
    m_vector.addElement(new StockData("EGGS", "Egghead.ru", 
      17.25, 17.4375, -0.1875, -1.43, 2146400));
    m_vector.addElement(new StockData("T", "AT&T", 
      65.1875, 66, -0.8125, -0.10, 554000));
    m_vector.addElement(new StockData("LU", "Lucent Technology", 
      64.625, 59.9375, 4.6875, 9.65, 29856300));
    m_vector.addElement(new StockData("FON", "Sprint", 
      104.5625, 106.375, -1.8125, -1.82, 1135100));
    m_vector.addElement(new StockData("ENML", "Enamelon Inc.", 
      4.875, 5, -0.125, 0, 35900)); 
    m_vector.addElement(new StockData("CPQ", "Compaq Computers", 
      30.875, 31.25, -0.375, -2.18, 11853900));
    m_vector.addElement(new StockData("MSFT", "Microsoft Corp.", 
      94.0625, 95.1875, -1.125, -0.92, 19836900));
    m_vector.addElement(new StockData("DELL", "Dell Computers", 
      46.1875, 44.5, 1.6875, 6.24, 47310000));
    m_vector.addElement(new StockData("SUNW", "Sun Microsystems", 
      140.625, 130.9375, 10, 10.625, 17734600));
    m_vector.addElement(new StockData("IBM", "Intl. Bus. Machines", 
      183, 183.125, -0.125, -0.51, 4371400));
    m_vector.addElement(new StockData("HWP", "Hewlett-Packard", 
      70, 71.0625, -1.4375, -2.01, 2410700));
    m_vector.addElement(new StockData("UIS", "Unisys Corp.", 
      28.25, 29, -0.75, -2.59, 2576200));
    m_vector.addElement(new StockData("SNE", "Sony Corp.", 
      96.1875, 95.625, 1.125, 1.18, 330600));
    m_vector.addElement(new StockData("NOVL", "Novell Inc.", 
      24.0625, 24.375, -0.3125, -3.02, 6047900));
    m_vector.addElement(new StockData("HIT", "Hitachi, Ltd.", 
      78.5, 77.625, 0.875, 1.12, 49400));
  }
  public int getRowCount() {
    return m_vector==null ? 0 : m_vector.size(); 
  }
  public int getColumnCount() { 
    return m_columns.length; 
  } 
  public String getColumnName(int column) { 
    return m_columns[column].m_title; 
  }
 
  public boolean isCellEditable(int nRow, int nCol) {
    return false;
  }
  public Object getValueAt(int nRow, int nCol) {
    if (nRow < 0 || nRow>=getRowCount())
      return "";
    StockData row = (StockData)m_vector.elementAt(nRow);
    switch (nCol) {
      case 0: return row.m_symbol;
      case 1: return row.m_name;
      case 2: return row.m_last;
      case 3: return row.m_open;
      case 4: return row.m_change;
      case 5: return row.m_changePr;
      case 6: return row.m_volume;
    }
    return "";
  }
  public String getTitle() {
    if (m_date==null)
      return "Stock Quotes";
    return "Stock Quotes at "+m_frm.format(m_date);
  }
}





Tab in and out JComboBox in JTable

 
/*
 * 
  Code reference: http://forum.java.sun.ru/thread.jspa?threadID=384665&messageID=3310903  
Pratap Singh
Email:  pratap.singh at siemens.ru
        at is @
 * 
 * */
import java.awt.BorderLayout;
import java.awt.ruponent;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Calendar;
import java.util.EventObject;
import java.util.GregorianCalendar;
import javax.swing.ruboBoxEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.EventListenerList;
import javax.swing.plaf.basic.BasicComboBoxUI;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class SimpleTableTestTabComboBox extends JFrame {
  protected JTable table;
  public SimpleTableTestTabComboBox() {
    Container pane = getContentPane();
    pane.setLayout(new BorderLayout());
    TableValues tv = new TableValues();
    table = new JTable(tv);
    TableColumnModel tcm = table.getColumnModel();
    TableColumn tc = tcm.getColumn(TableValues.GENDER);
//    tc.setCellRenderer(new GenderRenderer());
    tc.setCellEditor(new GenderEditor());
    JScrollPane jsp = new JScrollPane(table);
    pane.add(jsp, BorderLayout.CENTER);
    pane.add(new JTextField(), BorderLayout.SOUTH);
  }
  public static void main(String[] args) {
    SimpleTableTestTabComboBox stt = new SimpleTableTestTabComboBox();
    stt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    stt.setSize(400, 300);
    stt.setVisible(true);
  }
}
class TableValues extends AbstractTableModel {
  public final static int FIRST_NAME = 0;
  public final static int LAST_NAME = 1;
  public final static int DATE_OF_BIRTH = 2;
  public final static int ACCOUNT_BALANCE = 3;
  public final static int GENDER = 4;
  public final static boolean GENDER_MALE = true;
  public final static boolean GENDER_FEMALE = false;
  public final static String[] columnNames = { "First Name", "Last Name", "Date of Birth",
      "Account Balance", "Gender" };
  public Object[][] values = {
      { "Clay", "Ashworth", new GregorianCalendar(1962, Calendar.FEBRUARY, 20).getTime(),
          new Float(12345.67), "three" },
      { "Jacob", "Ashworth", new GregorianCalendar(1987, Calendar.JANUARY, 6).getTime(),
          new Float(23456.78), "three1" },
      { "Jordan", "Ashworth", new GregorianCalendar(1989, Calendar.AUGUST, 31).getTime(),
          new Float(34567.89), "three2" },
      { "Evelyn", "Kirk", new GregorianCalendar(1945, Calendar.JANUARY, 16).getTime(),
          new Float(-456.70), "One" },
      { "Belle", "Spyres", new GregorianCalendar(1907, Calendar.AUGUST, 2).getTime(),
          new Float(567.00), "two" } };
  public int getRowCount() {
    return values.length;
  }
  public int getColumnCount() {
    return values[0].length;
  }
  public Object getValueAt(int row, int column) {
    return values[row][column];
  }
  public void setValueAt(Object aValue, int r, int c) {
    values[r][c] = aValue;
  }
  public String getColumnName(int column) {
    return columnNames[column];
  }
  public boolean isCellEditable(int r, int c) {
    return c == GENDER;
  }
}
class MyComboUI extends BasicComboBoxUI {
  public JList getList() {
    return listBox;
  }
}
class GenderRenderer extends JComboBox implements TableCellRenderer {
  public GenderRenderer() {
    super();
    addItem("three");
    addItem("three1");
    addItem("three2");
    addItem("One");
    addItem("two");
  }
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    if (hasFocus) {
      table.editCellAt(row, column);
      JComboBox combo = (JComboBox) table.getColumnModel().getColumn(TableValues.GENDER)
          .getCellEditor();
      ComboBoxEditor editor = (ComboBoxEditor) combo.getEditor();
      JTextField tf = (JTextField) editor.getEditorComponent();
      tf.requestFocusInWindow();
      tf.selectAll();
    }
    if (isSelected) {
      setForeground(table.getSelectionForeground());
      super.setBackground(table.getSelectionBackground());
    } else {
      setForeground(table.getForeground());
      setBackground(table.getBackground());
    }
    setSelectedItem(value);
    return this;
  }
}
class GenderEditor extends JComboBox implements TableCellEditor, CaretListener {
  protected EventListenerList listenerList = new EventListenerList();
  protected ChangeEvent changeEvent = new ChangeEvent(this);
  private MyComboUI comboUi = new MyComboUI();
  private JTextField tf;
  Object newValue;
  public GenderEditor() {
    super();
    setUI(comboUi);
    // comboUi.get
    addItem("three");
    addItem("three1");
    addItem("three2");
    addItem("One");
    addItem("two");
    setEditable(true);
    tf = (JTextField) getEditor().getEditorComponent();
    tf.addCaretListener(this);
    tf.addKeyListener(new KeyAdapter() {
      public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == e.VK_ENTER) {
          Object value = comboUi.getList().getSelectedValue();
          tf.transferFocus();
          hidePopup();
          System.out.println("enter pressed, selected value, when enter pressed: " + value);
          fireEditingStopped();
        }
      }
    });
    addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent event) {
        // fireEditingStopped();
      }
    });
  }
  public void addCellEditorListener(CellEditorListener listener) {
    listenerList.add(CellEditorListener.class, listener);
  }
  public void removeCellEditorListener(CellEditorListener listener) {
    listenerList.remove(CellEditorListener.class, listener);
  }
  protected void fireEditingStopped() {
    System.out.println("fireEditingStopped called ");
    CellEditorListener listener;
    Object[] listeners = listenerList.getListenerList();
    for (int i = 0; i < listeners.length; i++) {
      if (listeners[i] == CellEditorListener.class) {
        listener = (CellEditorListener) listeners[i + 1];
        listener.editingStopped(changeEvent);
      }
    }
  }
  protected void fireEditingCanceled() {
    CellEditorListener listener;
    Object[] listeners = listenerList.getListenerList();
    for (int i = 0; i < listeners.length; i++) {
      //if (listeners == CellEditorListener.class) {
      if (listeners[i] == CellEditorListener.class) {
        listener = (CellEditorListener) listeners[i + 1];
        listener.editingCanceled(changeEvent);
      }
    }
  }
  public void cancelCellEditing() {
    System.out.println("cancelCellEditing called ");
    fireEditingCanceled();
  }
  public boolean stopCellEditing() {
    System.out.println("stopCellEditing called ");
    fireEditingStopped();
    return true;
  }
  public boolean isCellEditable(EventObject event) {
    return true;
  }
  public boolean shouldSelectCell(EventObject event) {
    return true;
  }
  public Object getCellEditorValue() {
    System.out.println("getCellEditorValue called returning vlaue: " + newValue);
    tf.setText(newValue.toString());
    return newValue;
    // return super.getSelectedItem();
  }
  public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected,
      int row, int column) {
    return this;
  }
  public void caretUpdate(CaretEvent e) {
    if (!isPopupVisible() && tf.isShowing() && tf.hasFocus())
      showPopup();
    JTextField tf = (JTextField) e.getSource();
    String text = tf.getText().toLowerCase();
    int index = -1;
    for (int i = 0; i < super.getItemCount(); i++) {
      String item = ((String) getItemAt(i)).toLowerCase();
      if (item.startsWith(text)) {
        index = i;
        break;
      }
    }
    if (index != -1)
      comboUi.getList().setSelectedIndex(index);
    else
      comboUi.getList().clearSelection();
    newValue = comboUi.getList().getSelectedValue();
    System.out.println("new value set to: " + newValue);
  }
}





Table Cell Editor: ComboBoxCellEditor

 
/*
Applied Java Patterns
Stephen Stelting, Olav Maassen
Paper, 598 pp.
ISBN: 0130935387
Published: DEC 26, 2001    
*/
import java.awt.Container;
import java.awt.Dimension;
import javax.swing.*;
public class TableDemoApplet extends JApplet {
    
    public TableDemoApplet() {
        createGUI(getContentPane());
    }
    
    private static void createGUI(Container contentPane) {
        Object[][] rowData = new String[][] { {"98-43", "AraAra! SL"},
                                              {"81-31", "Aragones Transports SA"},
                                              {"12-72", "Rocca SL"},
                                              {"99-10", "Rodriguez e Hijos SA"},
                                              {"00-65", "Rimbau Motors SL"} };
        JTable table = new JTable(rowData, new String[] {"Part No", "Provider"});
        
        JComboBox companyComboBox = new JComboBox(new Object[] {"AraAra! SL", "Aragones Transports SA", "Rocca SL", "Rodriguez e Hijos SA", "Rimbau Motors SL"});
        companyComboBox.setEditable(true);
        new S15WorkingBackspace(companyComboBox);
        // setup the ComboBoxCellEditor, DefaultCellEditor won"t work!
        table.getColumnModel().getColumn(1).setCellEditor(new ComboBoxCellEditor(companyComboBox));
        
        table.setPreferredScrollableViewportSize(new Dimension(400, 100));
        JScrollPane scrollPane = new JScrollPane(table);
        
        contentPane.setLayout(new java.awt.FlowLayout());
        contentPane.add(scrollPane);
        contentPane.add(new JTextField("HALLO!"));
    }
    
    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation(3);
                createGUI(frame.getContentPane());
                frame.pack(); frame.setVisible(true);
            }
        });
    }   
}





Table Editor: Editable Color Column

 
/*
Definitive Guide to Swing for Java 2, Second Edition
By John Zukowski     
ISBN: 1-893115-78-X
Publisher: APress
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Graphics;
import java.awt.Polygon;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.JComboBox;
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.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.TableModel;
public class EditableColorColumn {
  public static void main(String args[]) {
    Color choices[] = { Color.red, Color.orange, Color.yellow, Color.green,
        Color.blue, Color.magenta };
    ComboTableCellRenderer renderer = new ComboTableCellRenderer();
    JComboBox comboBox = new JComboBox(choices);
    comboBox.setRenderer(renderer);
    TableCellEditor editor = new DefaultCellEditor(comboBox);
    JFrame frame = new JFrame("Editable Color Table");
    TableModel model = new ColorTableModel();
    JTable table = new JTable(model);
    TableColumn column = table.getColumnModel().getColumn(3);
    column.setCellRenderer(renderer);
    column.setCellEditor(editor);
    JScrollPane scrollPane = new JScrollPane(table);
    frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
    frame.setSize(400, 150);
    frame.setVisible(true);
  }
}
class ComboTableCellRenderer implements ListCellRenderer, TableCellRenderer {
  DefaultListCellRenderer listRenderer = new DefaultListCellRenderer();
  DefaultTableCellRenderer tableRenderer = new DefaultTableCellRenderer();
  private void configureRenderer(JLabel renderer, Object value) {
    if ((value != null) && (value instanceof Color)) {
      renderer.setIcon(new DiamondIcon((Color) value));
      renderer.setText("");
    } else {
      renderer.setIcon(null);
      renderer.setText((String) value);
    }
  }
  public Component getListCellRendererComponent(JList list, Object value,
      int index, boolean isSelected, boolean cellHasFocus) {
    listRenderer = (DefaultListCellRenderer) listRenderer
        .getListCellRendererComponent(list, value, index, isSelected,
            cellHasFocus);
    configureRenderer(listRenderer, value);
    return listRenderer;
  }
  public Component getTableCellRendererComponent(JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) {
    tableRenderer = (DefaultTableCellRenderer) tableRenderer
        .getTableCellRendererComponent(table, value, isSelected,
            hasFocus, row, column);
    configureRenderer(tableRenderer, value);
    return tableRenderer;
  }
}
class ColorTableModel extends AbstractTableModel {
  Object rowData[][] = { { "1", "ichi - \u4E00", Boolean.TRUE, Color.red },
      { "2", "ni - \u4E8C", Boolean.TRUE, Color.blue },
      { "3", "san - \u4E09", Boolean.FALSE, Color.green },
      { "4", "shi - \u56DB", Boolean.TRUE, Color.magenta },
      { "5", "go - \u4E94", Boolean.FALSE, Color.pink }, };
  String columnNames[] = { "English", "Japanese", "Boolean", "Color" };
  public int getColumnCount() {
    return columnNames.length;
  }
  public String getColumnName(int column) {
    return columnNames[column];
  }
  public int getRowCount() {
    return rowData.length;
  }
  public Object getValueAt(int row, int column) {
    return rowData[row][column];
  }
  public Class getColumnClass(int column) {
    return (getValueAt(0, column).getClass());
  }
  public void setValueAt(Object value, int row, int column) {
    rowData[row][column] = value;
  }
  public boolean isCellEditable(int row, int column) {
    return (column != 0);
  }
}
class DiamondIcon implements Icon {
  private Color color;
  private boolean selected;
  private int width;
  private int height;
  private Polygon poly;
  private static final int DEFAULT_WIDTH = 10;
  private static final int DEFAULT_HEIGHT = 10;
  public DiamondIcon(Color color) {
    this(color, true, DEFAULT_WIDTH, DEFAULT_HEIGHT);
  }
  public DiamondIcon(Color color, boolean selected) {
    this(color, selected, DEFAULT_WIDTH, DEFAULT_HEIGHT);
  }
  public DiamondIcon(Color color, boolean selected, int width, int height) {
    this.color = color;
    this.selected = selected;
    this.width = width;
    this.height = height;
    initPolygon();
  }
  private void initPolygon() {
    poly = new Polygon();
    int halfWidth = width / 2;
    int halfHeight = height / 2;
    poly.addPoint(0, halfHeight);
    poly.addPoint(halfWidth, 0);
    poly.addPoint(width, halfHeight);
    poly.addPoint(halfWidth, height);
  }
  public int getIconHeight() {
    return height;
  }
  public int getIconWidth() {
    return width;
  }
  public void paintIcon(Component c, Graphics g, int x, int y) {
    g.setColor(color);
    g.translate(x, y);
    if (selected) {
      g.fillPolygon(poly);
    } else {
      g.drawPolygon(poly);
    }
    g.translate(-x, -y);
  }
}





Table with a custom cell renderer and editor for the color data

 
/* From http://java.sun.ru/docs/books/tutorial/index.html */
/*
 * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * -Redistribution of source code must retain the above copyright notice, this
 *  list of conditions and the following disclaimer.
 *
 * -Redistribution in binary form must reproduce the above copyright notice,
 *  this list of conditions and the following disclaimer in the documentation
 *  and/or other materials provided with the distribution.
 *
 * Neither the name of Sun Microsystems, Inc. or the names of contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
 * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
 * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
 * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
 * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *
 * You acknowledge that this software is not designed, licensed or intended
 * for use in the design, construction, operation or maintenance of any
 * nuclear facility.
 */
/*
 * TableDialogEditDemo.java is a 1.4 application that requires these files:
 *   ColorRenderer.java
 *   ColorEditor.java
 */
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.border.Border;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
/**
 * This is like TableDemo, except that it substitutes a
 * Favorite Color column for the Last Name column and specifies
 * a custom cell renderer and editor for the color data.
 */
public class TableDialogEditDemo extends JPanel {
    private boolean DEBUG = false;
    public TableDialogEditDemo() {
        super(new GridLayout(1,0));
        JTable table = new JTable(new MyTableModel());
        table.setPreferredScrollableViewportSize(new Dimension(500, 70));
        //Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);
        //Set up renderer and editor for the Favorite Color column.
        table.setDefaultRenderer(Color.class,
                                 new ColorRenderer(true));
        table.setDefaultEditor(Color.class,
                               new ColorEditor());
        //Add the scroll pane to this panel.
        add(scrollPane);
    }
    class MyTableModel extends AbstractTableModel {
        private String[] columnNames = {"First Name",
                                        "Favorite Color",
                                        "Sport",
                                        "# of Years",
                                        "Vegetarian"};
        private Object[][] data = {
            {"Mary", new Color(153, 0, 153),
             "Snowboarding", new Integer(5), new Boolean(false)},
            {"Alison", new Color(51, 51, 153),
             "Rowing", new Integer(3), new Boolean(true)},
            {"Kathy", new Color(51, 102, 51),
             "Knitting", new Integer(2), new Boolean(false)},
            {"Sharon", Color.red,
             "Speed reading", new Integer(20), new Boolean(true)},
            {"Philip", Color.pink,
             "Pool", new Integer(10), new Boolean(false)}
        };
        public int getColumnCount() {
            return columnNames.length;
        }
        public int getRowCount() {
            return data.length;
        }
        public String getColumnName(int col) {
            return columnNames[col];
        }
        public Object getValueAt(int row, int col) {
            return data[row][col];
        }
        /*
         * JTable uses this method to determine the default renderer/
         * editor for each cell.  If we didn"t implement this method,
         * then the last column would contain text ("true"/"false"),
         * rather than a check box.
         */
        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }
        public boolean isCellEditable(int row, int col) {
            //Note that the data/cell address is constant,
            //no matter where the cell appears onscreen.
            if (col < 1) {
                return false;
            } else {
                return true;
            }
        }
        public void setValueAt(Object value, int row, int col) {
            if (DEBUG) {
                System.out.println("Setting value at " + row + "," + col
                                   + " to " + value
                                   + " (an instance of "
                                   + value.getClass() + ")");
            }
            data[row][col] = value;
            fireTableCellUpdated(row, col);
            if (DEBUG) {
                System.out.println("New value of data:");
                printDebugData();
            }
        }
        private void printDebugData() {
            int numRows = getRowCount();
            int numCols = getColumnCount();
            for (int i=0; i < numRows; i++) {
                System.out.print("    row " + i + ":");
                for (int j=0; j < numCols; j++) {
                    System.out.print("  " + data[i][j]);
                }
                System.out.println();
            }
            System.out.println("--------------------------");
        }
    }
    /**
     * Create the GUI and show it.  For thread safety,
     * this method should be invoked from the
     * event-dispatching thread.
     */
    private static void createAndShowGUI() {
        //Make sure we have nice window decorations.
        JFrame.setDefaultLookAndFeelDecorated(true);
        //Create and set up the window.
        JFrame frame = new JFrame("TableDialogEditDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //Create and set up the content pane.
        JComponent newContentPane = new TableDialogEditDemo();
        newContentPane.setOpaque(true); //content panes must be opaque
        frame.setContentPane(newContentPane);
        //Display the window.
        frame.pack();
        frame.setVisible(true);
    }
    public static void main(String[] args) {
        //Schedule a job for the event-dispatching thread:
        //creating and showing this application"s GUI.
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
/* 
 * ColorRenderer.java (compiles with releases 1.2, 1.3, and 1.4) is used by 
 * TableDialogEditDemo.java.
 */
class ColorRenderer extends JLabel
                           implements TableCellRenderer {
    Border unselectedBorder = null;
    Border selectedBorder = null;
    boolean isBordered = true;
    public ColorRenderer(boolean isBordered) {
        this.isBordered = isBordered;
        setOpaque(true); //MUST do this for background to show up.
    }
    public Component getTableCellRendererComponent(
                            JTable table, Object color,
                            boolean isSelected, boolean hasFocus,
                            int row, int column) {
        Color newColor = (Color)color;
        setBackground(newColor);
        if (isBordered) {
            if (isSelected) {
                if (selectedBorder == null) {
                    selectedBorder = BorderFactory.createMatteBorder(2,5,2,5,
                                              table.getSelectionBackground());
                }
                setBorder(selectedBorder);
            } else {
                if (unselectedBorder == null) {
                    unselectedBorder = BorderFactory.createMatteBorder(2,5,2,5,
                                              table.getBackground());
                }
                setBorder(unselectedBorder);
            }
        }
        
        setToolTipText("RGB value: " + newColor.getRed() + ", "
                                     + newColor.getGreen() + ", "
                                     + newColor.getBlue());
        return this;
    }
}
/* 
 * ColorEditor.java (compiles with releases 1.3 and 1.4) is used by 
 * TableDialogEditDemo.java.
 */
 class ColorEditor extends AbstractCellEditor
                         implements TableCellEditor,
                  ActionListener {
    Color currentColor;
    JButton button;
    JColorChooser colorChooser;
    JDialog dialog;
    protected static final String EDIT = "edit";
    public ColorEditor() {
        //Set up the editor (from the table"s point of view),
        //which is a button.
        //This button brings up the color chooser dialog,
        //which is the editor from the user"s point of view.
        button = new JButton();
        button.setActionCommand(EDIT);
        button.addActionListener(this);
        button.setBorderPainted(false);
        //Set up the dialog that the button brings up.
        colorChooser = new JColorChooser();
        dialog = JColorChooser.createDialog(button,
                                        "Pick a Color",
                                        true,  //modal
                                        colorChooser,
                                        this,  //OK button handler
                                        null); //no CANCEL button handler
    }
    /**
     * Handles events from the editor button and from
     * the dialog"s OK button.
     */
    public void actionPerformed(ActionEvent e) {
        if (EDIT.equals(e.getActionCommand())) {
            //The user has clicked the cell, so
            //bring up the dialog.
            button.setBackground(currentColor);
            colorChooser.setColor(currentColor);
            dialog.setVisible(true);
            //Make the renderer reappear.
            fireEditingStopped();
        } else { //User pressed dialog"s "OK" button.
            currentColor = colorChooser.getColor();
        }
    }
    //Implement the one CellEditor method that AbstractCellEditor doesn"t.
    public Object getCellEditorValue() {
        return currentColor;
    }
    //Implement the one method defined by TableCellEditor.
    public Component getTableCellEditorComponent(JTable table,
                                                 Object value,
                                                 boolean isSelected,
                                                 int row,
                                                 int column) {
        currentColor = (Color)value;
        return button;
    }
}





Table with initialized column sizes and a combo box editor

 
/* From http://java.sun.ru/docs/books/tutorial/index.html */
/*
 * Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * -Redistribution of source code must retain the above copyright notice, this
 *  list of conditions and the following disclaimer.
 *
 * -Redistribution in binary form must reproduce the above copyright notice,
 *  this list of conditions and the following disclaimer in the documentation
 *  and/or other materials provided with the distribution.
 *
 * Neither the name of Sun Microsystems, Inc. or the names of contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
 * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
 * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN MIDROSYSTEMS, INC. ("SUN")
 * AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR ANY LOST
 * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
 * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
 * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
 * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 *
 * You acknowledge that this software is not designed, licensed or intended
 * for use in the design, construction, operation or maintenance of any
 * nuclear facility.
 */
/*
 * TableRenderDemo.java is a 1.4 application that requires no other files.
 */
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import java.awt.ruponent;
import java.awt.Dimension;
import java.awt.GridLayout;
/**
 * TableRenderDemo is just like TableDemo, except that it explicitly initializes
 * column sizes and it uses a combo box as an editor for the Sport column.
 */
public class TableRenderDemo extends JPanel {
  private boolean DEBUG = false;
  public TableRenderDemo() {
    super(new GridLayout(1, 0));
    JTable table = new JTable(new MyTableModel());
    table.setPreferredScrollableViewportSize(new Dimension(500, 70));
    //Create the scroll pane and add the table to it.
    JScrollPane scrollPane = new JScrollPane(table);
    //Set up column sizes.
    initColumnSizes(table);
    //Fiddle with the Sport column"s cell editors/renderers.
    setUpSportColumn(table, table.getColumnModel().getColumn(2));
    //Add the scroll pane to this panel.
    add(scrollPane);
  }
  /*
   * This method picks good column sizes. If all column heads are wider than
   * the column"s cells" contents, then you can just use
   * column.sizeWidthToFit().
   */
  private void initColumnSizes(JTable table) {
    MyTableModel model = (MyTableModel) table.getModel();
    TableColumn column = null;
    Component comp = null;
    int headerWidth = 0;
    int cellWidth = 0;
    Object[] longValues = model.longValues;
    TableCellRenderer headerRenderer = table.getTableHeader()
        .getDefaultRenderer();
    for (int i = 0; i < 5; i++) {
      column = table.getColumnModel().getColumn(i);
      comp = headerRenderer.getTableCellRendererComponent(null, column
          .getHeaderValue(), false, false, 0, 0);
      headerWidth = comp.getPreferredSize().width;
      comp = table.getDefaultRenderer(model.getColumnClass(i))
          .getTableCellRendererComponent(table, longValues[i], false,
              false, 0, i);
      cellWidth = comp.getPreferredSize().width;
      if (DEBUG) {
        System.out.println("Initializing width of column " + i + ". "
            + "headerWidth = " + headerWidth + "; cellWidth = "
            + cellWidth);
      }
      //XXX: Before Swing 1.1 Beta 2, use setMinWidth instead.
      column.setPreferredWidth(Math.max(headerWidth, cellWidth));
    }
  }
  public void setUpSportColumn(JTable table, TableColumn sportColumn) {
    //Set up the editor for the sport cells.
    JComboBox comboBox = new JComboBox();
    comboBox.addItem("Snowboarding");
    comboBox.addItem("Rowing");
    comboBox.addItem("Knitting");
    comboBox.addItem("Speed reading");
    comboBox.addItem("Pool");
    comboBox.addItem("None of the above");
    sportColumn.setCellEditor(new DefaultCellEditor(comboBox));
    //Set up tool tips for the sport cells.
    DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
    renderer.setToolTipText("Click for combo box");
    sportColumn.setCellRenderer(renderer);
  }
  class MyTableModel extends AbstractTableModel {
    private String[] columnNames = { "First Name", "Last Name", "Sport",
        "# of Years", "Vegetarian" };
    private Object[][] data = {
        { "Mary", "Campione", "Snowboarding", new Integer(5),
            new Boolean(false) },
        { "Alison", "Huml", "Rowing", new Integer(3), new Boolean(true) },
        { "Kathy", "Walrath", "Knitting", new Integer(2),
            new Boolean(false) },
        { "Sharon", "Zakhour", "Speed reading", new Integer(20),
            new Boolean(true) },
        { "Philip", "Milne", "Pool", new Integer(10),
            new Boolean(false) } };
    public final Object[] longValues = { "Sharon", "Campione",
        "None of the above", new Integer(20), Boolean.TRUE };
    public int getColumnCount() {
      return columnNames.length;
    }
    public int getRowCount() {
      return data.length;
    }
    public String getColumnName(int col) {
      return columnNames[col];
    }
    public Object getValueAt(int row, int col) {
      return data[row][col];
    }
    /*
     * JTable uses this method to determine the default renderer/ editor for
     * each cell. If we didn"t implement this method, then the last column
     * would contain text ("true"/"false"), rather than a check box.
     */
    public Class getColumnClass(int c) {
      return getValueAt(0, c).getClass();
    }
    /*
     * Don"t need to implement this method unless your table"s editable.
     */
    public boolean isCellEditable(int row, int col) {
      //Note that the data/cell address is constant,
      //no matter where the cell appears onscreen.
      if (col < 2) {
        return false;
      } else {
        return true;
      }
    }
    /*
     * Don"t need to implement this method unless your table"s data can
     * change.
     */
    public void setValueAt(Object value, int row, int col) {
      if (DEBUG) {
        System.out.println("Setting value at " + row + "," + col
            + " to " + value + " (an instance of "
            + value.getClass() + ")");
      }
      data[row][col] = value;
      fireTableCellUpdated(row, col);
      if (DEBUG) {
        System.out.println("New value of data:");
        printDebugData();
      }
    }
    private void printDebugData() {
      int numRows = getRowCount();
      int numCols = getColumnCount();
      for (int i = 0; i < numRows; i++) {
        System.out.print("    row " + i + ":");
        for (int j = 0; j < numCols; j++) {
          System.out.print("  " + data[i][j]);
        }
        System.out.println();
      }
      System.out.println("--------------------------");
    }
  }
  /**
   * Create the GUI and show it. For thread safety, this method should be
   * invoked from the event-dispatching thread.
   */
  private static void createAndShowGUI() {
    //Make sure we have nice window decorations.
    JFrame.setDefaultLookAndFeelDecorated(true);
    //Create and set up the window.
    JFrame frame = new JFrame("TableRenderDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //Create and set up the content pane.
    TableRenderDemo newContentPane = new TableRenderDemo();
    newContentPane.setOpaque(true); //content panes must be opaque
    frame.setContentPane(newContentPane);
    //Display the window.
    frame.pack();
    frame.setVisible(true);
  }
  public static void main(String[] args) {
    //Schedule a job for the event-dispatching thread:
    //creating and showing this application"s GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    });
  }
}





Using a JComboBox in a Cell in a JTable Component

import java.awt.ruponent;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    DefaultTableModel model = (DefaultTableModel) table.getModel();
    model.addColumn("A", new Object[] { "item1" });
    model.addColumn("B", new Object[] { "item2" });
    String[] values = new String[] { "1", "2", "3" };
    TableColumn col = table.getColumnModel().getColumn(0);
    col.setCellEditor(new MyComboBoxEditor(values));
    col.setCellRenderer(new MyComboBoxRenderer(values));
  }
}
class MyComboBoxRenderer extends JComboBox implements TableCellRenderer {
  public MyComboBoxRenderer(String[] items) {
    super(items);
  }
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    if (isSelected) {
      setForeground(table.getSelectionForeground());
      super.setBackground(table.getSelectionBackground());
    } else {
      setForeground(table.getForeground());
      setBackground(table.getBackground());
    }
    setSelectedItem(value);
    return this;
  }
}
class MyComboBoxEditor extends DefaultCellEditor {
  public MyComboBoxEditor(String[] items) {
    super(new JComboBox(items));
  }
}





Using a List JSpinner as a Cell Editor in a JTable Component

import java.awt.ruponent;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.EventObject;
import javax.swing.AbstractCellEditor;
import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.SpinnerListModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    DefaultTableModel model = (DefaultTableModel) table.getModel();
    model.addColumn("A", new Object[] { "item1" });
    model.addColumn("B", new Object[] { "item2" });
    String[] values = new String[] { "1", "2", "3" };
    TableColumn col = table.getColumnModel().getColumn(0);
    col.setCellEditor(new SpinnerEditor(values));
  }
}
class SpinnerEditor extends AbstractCellEditor implements TableCellEditor {
  final JSpinner spinner = new JSpinner();
  public SpinnerEditor(String[] items) {
    spinner.setModel(new SpinnerListModel(Arrays.asList(items)));
  }
  public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected,
      int row, int column) {
    spinner.setValue(value);
    return spinner;
  }
  public boolean isCellEditable(EventObject evt) {
    if (evt instanceof MouseEvent) {
      return ((MouseEvent) evt).getClickCount() >= 2;
    }
    return true;
  }
  public Object getCellEditorValue() {
    return spinner.getValue();
  }
}





Using Built-In Cell Renderers and Editors in a JTable Component

import java.util.Date;
import java.util.Enumeration;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
public class Main {
  public static void main(String[] argv) {
    DefaultTableModel model = new DefaultTableModel() {
      public Class getColumnClass(int columnIndex) {
        Object o = getValueAt(0, columnIndex);
        if (o == null) {
          return Object.class;
        } else {
          return o.getClass();
        }
      }
    };
    JTable table = new JTable(model);
    model.addColumn("Boolean", new Object[] { Boolean.TRUE });
    model.addColumn("Date", new Object[] { new Date() });
    model.addColumn("Double", new Object[] { new Double(Math.PI) });
    model.addColumn("Float", new Object[] { new Float(1.2) });
    model.addColumn("Icon", new Object[] { new ImageIcon("icon.gif") });
    model.addColumn("Number", new Object[] { new Integer(1) });
    model.addColumn("Object", new Object[] { "object" });
    
    JFrame f = new JFrame();
    f.setSize(300,300);
    f.add(new JScrollPane(table));
    f.setVisible(true);
  }
}