Java/Swing JFC/Table

Материал из Java эксперт
Версия от 18:01, 31 мая 2010; (обсуждение)
(разн.) ← Предыдущая | Текущая версия (разн.) | Следующая → (разн.)
Перейти к: навигация, поиск

Содержание

Add 5 spaces to the left and right sides of a cell.

import java.awt.Dimension;
import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    int gapWidth = 10;
    int gapHeight = 4;
    table.setIntercellSpacing(new Dimension(gapWidth, gapHeight));
  }
}





Add columns to a table through DefaultTableModel

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    DefaultTableModel model = new DefaultTableModel();
    JTable table = new JTable(model);
    model.addColumn("Col1");
    model.addColumn("Col2");
    JFrame f = new JFrame();
    f.setSize(300, 300);
    f.add(new JScrollPane(table));
    f.setVisible(true);
  }
}





Allowing the User to Resize a Column in a JTable Component

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 3;
    int cols = 3;
    JTable table = new JTable(rows, cols);
    table.getTableHeader().setResizingAllowed(false);
  }
}





Allow multiple selections of rows, visible columns, or cell blocks (default)

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
  }
}





Allow only single a selection

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  }
}





Allow selection to span one contiguous set of rows, visible columns, or block of cells

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
  }
}





Appending a Row to a JTable Component

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    DefaultTableModel model = new DefaultTableModel();
    JTable table = new JTable(model);
    model.addColumn("Col1");
    model.addColumn("Col2");
    model.addRow(new Object[] { "v1", "v2" });
    model.addRow(new Object[] { "v1" });
    model.addRow(new Object[] { "v1", "v2", "v3" });
    JFrame f = new JFrame();
    f.setSize(300, 300);
    f.add(new JScrollPane(table));
    f.setVisible(true);
  }
}





A table with the ability to play with row and column selections

 
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly 
*/
// SelectionExample.java
//A simple multiplication table with the ability to play with row and column
//selections. You can alter the cell, column and row selection properties
//of the table at runtime.
//
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JCheckBox;
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.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
public class SelectionExample extends JFrame {
  public SelectionExample() {
    super("Selection Model Test");
    setSize(450, 350);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    TableModel tm = new AbstractTableModel() {
      // We"ll create a simple multiplication table to serve as a
      // noneditable
      // table with several rows and columns
      public int getRowCount() {
        return 10;
      }
      public int getColumnCount() {
        return 10;
      }
      public Object getValueAt(int r, int c) {
        return "" + (r + 1) * (c + 1);
      }
    };
    final JTable jt = new JTable(tm);
    JScrollPane jsp = new JScrollPane(jt);
    getContentPane().add(jsp, BorderLayout.CENTER);
    // Now set up our selection controls
    JPanel controlPanel, buttonPanel, columnPanel, rowPanel;
    buttonPanel = new JPanel();
    final JCheckBox cellBox, columnBox, rowBox;
    cellBox = new JCheckBox("Cells", jt.getCellSelectionEnabled());
    columnBox = new JCheckBox("Columns", jt.getColumnSelectionAllowed());
    rowBox = new JCheckBox("Rows", jt.getRowSelectionAllowed());
    cellBox.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        jt.setCellSelectionEnabled(cellBox.isSelected());
        columnBox.setSelected(jt.getColumnSelectionAllowed());
        rowBox.setSelected(jt.getRowSelectionAllowed());
      }
    });
    columnBox.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        jt.setColumnSelectionAllowed(columnBox.isSelected());
        cellBox.setSelected(jt.getCellSelectionEnabled());
      }
    });
    rowBox.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent ae) {
        jt.setRowSelectionAllowed(rowBox.isSelected());
        cellBox.setSelected(jt.getCellSelectionEnabled());
      }
    });
    buttonPanel.add(new JLabel("Selections allowed:"));
    buttonPanel.add(cellBox);
    buttonPanel.add(columnBox);
    buttonPanel.add(rowBox);
    columnPanel = new JPanel();
    ListSelectionModel csm = jt.getColumnModel().getSelectionModel();
    JLabel columnCounter = new JLabel("(Selected Column Indices Go Here)");
    csm.addListSelectionListener(new SelectionDebugger(columnCounter, csm));
    columnPanel.add(new JLabel("Selected columns:"));
    columnPanel.add(columnCounter);
    rowPanel = new JPanel();
    ListSelectionModel rsm = jt.getSelectionModel();
    JLabel rowCounter = new JLabel("(Selected Row Indices Go Here)");
    rsm.addListSelectionListener(new SelectionDebugger(rowCounter, rsm));
    rowPanel.add(new JLabel("Selected rows:"));
    rowPanel.add(rowCounter);
    controlPanel = new JPanel(new GridLayout(0, 1));
    controlPanel.add(buttonPanel);
    controlPanel.add(columnPanel);
    controlPanel.add(rowPanel);
    getContentPane().add(controlPanel, BorderLayout.SOUTH);
  }
  public static void main(String args[]) {
    SelectionExample se = new SelectionExample();
    se.setVisible(true);
  }
  public class SelectionDebugger implements ListSelectionListener {
    JLabel debugger;
    ListSelectionModel model;
    public SelectionDebugger(JLabel target, ListSelectionModel lsm) {
      debugger = target;
      model = lsm;
    }
    public void valueChanged(ListSelectionEvent lse) {
      if (!lse.getValueIsAdjusting()) {
        // skip all the intermediate events . . .
        StringBuffer buf = new StringBuffer();
        int[] selection = getSelectedIndices(model
            .getMinSelectionIndex(), model.getMaxSelectionIndex());
        if (selection.length == 0) {
          buf.append("none");
        } else {
          for (int i = 0; i < selection.length - 1; i++) {
            buf.append(selection[i]);
            buf.append(", ");
          }
          buf.append(selection[selection.length - 1]);
        }
        debugger.setText(buf.toString());
      }
    }
    // This method returns an array of selected indices. It"s guaranteed to
    // return a nonnull value.
    protected int[] getSelectedIndices(int start, int stop) {
      if ((start == -1) || (stop == -1)) {
        // no selection, so return an empty array
        return new int[0];
      }
      int guesses[] = new int[stop - start + 1];
      int index = 0;
      // manually walk through these . . .
      for (int i = start; i <= stop; i++) {
        if (model.isSelectedIndex(i)) {
          guesses[index++] = i;
        }
      }
      // ok, pare down the guess array to the real thing
      int realthing[] = new int[index];
      System.arraycopy(guesses, 0, realthing, 0, index);
      return realthing;
    }
  }
}





Build a table from list data and column names

import java.util.Arrays;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) {
    Vector rowData = new Vector();
    for (int i = 0; i < 1; i++) {
      Vector colData = new Vector(Arrays.asList("qq"));
      rowData.add(colData);
    }
    
    String[] columnNames = {"a"};
    
    Vector columnNamesV = new Vector(Arrays.asList(columnNames));
    JTable table = new JTable(rowData, columnNamesV);
    JFrame f = new JFrame();
    f.setSize(300, 300);
    f.add(new JScrollPane(table));
    f.setVisible(true);
  }
}





Change a cell in the 2nd visible column

  
import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 3;
    int cols = 3;
    JTable table = new JTable(rows, cols);
    table.setValueAt("New Value", 0, 0);
  }
}





Change a cell in the 3rd column in the model

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 3;
    int cols = 3;
    JTable table = new JTable(rows, cols);
    table.getModel().setValueAt("New Value", 0, 0);
  }
}





Changing the Name of a Column in a JTable Component

import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    DefaultTableModel model = new DefaultTableModel();
    JTable table = new JTable(model);
    model.addColumn("Col1");
    model.addColumn("Col2");
    table.getColumnModel().getColumn(0).setHeaderValue("New Name");
    table.getTableHeader().resizeAndRepaint();
  }
}





Check each cell in the min and max ranges of selected cells

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    if (table.getCellSelectionEnabled()) {
      // In the other modes, the set of selected cells can be retrieved using
      table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
      table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
      // Get the min and max ranges of selected cells
      int rowIndexStart = table.getSelectedRow();
      int rowIndexEnd = table.getSelectionModel().getMaxSelectionIndex();
      int colIndexStart = table.getSelectedColumn();
      int colIndexEnd = table.getColumnModel().getSelectionModel().getMaxSelectionIndex();
      // Check each cell in the range
      for (int r = rowIndexStart; r <= rowIndexEnd; r++) {
        for (int c = colIndexStart; c <= colIndexEnd; c++) {
          if (table.isCellSelected(r, c)) {
            System.out.println("cell is selected"); 
          }
        }
      }
    }
  }
}





Column selection is enabled, get the indices of the selected columns

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    if (table.getColumnSelectionAllowed() && !table.getRowSelectionAllowed()) {
      
      int[] vColIndices = table.getSelectedColumns();
    }
  }
}





Create a table with two dimensional array

 
import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
public class TableSample {
  public static void main(String args[]) {
    JFrame f = new JFrame("JTable Sample");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Container content = f.getContentPane();
    Object rows[][] = { { "AMZN", "Amazon", "67 9/16" },
        { "AOL", "America Online", "68 3/4" },
        { "BOUT", "About.ru", "56 3/8" },
        { "CDNW", "CDnow", "4 7/16" },
        { "DCLK", "DoubleClick", "87 3/16" },
        { "EBAY", "eBay", "180 7/8" },
        { "EWBX", "EarthWeb", "18 1/4" },
        { "MKTW", "MarketWatch", "29" },
        { "TGLO", "Theglobe.ru", "4 15/16" },
        { "YHOO", "Yahoo!", "151 1/8" } };
    Object columns[] = { "Symbol", "Name", "Price" };
    JTable table = new JTable(rows, columns);
    JScrollPane scrollPane = new JScrollPane(table);
    content.add(scrollPane, BorderLayout.CENTER);
    f.setSize(300, 200);
    f.setVisible(true);
  }
}





Creates tables that allow rows and columns to be added or deleted

import java.util.Arrays;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    JFrame f = new JFrame();
    f.setSize(300, 300);
    f.add(new JScrollPane(table));
    f.setVisible(true);
  }
}





Create table with Unicode data

 
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
public class SimpleTableSample {
  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" };
    String title = (args.length == 0 ? "JTable Sample" : args[0]);
    JFrame frame = new JFrame(title);
    JTable table = new JTable(rows, headers);
    JScrollPane scrollPane = new JScrollPane(table);
    frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}





Creating a Custom Column Header 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.setHeaderRenderer(new MyTableHeaderRenderer());
  }
}
class MyTableHeaderRenderer 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 JTable Component

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    Object[][] cellData = { { "1-1", "1-2" }, { "2-1", "2-2" } };
    String[] columnNames = { "col1", "col2" };
    JTable table = new JTable(cellData, columnNames);
    
    JFrame f = new JFrame();
    f.setSize(300,300);
    f.add(new JScrollPane(table));
    f.setVisible(true);
  }
}





Creating a JTable with rows of variable height

import java.awt.Color;
import java.awt.ruponent;
import javax.swing.BorderFactory;
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.TableCellRenderer;
public class Main {
  public static void main(String[] argv) {
    JFrame demoFrame = new JFrame("Variable Row Height Table Demo");
    StringTableModel imageTableModel = new StringTableModel();
    JTable imageTable = new JTable(imageTableModel);
    imageTable.getColumnModel().getColumn(0).setCellRenderer(new VariableRowHeightRenderer());
    demoFrame.getContentPane().add(new JScrollPane(imageTable));
    demoFrame.pack();
    demoFrame.setVisible(true);
  }
}
class VariableRowHeightRenderer extends JLabel implements TableCellRenderer {
  public VariableRowHeightRenderer() {
    super();
    setOpaque(true);
    setHorizontalAlignment(JLabel.CENTER);
  }
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    if (isSelected) {
      setBackground(UIManager.getColor("Table.selectionBackground"));
    }
    if (hasFocus) {
      setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
      if (table.isCellEditable(row, column)) {
        super.setForeground(UIManager.getColor("Table.focusCellForeground"));
        super.setBackground(UIManager.getColor("Table.focusCellBackground"));
      }
    } else {
      setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
    }
    setText((String) (value));
    table.setRowHeight(row, getPreferredSize().height + row * 10);
    return this;
  }
}
class StringTableModel extends AbstractTableModel {
  public static final int IMG_COL = 0;
  public String[] m_colNames = { "Variable Dimension" };
  public Class[] m_colTypes = { String.class };
  public StringTableModel() {
    super();
  }
  public int getColumnCount() {
    return m_colNames.length;
  }
  public int getRowCount() {
    return 3;
  }
  public String getColumnName(int col) {
    return "" + col;
  }
  public Object getValueAt(int row, int col) {
    return "aa";
  }
}





Creating a Scrollable JTable Component

import javax.swing.JScrollPane;
import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) {
    // Create a table with 10 rows and 5 columns
    JTable table = new JTable(10, 5);
    // Make the table vertically scrollable
    JScrollPane scrollPane = new JScrollPane(table);
  }
}





Creating image out of a JTable

 
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;
public class Main {
  public static BufferedImage createImage(JTable table) {
    JTableHeader tableHeaderComp = table.getTableHeader();
    int totalWidth = tableHeaderComp.getWidth() + table.getWidth();
    int totalHeight = tableHeaderComp.getHeight() + table.getHeight();
    BufferedImage tableImage = new BufferedImage(totalWidth, totalHeight,
        BufferedImage.TYPE_INT_RGB);
    Graphics2D g2D = (Graphics2D) tableImage.getGraphics();
    tableHeaderComp.paint(g2D);
    g2D.translate(0, tableHeaderComp.getHeight());
    table.paint(g2D);
    return tableImage;
  }
}





Deselect a cell: cell (3,2), All cells in the row and column containing (3,2) are deselected.

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(true);
    int row = 3;
    int col = 2;
    boolean toggle = true;
    boolean extend = false;
    table.changeSelection(row, col, toggle, extend);
  }
}





Deselect all cells

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(false);
    table.clearSelection();
  }
}





Deselect a range of columns - columns 0 to 1

    
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(false);
    table.removeColumnSelectionInterval(0, 1);
  }
}





Deselect a range of rows - rows 0 to 1

  
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(false);
    table.setColumnSelectionAllowed(false);
    table.setRowSelectionAllowed(true);
    table.removeRowSelectionInterval(0, 1);
  }
}





Determining If a Cell Is Visible in a JTable Component

import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.JTable;
import javax.swing.JViewport;
public class Main {
  public static void main(String[] argv) {
    JTable table = new JTable(10, 5);
    int rowIndex = 1;
    int vColIndex = 2;
    isCellVisible(table, rowIndex, vColIndex);
  }
  public static boolean isCellVisible(JTable table, int rowIndex, int vColIndex) {
    if (!(table.getParent() instanceof JViewport)) {
      return false;
    }
    JViewport viewport = (JViewport) table.getParent();
    Rectangle rect = table.getCellRect(rowIndex, vColIndex, true);
    Point pt = viewport.getViewPosition();
    rect.setLocation(rect.x - pt.x, rect.y - pt.y);
    return new Rectangle(viewport.getExtentSize()).contains(rect);
  }
}





Disable auto resizing to make the table horizontal scrollable

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) {
    // Create a table with 10 rows and 5 columns
    JTable table = new JTable(10, 5);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
  }
}





Disabling Selections in a JTable Component

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    table.setFocusable(false);
    table.setCellSelectionEnabled(false);
  }
}





Disabling User Edits in a JTable

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table1 = new JTable() {
      public boolean isCellEditable(int rowIndex, int vColIndex) {
        return false;
      }
    };
  }
}





Disabling User Edits in a JTable with DefaultTableModel

import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    TableModel model = new DefaultTableModel() {
      public boolean isCellEditable(int rowIndex, int mColIndex) {
        return false;
      }
    };
    JTable table2 = new JTable(model);
  }
}





Discard any changes made by the user and stops the editing process

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(true);
    int row = 1;
    int col = 3;
    boolean success = table.editCellAt(row, col);
    if (success) {
      boolean toggle = false;
      boolean extend = false;
      table.changeSelection(row, col, toggle, extend);
    }
    if (table.getCellEditor() != null) {
      table.getCellEditor().cancelCellEditing();
    }
  }
}





Displaying an Icon in a Column Head of a JTable Component

import java.awt.ruponent;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
public class Main {
  public static void main(String[] argv) throws Exception {
    DefaultTableModel model = new DefaultTableModel();
    JTable table = new JTable(model);
    model.addColumn("Col1");
    model.addColumn("Col2");
    table.getTableHeader().getColumnModel().getColumn(1).setHeaderRenderer(new IconHeaderRenderer());
    table.getColumnModel().getColumn(1).setHeaderValue(new TextAndIcon("Col2", new ImageIcon("icon.gif")));
  }
}
class TextAndIcon {
  TextAndIcon(String text, Icon icon) {
    this.text = text;
    this.icon = icon;
  }
  String text;
  Icon icon;
}
class IconHeaderRenderer extends DefaultTableCellRenderer {
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    if (table != null) {
      JTableHeader header = table.getTableHeader();
      if (header != null) {
        setForeground(header.getForeground());
        setBackground(header.getBackground());
        setFont(header.getFont());
      }
    }
    if (value instanceof TextAndIcon) {
      setIcon(((TextAndIcon) value).icon);
      setText(((TextAndIcon) value).text);
    } else {
      setText((value == null) ? "" : value.toString());
      setIcon(null);
    }
    setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    setHorizontalAlignment(JLabel.CENTER);
    return this;
  }
}





Display ResultSet in Table (JTable)

 
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly 
*/
// DatabaseTest.java
//Let"s try to make one of these databases work with a JTable for ouptut.
//
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.AbstractTableModel;
public class DatabaseTest extends JFrame {
  JTextField hostField;
  JTextField queryField;
  QueryTableModel qtm;
  public DatabaseTest() {
    super("Database Test Frame");
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(350, 200);
    qtm = new QueryTableModel();
    JTable table = new JTable(qtm);
    JScrollPane scrollpane = new JScrollPane(table);
    JPanel p1 = new JPanel();
    p1.setLayout(new GridLayout(3, 2));
    p1.add(new JLabel("Enter the Host URL: "));
    p1.add(hostField = new JTextField());
    p1.add(new JLabel("Enter your query: "));
    p1.add(queryField = new JTextField());
    p1.add(new JLabel("Click here to send: "));
    JButton jb = new JButton("Search");
    jb.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        qtm.setHostURL(hostField.getText().trim());
        qtm.setQuery(queryField.getText().trim());
      }
    });
    p1.add(jb);
    getContentPane().add(p1, BorderLayout.NORTH);
    getContentPane().add(scrollpane, BorderLayout.CENTER);
  }
  public static void main(String args[]) {
    DatabaseTest tt = new DatabaseTest();
    tt.setVisible(true);
  }
}
//QueryTableModel.java
//A basic implementation of the TableModel interface that fills out a Vector of
//String[] structures from a query"s result set.
//
class QueryTableModel extends AbstractTableModel {
  Vector cache; // will hold String[] objects . . .
  int colCount;
  String[] headers;
  Connection db;
  Statement statement;
  String currentURL;
  public QueryTableModel() {
    cache = new Vector();
    new gsl.sql.driv.Driver();
  }
  public String getColumnName(int i) {
    return headers[i];
  }
  public int getColumnCount() {
    return colCount;
  }
  public int getRowCount() {
    return cache.size();
  }
  public Object getValueAt(int row, int col) {
    return ((String[]) cache.elementAt(row))[col];
  }
  public void setHostURL(String url) {
    if (url.equals(currentURL)) {
      // same database, we can leave the current connection open
      return;
    }
    // Oops . . . new connection required
    closeDB();
    initDB(url);
    currentURL = url;
  }
  // All the real work happens here; in a real application,
  // we"d probably perform the query in a separate thread.
  public void setQuery(String q) {
    cache = new Vector();
    try {
      // Execute the query and store the result set and its metadata
      ResultSet rs = statement.executeQuery(q);
      ResultSetMetaData meta = rs.getMetaData();
      colCount = meta.getColumnCount();
      // Now we must rebuild the headers array with the new column names
      headers = new String[colCount];
      for (int h = 1; h <= colCount; h++) {
        headers[h - 1] = meta.getColumnName(h);
      }
      // and file the cache with the records from our query. This would
      // not be
      // practical if we were expecting a few million records in response
      // to our
      // query, but we aren"t, so we can do this.
      while (rs.next()) {
        String[] record = new String[colCount];
        for (int i = 0; i < colCount; i++) {
          record[i] = rs.getString(i + 1);
        }
        cache.addElement(record);
      }
      fireTableChanged(null); // notify everyone that we have a new table.
    } catch (Exception e) {
      cache = new Vector(); // blank it out and keep going.
      e.printStackTrace();
    }
  }
  public void initDB(String url) {
    try {
      db = DriverManager.getConnection(url);
      statement = db.createStatement();
    } catch (Exception e) {
      System.out.println("Could not initialize the database.");
      e.printStackTrace();
    }
  }
  public void closeDB() {
    try {
      if (statement != null) {
        statement.close();
      }
      if (db != null) {
        db.close();
      }
    } catch (Exception e) {
      System.out.println("Could not close the current connection.");
      e.printStackTrace();
    }
  }
}





Don"t show any grid lines

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    table.setShowGrid(false);
  }
}





Enable cell selection in a JTable

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(true);
  }
}





Enable column selection in a JTable

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(false);
  }
}





Enable row selection (default) in a JTable

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    // Enable row selection (default)
    table.setColumnSelectionAllowed(false);
    table.setRowSelectionAllowed(true);
  }
}





Expense Table

 
/*
Swing, Second Edition
by Matthew Robinson, Pavel Vorobiev
*/
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import java.text.SimpleDateFormat;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class ExpenseReport extends JFrame 
{
  protected JTable m_table;
  protected ExpenseReportData m_data;
  protected JLabel m_title;
  public ExpenseReport() {
    super("Expense Report");
    setSize(570, 200);
    m_data = new ExpenseReportData(this);
    m_table = new JTable();
    m_table.setAutoCreateColumnsFromModel(false);
    m_table.setModel(m_data); 
    m_table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        
    for (int k = 0; k < ExpenseReportData.m_columns.length; k++) {
      TableCellRenderer renderer;
      if (k==ExpenseReportData.COL_APPROVED)
        renderer = new CheckCellRenderer();
      else {
        DefaultTableCellRenderer textRenderer = 
          new DefaultTableCellRenderer();
        textRenderer.setHorizontalAlignment(
          ExpenseReportData.m_columns[k].m_alignment);
        renderer = textRenderer;
      }
      TableCellEditor editor;
      if (k==ExpenseReportData.COL_CATEGORY)
        editor = new DefaultCellEditor(new JComboBox(
          ExpenseReportData.CATEGORIES));
      else if (k==ExpenseReportData.COL_APPROVED)
        editor = new DefaultCellEditor(new JCheckBox());
      else
        editor = new DefaultCellEditor(new JTextField());
      TableColumn column = new TableColumn(k, 
        ExpenseReportData.m_columns[k].m_width, 
          renderer, editor);
        m_table.addColumn(column);   
    }
    JTableHeader header = m_table.getTableHeader();
    header.setUpdateTableInRealTime(false);
    JScrollPane ps = new JScrollPane();
    ps.setSize(550, 150);
    ps.getViewport().add(m_table);
    getContentPane().add(ps, BorderLayout.CENTER);
    JPanel p = new JPanel();
    p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
    ImageIcon penny = new ImageIcon("penny.gif");
    m_title = new JLabel("Total: $", 
      penny, JButton.LEFT);
    m_title.setForeground(Color.black);
    m_title.setAlignmentY(0.5f);
    p.add(m_title);
    p.add(Box.createHorizontalGlue());
    JButton bt = new JButton("Insert before");
    bt.setMnemonic("b");
    bt.setAlignmentY(0.5f);
    ActionListener lst = new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
        int row = m_table.getSelectedRow();
        m_data.insert(row);
        m_table.tableChanged(new TableModelEvent(
          m_data, row, row, TableModelEvent.ALL_COLUMNS, 
          TableModelEvent.INSERT)); 
        m_table.repaint();
      }
    };
    bt.addActionListener(lst);
    p.add(bt);
    bt = new JButton("Insert after");
    bt.setMnemonic("a");
    bt.setAlignmentY(0.5f);
    lst = new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
        int row = m_table.getSelectedRow();
        m_data.insert(row+1);
        m_table.tableChanged(new TableModelEvent(
          m_data, row+1, row+1, TableModelEvent.ALL_COLUMNS,
          TableModelEvent.INSERT)); 
        m_table.repaint();
      }
    };
    bt.addActionListener(lst);
    p.add(bt);
    bt = new JButton("Delete row");
    bt.setMnemonic("d");
    bt.setAlignmentY(0.5f);
    lst = new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
        int row = m_table.getSelectedRow();
        if (m_data.delete(row)) {
          m_table.tableChanged(new TableModelEvent(
            m_data, row, row, TableModelEvent.ALL_COLUMNS,
            TableModelEvent.INSERT)); 
          m_table.repaint();
          calcTotal();
        }
      }
    };
    bt.addActionListener(lst);
    p.add(bt);
      
    getContentPane().add(p, BorderLayout.SOUTH);
    calcTotal();
    WindowListener wndCloser = new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    };
    addWindowListener(wndCloser);
    
    setVisible(true);
  }
  public void calcTotal() {
    double total = 0;
    for (int k=0; k<m_data.getRowCount(); k++) {
      Double amount = (Double)m_data.getValueAt(k, 
        ExpenseReportData.COL_AMOUNT);
      total += amount.doubleValue();
    }
    m_title.setText("Total: $"+total);
  }
  public static void main(String argv[]) {
    new ExpenseReport();
  }
}
class CheckCellRenderer extends JCheckBox implements TableCellRenderer
{
  protected static Border m_noFocusBorder;
  public CheckCellRenderer() {
    super();
    m_noFocusBorder = new EmptyBorder(1, 2, 1, 2);
    setOpaque(true);
    setBorder(m_noFocusBorder);
  }
  public Component getTableCellRendererComponent(JTable table,
   Object value, boolean isSelected, boolean hasFocus, 
   int row, int column) 
  {
    if (value instanceof Boolean) {
      Boolean b = (Boolean)value;
      setSelected(b.booleanValue());
    }
    setBackground(isSelected && !hasFocus ? 
      table.getSelectionBackground() : table.getBackground());
    setForeground(isSelected && !hasFocus ? 
      table.getSelectionForeground() : table.getForeground());
        
    setFont(table.getFont());
    setBorder(hasFocus ? UIManager.getBorder(
      "Table.focusCellHighlightBorder") : m_noFocusBorder);
    return this;
  }
}
class ExpenseData
{
  public Date    m_date;
  public Double  m_amount;
  public Integer m_category;
  public Boolean m_approved;
  public String  m_description;
  public ExpenseData() {
    m_date = new Date();
    m_amount = new Double(0);
    m_category = new Integer(1);
    m_approved = new Boolean(false);
    m_description = "";
  }
  public ExpenseData(Date date, double amount, int category, 
   boolean approved, String description) 
  {
    m_date = date;
    m_amount = new Double(amount);
    m_category = new Integer(category);
    m_approved = new Boolean(approved);
    m_description = description;
  }
}
class ColumnData
{
  public String  m_title;
  int m_width;
  int m_alignment;
  public ColumnData(String title, int width, int alignment) {
    m_title = title;
    m_width = width;
    m_alignment = alignment;
  }
}
class ExpenseReportData extends AbstractTableModel 
{
  public static final ColumnData m_columns[] = {
    new ColumnData( "Date", 80, JLabel.LEFT ),
    new ColumnData( "Amount", 80, JLabel.RIGHT ),
    new ColumnData( "Category", 130, JLabel.LEFT ),
    new ColumnData( "Approved", 80, JLabel.LEFT ),
    new ColumnData( "Description", 180, JLabel.LEFT )
  };
  public static final int COL_DATE = 0;
  public static final int COL_AMOUNT = 1;
  public static final int COL_CATEGORY = 2;
  public static final int COL_APPROVED = 3;
  public static final int COL_DESCR = 4;
  public static final String[] CATEGORIES = {
    "Fares", "Logging", "Business meals", "Others"
  };
  protected ExpenseReport m_parent;
  protected SimpleDateFormat m_frm;
  protected Vector m_vector;
  public ExpenseReportData(ExpenseReport parent) {
    m_parent = parent;
    m_frm = new SimpleDateFormat("MM/dd/yy");
    m_vector = new Vector();
    setDefaultData();
  }
  public void setDefaultData() {
    m_vector.removeAllElements();
    try {
      m_vector.addElement(new ExpenseData(
      m_frm.parse("04/06/99"), 200, 0, true, 
        "Airline tickets"));
      m_vector.addElement(new ExpenseData(
        m_frm.parse("04/06/99"), 50,  2, false, 
        "Lunch with client"));
      m_vector.addElement(new ExpenseData(
        m_frm.parse("04/06/99"), 120, 1, true, 
        "Hotel"));
    }
    catch (java.text.ParseException ex) {}
  }
  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 true;
  }
  public Object getValueAt(int nRow, int nCol) {
    if (nRow < 0 || nRow>=getRowCount())
      return "";
    ExpenseData row = (ExpenseData)m_vector.elementAt(nRow);
    switch (nCol) {
      case COL_DATE: return m_frm.format(row.m_date);
      case COL_AMOUNT: return row.m_amount;
      case COL_CATEGORY: return CATEGORIES[row.m_category.intValue()];
      case COL_APPROVED: return row.m_approved;
      case COL_DESCR: return row.m_description;
    }
    return "";
  }
  public void setValueAt(Object value, int nRow, int nCol) {
    if (nRow < 0 || nRow>=getRowCount())
      return;
    ExpenseData row = (ExpenseData)m_vector.elementAt(nRow);
    String svalue = value.toString();
    switch (nCol) {
      case COL_DATE: 
        Date  date = null;
        try { 
          date = m_frm.parse(svalue); 
        }
        catch (java.text.ParseException ex) { 
          date = null; 
        }
        if (date == null) {
          JOptionPane.showMessageDialog(null, 
            svalue+" is not a valid date",
            "Warning", JOptionPane.WARNING_MESSAGE);
          return;
        }
        row.m_date = date; 
        break;
      case COL_AMOUNT:
        try { 
          row.m_amount = new Double(svalue); 
        }
        catch (NumberFormatException e) { break; }
        m_parent.calcTotal();
        break;
      case COL_CATEGORY:
        for (int k=0; k<CATEGORIES.length; k++)
          if (svalue.equals(CATEGORIES[k])) {
            row.m_category = new Integer(k);
            break;
          }
        break;
      case COL_APPROVED:
        row.m_approved = (Boolean)value; 
        break;
      case COL_DESCR:
        row.m_description = svalue; 
        break;
    }
  }
  public void insert(int row) {
    if (row < 0)
      row = 0;
    if (row > m_vector.size())
      row = m_vector.size();
    m_vector.insertElementAt(new ExpenseData(), row);
  }
  public boolean delete(int row) {
    if (row < 0 || row >= m_vector.size())
      return false;
    m_vector.remove(row);
      return true;
  }
}





Extend the selection to include all cells (5,3)

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(true);
    int row = 5;
    int col = 3;
    boolean toggle = false;
    boolean extend = true;
    table.changeSelection(row, col, toggle, extend);
  }
}





Get default selection mode:MULTIPLE_INTERVAL_SELECTION

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    int selMode = table.getSelectionModel().getSelectionMode();
  }
}





Get selected row and selected index

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    if (table.getCellSelectionEnabled()) {
      table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
      int rowIndex = table.getSelectedRow();
      int colIndex = table.getSelectedColumn();
    }
  }
}





Get the min and max ranges of selected cells

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    if (table.getCellSelectionEnabled()) {
      table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
      table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
      int rowIndexStart = table.getSelectedRow();
      int rowIndexEnd = table.getSelectionModel().getMaxSelectionIndex();
      int colIndexStart = table.getSelectedColumn();
      int colIndexEnd = table.getColumnModel().getSelectionModel().getMaxSelectionIndex();
    }
  }
}





Getting the Anchor Cell in a JTable Component

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    int rowIndex = table.getSelectionModel().getAnchorSelectionIndex();
    int vColIndex = table.getColumnModel().getSelectionModel().getAnchorSelectionIndex();
  }
}





Getting the Gap Size Between Cells in a JTable Component

import java.awt.Dimension;
import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    Dimension d = table.getIntercellSpacing();
    // d.width == 1, d.height == 1
  }
}





Getting the Number of Rows and Columns in a JTable Component

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    Object[][] cellData = { { "1-1", "1-2" }, { "2-1", "2-2" } };
    String[] columnNames = { "col1", "col2" };
    JTable table = new JTable(cellData, columnNames);
    int rows = table.getRowCount();
    int cols = table.getColumnCount();
    System.out.println(rows);
    System.out.println(cols);
  }
}





Handle selection and model change events for a JTable.

import java.awt.Dimension;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
public class Main implements ListSelectionListener {
  String[] headings = { "Name", "Customer ID", "Order #", "Status" };
  Object[][] data = { { "A", new Integer(3), "0", new Date() },
      { "B", new Integer(6), "4", new Date() }, { "C", new Integer(9), "9", new Date() },
      { "D", new Integer(7), "1", new Date() }, { "E", new Integer(4), "1", new Date() },
      { "F", new Integer(8), "2", new Date() }, { "G", new Integer(6), "1", new Date() } };
  JTable jtabOrders = new JTable(data, headings);
  TableModel tm;
  Main() {
    JFrame jfrm = new JFrame("JTable Event Demo");
    jfrm.setSize(400, 200);
    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    jtabOrders.setPreferredScrollableViewportSize(new Dimension(420, 62));
    ListSelectionModel rowSelMod = jtabOrders.getSelectionModel();
    ListSelectionModel colSelMod = jtabOrders.getColumnModel().getSelectionModel();
    rowSelMod.addListSelectionListener(this);
    colSelMod.addListSelectionListener(this);
    tm = jtabOrders.getModel();
    tm.addTableModelListener(new TableModelListener() {
      public void tableChanged(TableModelEvent tme) {
        if (tme.getType() == TableModelEvent.UPDATE) {
          System.out.println("Cell " + tme.getFirstRow() + ", " + tme.getColumn() + " changed."
              + " The new value: " + tm.getValueAt(tme.getFirstRow(), tme.getColumn()));
        }
      }
    });
    jfrm.add(new JScrollPane(jtabOrders));
    jfrm.setVisible(true);
  }
  public void valueChanged(ListSelectionEvent le) {
    String str = "Selected Row(s): ";
    int[] rows = jtabOrders.getSelectedRows();
    for (int i = 0; i < rows.length; i++)
      str += rows[i] + " ";
    str += "Selected Column(s): ";
    int[] cols = jtabOrders.getSelectedColumns();
    for (int i = 0; i < cols.length; i++)
      str += cols[i] + " ";
    str += "Selected Cell: " + jtabOrders.getSelectedRow() + ", "
        + jtabOrders.getSelectedColumn();
    System.out.println(str);
  }
  public static void main(String args[]) {
    new Main();
  }
}





Implementing Variable-Height Column Headers in a JTable Component

import java.awt.ruponent;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
public class Main {
  public static void main(String[] argv) throws Exception {
    DefaultTableModel model = new DefaultTableModel();
    JTable table = new JTable(model);
    model.addColumn("Col1");
    model.addColumn("Icon Here");
    table.getColumnModel().getColumn(0).setHeaderValue(new ImageIcon("image.gif"));
    table.getColumnModel().getColumn(0).setHeaderRenderer(new IconHeaderRenderer());
  }
}
class IconHeaderRenderer extends DefaultTableCellRenderer {
  public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
      boolean hasFocus, int row, int column) {
    if (table != null) {
      JTableHeader header = table.getTableHeader();
      if (header != null) {
        setForeground(header.getForeground());
        setBackground(header.getBackground());
        setFont(header.getFont());
      }
    }
    if (value instanceof Icon) {
      setIcon((Icon) value);
      setText("");
    } else {
      setText((value == null) ? "" : value.toString());
      setIcon(null);
    }
    setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    setHorizontalAlignment(JLabel.CENTER);
    return this;
  }
}





Increase the row height

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    table.setRowHeight(table.getRowHeight() + 3);
  }
}





Insert a row to a table through DefaultTableModel

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    DefaultTableModel model = new DefaultTableModel();
    JTable table = new JTable(model);
    model.addColumn("Col1");
    model.addColumn("Col2");
    // Create the first row
    model.insertRow(0, new Object[] { "r1" });
    
    JFrame f = new JFrame();
    f.setSize(300, 300);
    f.add(new JScrollPane(table));
    f.setVisible(true);
  }
}





Insert a row to a table through DefaultTableModel at specified row

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    DefaultTableModel model = new DefaultTableModel();
    JTable table = new JTable(model);
    model.addColumn("Col1");
    model.addColumn("Col2");
    // Create the first row
    model.insertRow(0, new Object[] { "r1" });
    
    // Insert a row at position p
    int p = 1;
    model.insertRow(p, new Object[] { "r3" });
    
    JFrame f = new JFrame();
    f.setSize(300, 300);
    f.add(new JScrollPane(table));
    f.setVisible(true);
  }
}





JTable selection events

 
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
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.border.Border;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
public class TableIt {
  class MyTableCellRenderer extends JLabel implements TableCellRenderer {
    final Border blueBorder = BorderFactory.createLineBorder(Color.BLUE);
    MyTableCellRenderer() {
      setOpaque(true);
    }
    public Component getTableCellRendererComponent(JTable table,
        Object value, boolean isSelected, boolean hasFocus, int row,
        int col) {
      setBackground((Color) value);
      if (isSelected) {
        setBorder(blueBorder);
      } else {
        setBorder(BorderFactory.createEmptyBorder());
      }
      return this;
    }
  }
  class MyTableModel extends DefaultTableModel {
    Object data[][] = { { "1", Color.RED }, { "2", Color.ORANGE },
        { "3", Color.YELLOW }, { "4", Color.GREEN },
        { "5", Color.BLUE }, { "6", Color.MAGENTA },
        { "7", Color.CYAN }, { "8", Color.PINK },
        { "9", Color.BLACK }, { "10", Color.GRAY } };
    MyTableModel() {
      setColumnIdentifiers(new String[] { "ID", "Name", "Color" });
      for (int i = 0, n = data.length; i < n; i++)
        addRow(new Object[] { new Integer(i + 1), data[i][0],
            data[i][1] });
    }
    public boolean isCellEditable(int row, int column) {
      return (column != 0);
    }
  }
  public TableIt() {
    JFrame f = new JFrame();
    TableModel tm = new MyTableModel();
    final JTable table = new JTable(tm);
    TableColumnModel tcm = table.getColumnModel();
    TableColumn column = tcm.getColumn(tcm.getColumnCount() - 1);
    TableCellRenderer renderer = new MyTableCellRenderer();
    column.setCellRenderer(renderer);
    JButton selectionType = new JButton("Next Type");
    selectionType.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        boolean rowSet = table.getRowSelectionAllowed();
        boolean colSet = table.getColumnSelectionAllowed();
        boolean cellSet = table.getCellSelectionEnabled();
        boolean setRow = !rowSet;
        boolean setCol = rowSet ^ colSet;
        boolean setCell = rowSet & colSet;
        table.setCellSelectionEnabled(setCell);
        table.setColumnSelectionAllowed(setCol);
        table.setRowSelectionAllowed(setRow);
        System.out.println("Row Selection Allowed? " + setRow);
        System.out.println("Column Selection Allowed? " + setCol);
        System.out.println("Cell Selection Enabled? " + setCell);
        table.repaint();
      }
    });
    JButton selectionMode = new JButton("Next Mode");
    selectionMode.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        ListSelectionModel lsm = table.getSelectionModel();
        int mode = lsm.getSelectionMode();
        int nextMode;
        String nextModeString;
        if (mode == ListSelectionModel.SINGLE_SELECTION) {
          nextMode = ListSelectionModel.SINGLE_INTERVAL_SELECTION;
          nextModeString = "Single Interval Selection";
        } else if (mode == ListSelectionModel.SINGLE_INTERVAL_SELECTION) {
          nextMode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION;
          nextModeString = "Multiple Interval Selection";
        } else {
          nextMode = ListSelectionModel.SINGLE_SELECTION;
          nextModeString = "Single Selection";
        }
        lsm.setSelectionMode(nextMode);
        System.out.println("Selection Mode: " + nextModeString);
        table.repaint();
      }
    });
    JPanel jp = new JPanel();
    jp.add(selectionType);
    jp.add(selectionMode);
    JScrollPane jsp = new JScrollPane(table);
    Container c = f.getContentPane();
    c.add(jsp, BorderLayout.CENTER);
    c.add(jp, BorderLayout.SOUTH);
    f.setSize(300, 250);
    f.show();
  }
  public static void main(String args[]) {
    new TableIt();
  }
}





JTable.setCellSelectionEnabled(boolean b);

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  String[] headings = { "Name", "Customer ID","Order #", "Status" };
  Object[][] data = {
    { "A", new Integer(3), "0", new Date() },
    { "B", new Integer(6), "4", new Date() },
    { "C", new Integer(9), "9", new Date() },
    { "D", new Integer(7), "1", new Date() },
    { "E", new Integer(4), "1", new Date() },
    { "F", new Integer(8), "2", new Date() },
    { "G", new Integer(6), "1", new Date() }
  };
  JTable jtabOrders = new JTable(data, headings);
  Main() {
    JFrame jfrm = new JFrame("JTable Demo");
    jfrm.setLayout(new FlowLayout());
    jfrm.setSize(460, 180);
    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JScrollPane jscrlp = new JScrollPane(jtabOrders);
    jtabOrders.setPreferredScrollableViewportSize(new Dimension(420, 60));
    jtabOrders.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    jtabOrders.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    jfrm.setVisible(true);
  
    jtabOrders.setCellSelectionEnabled(true);
  }
  public static void main(String args[]) {
     new Main();
  }
}





JTable.setColumnSelectionAllowed(boolean b);

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  String[] headings = { "Name", "Customer ID",
                        "Order #", "Status" };
  Object[][] data = {
    { "A", new Integer(3), "0", new Date() },
    { "B", new Integer(6), "4", new Date() },
    { "C", new Integer(9), "9", new Date() },
    { "D", new Integer(7), "1", new Date() },
    { "E", new Integer(4), "1", new Date() },
    { "F", new Integer(8), "2", new Date() },
    { "G", new Integer(6), "1", new Date() }
  };
  JTable jtabOrders = new JTable(data, headings);
  Main() {
    JFrame jfrm = new JFrame("JTable Demo");
    jfrm.setLayout(new FlowLayout());
    jfrm.setSize(460, 180);
    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JScrollPane jscrlp = new JScrollPane(jtabOrders);
    jtabOrders.setPreferredScrollableViewportSize(
                new Dimension(420, 60));
    jtabOrders.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    jfrm.setVisible(true);
  
    jtabOrders.setColumnSelectionAllowed(false);
    jtabOrders.setRowSelectionAllowed(true);
  }
  public static void main(String args[]) {
     new Main();
  }
}





JTable.setRowSelectionAllowed(boolean b);

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  String[] headings = { "Name", "Customer ID","Order #", "Status" };
  Object[][] data = {
    { "A", new Integer(3), "0", new Date() },
    { "B", new Integer(6), "4", new Date() },
    { "C", new Integer(9), "9", new Date() },
    { "D", new Integer(7), "1", new Date() },
    { "E", new Integer(4), "1", new Date() },
    { "F", new Integer(8), "2", new Date() },
    { "G", new Integer(6), "1", new Date() }
  };
  JTable jtabOrders = new JTable(data, headings);
  Main() {
    JFrame jfrm = new JFrame("JTable Demo");
    jfrm.setLayout(new FlowLayout());
    jfrm.setSize(460, 180);
    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JScrollPane jscrlp = new JScrollPane(jtabOrders);
    jtabOrders.setPreferredScrollableViewportSize(
                new Dimension(420, 60));
    jtabOrders.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    jfrm.setVisible(true);
  
    jtabOrders.setColumnSelectionAllowed(false);
    jtabOrders.setRowSelectionAllowed(true);
  }
  public static void main(String args[]) {
     new Main();
  }
}





JTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  String[] headings = { "Name", "Customer ID", "Order #", "Status" };
  Object[][] data = {
    { "A", new Integer(3), "0", new Date() },
    { "B", new Integer(6), "4", new Date() },
    { "C", new Integer(9), "9", new Date() },
    { "D", new Integer(7), "1", new Date() },
    { "E", new Integer(4), "1", new Date() },
    { "F", new Integer(8), "2", new Date() },
    { "G", new Integer(6), "1", new Date() }
  };
  JTable jtabOrders = new JTable(data, headings);
  Main() {
    JFrame jfrm = new JFrame("JTable Demo");
    jfrm.setLayout(new FlowLayout());
    jfrm.setSize(460, 180);
    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JScrollPane jscrlp = new JScrollPane(jtabOrders);
    jtabOrders.setPreferredScrollableViewportSize(new Dimension(420, 60));
    jtabOrders.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    jfrm.setVisible(true);
  
    jtabOrders.setColumnSelectionAllowed(false);
    jtabOrders.setRowSelectionAllowed(true);
  }
  public static void main(String args[]) {
     new Main();
  }
}





JTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  String[] headings = { "Name", "Customer ID","Order #", "Status" };
  Object[][] data = {
    { "A", new Integer(3), "0", new Date() },
    { "B", new Integer(6), "4", new Date() },
    { "C", new Integer(9), "9", new Date() },
    { "D", new Integer(7), "1", new Date() },
    { "E", new Integer(4), "1", new Date() },
    { "F", new Integer(8), "2", new Date() },
    { "G", new Integer(6), "1", new Date() }
  };
  JTable jtabOrders = new JTable(data, headings);
  Main() {
    JFrame jfrm = new JFrame("JTable Demo");
    jfrm.setLayout(new FlowLayout());
    jfrm.setSize(460, 180);
    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JScrollPane jscrlp = new JScrollPane(jtabOrders);
    jtabOrders.setPreferredScrollableViewportSize(new Dimension(420, 60));
    jtabOrders.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    jfrm.setVisible(true);
  
    jtabOrders.setColumnSelectionAllowed(false);
    jtabOrders.setRowSelectionAllowed(true);
  }
  public static void main(String args[]) {
     new Main();
  }
}





JTable sorter:click the table header to sort a column and a table

 
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 TableSortDemo extends JFrame{
  protected JTable table = new JTable();
  protected MyTableModel tableModel;
  protected JLabel titleLabel = new JLabel("Click table header to sort the column.");
  public TableSortDemo() {
    super();
    setSize(600, 300);
    tableModel = new MyTableModel();
    getContentPane().add(titleLabel, BorderLayout.NORTH);
    table.setModel(tableModel);
    JTableHeader header = table.getTableHeader();
    header.setUpdateTableInRealTime(true);
    header.addMouseListener(tableModel.new ColumnListener(table));
    header.setReorderingAllowed(true);
    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 TableSortDemo();
  }
}
class MyTableModel extends AbstractTableModel {
  protected int sortCol = 0;
  protected boolean isSortAsc = true;
  protected int m_result = 0;
  protected int columnsCount = 1;
  Vector vector = new Vector();
  public MyTableModel() {
    vector.removeAllElements();
    vector.addElement(new Integer(24976600));
    vector.addElement(new Integer(24));
    vector.addElement(new Integer(2497));
    vector.addElement(new Integer(249766));
    vector.addElement(new Integer(2497660));
    vector.addElement(new Integer(6600));
    vector.addElement(new Integer(76600));
    vector.addElement(new Integer(976600));
    vector.addElement(new Integer(4976600));
  }
  public int getRowCount() {
    return vector == null ? 0 : vector.size();
  }
  public int getColumnCount() {
    return columnsCount;
  }
  public String getColumnName(int column) {
    String str = "data";
    if (column == sortCol)
      str += isSortAsc ? " >>" : " <<";
    return str;
  }
  public boolean isCellEditable(int nRow, int nCol) {
    return false;
  }
  public Object getValueAt(int nRow, int nCol) {
    if (nRow < 0 || nRow >= getRowCount())
      return "";
    if(nCol>1){
      return "";
    }
    return vector.elementAt(nRow);
  }
  public String getTitle() {
    return "data ";
  }
  class ColumnListener extends MouseAdapter {
    protected JTable table;
    public ColumnListener(JTable t) {
      table = t;
    }
    public void mouseClicked(MouseEvent e) {
      TableColumnModel colModel = table.getColumnModel();
      int columnModelIndex = colModel.getColumnIndexAtX(e.getX());
      int modelIndex = colModel.getColumn(columnModelIndex)
          .getModelIndex();
      if (modelIndex < 0)
        return;
      if (sortCol == modelIndex)
        isSortAsc = !isSortAsc;
      else
        sortCol = modelIndex;
      for (int i = 0; i < columnsCount; i++) { 
        TableColumn column = colModel.getColumn(i);
        column.setHeaderValue(getColumnName(column.getModelIndex()));
      }
      table.getTableHeader().repaint();
      Collections.sort(vector,new MyComparator(isSortAsc));
      table.tableChanged(new TableModelEvent(MyTableModel.this));
      table.repaint();
    }
  }
}
class MyComparator implements Comparator {
  protected boolean isSortAsc;
  public MyComparator( boolean sortAsc) {
    isSortAsc = sortAsc;
  }
  public int compare(Object o1, Object o2) {
    if (!(o1 instanceof Integer) || !(o2 instanceof Integer))
      return 0;
    Integer s1 = (Integer) o1;
    Integer s2 = (Integer) o2;
    int result = 0;
    result = s1.rupareTo(s2);
    if (!isSortAsc)
      result = -result;
    return result;
  }
  public boolean equals(Object obj) {
    if (obj instanceof MyComparator) {
      MyComparator compObj = (MyComparator) obj;
      return compObj.isSortAsc == isSortAsc;
    }
    return false;
  }
}





JTable(Table) with JDBC and ResultSet

 
/*
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 java.sql.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class StocksTable5 extends JFrame 
{
  protected JTable m_table;
  protected StockTableData m_data;
  protected JLabel m_title;
  public StocksTable5() {
    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(true);
    header.addMouseListener(m_data.new ColumnListener(m_table));
    header.setReorderingAllowed(true);
    JScrollPane ps = new JScrollPane();
    ps.getViewport().add(m_table);
    getContentPane().add(ps, BorderLayout.CENTER);
    JMenuBar menuBar = createMenuBar();
      setJMenuBar(menuBar);
    WindowListener wndCloser = new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    };
    addWindowListener(wndCloser);
    setVisible(true);
  }
  protected JMenuBar createMenuBar() {
    JMenuBar menuBar = new JMenuBar();
        
    JMenu mFile = new JMenu("File");
    mFile.setMnemonic("f");
    JMenuItem mData = new JMenuItem("Retrieve Data...");
    mData.setMnemonic("r");
    ActionListener lstData = new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
        retrieveData(); 
      }
    };
    mData.addActionListener(lstData);
    mFile.add(mData);
    mFile.addSeparator();
    JMenuItem mExit = new JMenuItem("Exit");
    mExit.setMnemonic("x");
    ActionListener lstExit = new ActionListener() { 
      public void actionPerformed(ActionEvent e) {
        System.exit(0);
      }
    };
    mExit.addActionListener(lstExit);
    mFile.add(mExit);
    menuBar.add(mFile);
    return menuBar;
  }
  public void retrieveData() {
    SimpleDateFormat frm = new SimpleDateFormat("MM/dd/yyyy");
    String currentDate = frm.format(m_data.m_date);
    String result = (String)JOptionPane.showInputDialog(this, 
      "Please enter date in form mm/dd/yyyy:", "Input", 
      JOptionPane.INFORMATION_MESSAGE, null, null, 
      currentDate);
    if (result==null)
      return;
    java.util.Date date = null;
    try { 
      date = frm.parse(result); 
    }
    catch (java.text.ParseException ex) { 
      date = null; 
    }
        
    if (date == null) {
      JOptionPane.showMessageDialog(this, 
        result+" is not a valid date",
        "Warning", JOptionPane.WARNING_MESSAGE);
      return;
    }
    setCursor( Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR) );
    switch (m_data.retrieveData(date)) {
      case 0:    // Ok with data
        m_title.setText(m_data.getTitle());
        m_table.tableChanged(new TableModelEvent(m_data)); 
        m_table.repaint();
        break;
      case 1: // No data
        JOptionPane.showMessageDialog(this, 
          "No data found for "+result,
          "Warning", JOptionPane.WARNING_MESSAGE);
        break;
      case -1: // Error
        JOptionPane.showMessageDialog(this, 
          "Error retrieving data",
          "Warning", JOptionPane.WARNING_MESSAGE);
        break;
    }
    setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  }
  public static void main(String argv[]) {
    new StocksTable5();
  }
}
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 java.util.Date m_date;
  protected int m_sortCol = 0;
  protected boolean m_sortAsc = true;
  protected int m_result = 0;
  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));
    Collections.sort(m_vector, new 
      StockComparator(m_sortCol, m_sortAsc));
  }
  public int getRowCount() {
    return m_vector==null ? 0 : m_vector.size(); 
  }
  public int getColumnCount() { 
    return m_columns.length; 
  } 
  public String getColumnName(int column) {
    String str = m_columns[column].m_title;
    if (column==m_sortCol)
      str += m_sortAsc ? ">>" : "<<";
    return str;
  }
 
  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);
  }
  public int retrieveData(final java.util.Date date) {
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.setTime(date);
    int month = calendar.get(Calendar.MONTH)+1;
    int day = calendar.get(Calendar.DAY_OF_MONTH);
    int year = calendar.get(Calendar.YEAR);
    final String query = "SELECT data.symbol, symbols.name, "+
      "data.last, data.open, data.change, data.changeproc, "+
      "data.volume FROM DATA INNER JOIN SYMBOLS "+
      "ON DATA.symbol = SYMBOLS.symbol WHERE "+
      "month(data.date1)="+month+" AND day(data.date1)="+day+
      " AND year(data.date1)="+year;
    Thread runner = new Thread() {
      public void run() {
        try {
          // Load the JDBC-ODBC bridge driver
          Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
          Connection conn = DriverManager.getConnection(
            "jdbc:odbc:Market", "admin", "");
          Statement stmt = conn.createStatement();
          ResultSet results = stmt.executeQuery(query);
          boolean hasData = false;
          while (results.next()) {
            if (!hasData) {
              m_vector.removeAllElements();
              hasData = true;
            }
            String  symbol = results.getString(1);
            String  name = results.getString(2);
            double  last = results.getDouble(3);
            double  open = results.getDouble(4);
            double  change = results.getDouble(5);
            double  changePr = results.getDouble(6);
            long volume = results.getLong(7);
            m_vector.addElement(new StockData(symbol, name, last, 
              open, change, changePr, volume));
          }
          results.close();
          stmt.close();
          conn.close();
          if (!hasData)    // We"ve got nothing
            m_result = 1;
        }
        catch (Exception e) {
          e.printStackTrace();
          System.err.println("Load data error: "+e.toString());
          m_result = -1;
        }
        m_date = date;
        Collections.sort(m_vector, 
          new StockComparator(m_sortCol, m_sortAsc));
        m_result = 0;
      }
    };
    runner.start();
    return m_result;
  }
  class ColumnListener extends MouseAdapter
  {
    protected JTable m_table;
    public ColumnListener(JTable table) {
      m_table = table;
    }
    public void mouseClicked(MouseEvent e) {
      TableColumnModel colModel = m_table.getColumnModel();
      int columnModelIndex = colModel.getColumnIndexAtX(e.getX());
      int modelIndex = colModel.getColumn(columnModelIndex).getModelIndex();
      if (modelIndex < 0)
        return;
      if (m_sortCol==modelIndex)
        m_sortAsc = !m_sortAsc;
      else
        m_sortCol = modelIndex;
      for (int i=0; i < m_columns.length; i++) {
        TableColumn column = colModel.getColumn(i);
        column.setHeaderValue(getColumnName(column.getModelIndex()));    
      }
      m_table.getTableHeader().repaint();  
      Collections.sort(m_vector, new 
        StockComparator(modelIndex, m_sortAsc));
      m_table.tableChanged(
        new TableModelEvent(StockTableData.this)); 
      m_table.repaint();  
    }
  }
}
class StockComparator implements Comparator
{
  protected int     m_sortCol;
  protected boolean m_sortAsc;
  public StockComparator(int sortCol, boolean sortAsc) {
    m_sortCol = sortCol;
    m_sortAsc = sortAsc;
  }
  public int compare(Object o1, Object o2) {
    if(!(o1 instanceof StockData) || !(o2 instanceof StockData))
      return 0;
    StockData s1 = (StockData)o1;
    StockData s2 = (StockData)o2;
    int result = 0;
    double d1, d2;
    switch (m_sortCol) {
      case 0:    // symbol
        String str1 = (String)s1.m_symbol.m_data;
        String str2 = (String)s2.m_symbol.m_data;
        result = str1.rupareTo(str2);
        break;
      case 1:    // name
        result = s1.m_name.rupareTo(s2.m_name);
        break;
      case 2:    // last
        d1 = s1.m_last.doubleValue();
        d2 = s2.m_last.doubleValue();
        result = d1<d2 ? -1 : (d1>d2 ? 1 : 0);
        break;
      case 3:    // open
        d1 = s1.m_open.doubleValue();
        d2 = s2.m_open.doubleValue();
        result = d1<d2 ? -1 : (d1>d2 ? 1 : 0);
        break;
      case 4:    // change
        d1 = ((Fraction)s1.m_change.m_data).doubleValue();
        d2 = ((Fraction)s2.m_change.m_data).doubleValue();
        result = d1<d2 ? -1 : (d1>d2 ? 1 : 0);
        break;
      case 5:    // change %
        d1 = ((Double)s1.m_changePr.m_data).doubleValue();
        d2 = ((Double)s2.m_changePr.m_data).doubleValue();
        result = d1<d2 ? -1 : (d1>d2 ? 1 : 0);
        break;
      case 6:    // volume
        long l1 = s1.m_volume.longValue();
        long l2 = s2.m_volume.longValue();
        result = l1<l2 ? -1 : (l1>l2 ? 1 : 0);
        break;
    }
    if (!m_sortAsc)
      result = -result;
    return result;
  }
  public boolean equals(Object obj) {
    if (obj instanceof StockComparator) {
      StockComparator compObj = (StockComparator)obj;
      return (compObj.m_sortCol==m_sortCol) && 
        (compObj.m_sortAsc==m_sortAsc);
    }
    return false;
  }
}





JTree.getModel().addTreeModelListener(new TreeModelListener())

import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
public class Main {
  public static void main(String args[]) {
    JFrame f = new JFrame("JTree Demo");
    f.setSize(260, 240);
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
    DefaultMutableTreeNode aNode = new DefaultMutableTreeNode("A");
    root.add(aNode);
    DefaultMutableTreeNode bNode = new DefaultMutableTreeNode("B");
    aNode.add(bNode);
    DefaultMutableTreeNode cNode = new DefaultMutableTreeNode("C");
    aNode.add(cNode);
    cNode.add(new DefaultMutableTreeNode("D"));
    cNode.add(new DefaultMutableTreeNode("E"));
    DefaultMutableTreeNode fNode = new DefaultMutableTreeNode("F");
    root.add(fNode);
    DefaultMutableTreeNode gNode = new DefaultMutableTreeNode("G");
    fNode.add(gNode);
    fNode.add(new DefaultMutableTreeNode("H"));
    gNode.add(new DefaultMutableTreeNode("I"));
    JTree jtree = new JTree(root);
    jtree.setEditable(true);
    TreeSelectionModel tsm = jtree.getSelectionModel();
    tsm.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    jtree.addTreeExpansionListener(new TreeExpansionListener() {
      public void treeExpanded(TreeExpansionEvent tee) {
        TreePath tp = tee.getPath();
        System.out.println("Expansion: " + tp.getLastPathComponent());
      }
      public void treeCollapsed(TreeExpansionEvent tee) {
        TreePath tp = tee.getPath();
        System.out.println("Collapse: " + tp.getLastPathComponent());
      }
    });
    jtree.addTreeSelectionListener(new TreeSelectionListener() {
      public void valueChanged(TreeSelectionEvent tse) {
        TreePath tp = tse.getPath();
        System.out.println("Selection event: " + tp.getLastPathComponent());
      }
    });
    jtree.getModel().addTreeModelListener(new TreeModelListener() {
      public void treeNodesChanged(TreeModelEvent tme) {
        TreePath tp = tme.getTreePath();
        Object[] children = tme.getChildren();
        DefaultMutableTreeNode changedNode;
        if (children != null)
          changedNode = (DefaultMutableTreeNode) children[0];
        else
          changedNode = (DefaultMutableTreeNode) tp.getLastPathComponent();
        System.out.println("Model change path: " + tp + "New data: "
            + changedNode.getUserObject());
      }
      public void treeNodesInserted(TreeModelEvent tme) {
      }
      public void treeNodesRemoved(TreeModelEvent tme) {
      }
      public void treeStructureChanged(TreeModelEvent tme) {
      }
    });
    f.add(new JScrollPane(jtree));
    f.setVisible(true);
  }
}





Listening for Changes to the Rows and Columns of a JTable Component

import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    table.getModel().addTableModelListener(new MyTableModelListener(table));
  }
}
class MyTableModelListener implements TableModelListener {
  JTable table;
  MyTableModelListener(JTable table) {
    this.table = table;
  }
  public void tableChanged(TableModelEvent e) {
    int firstRow = e.getFirstRow();
    int lastRow = e.getLastRow();
    int index = e.getColumn();
    switch (e.getType()) {
    case TableModelEvent.INSERT:
      for (int i = firstRow; i <= lastRow; i++) {
        System.out.println(i);
      }
      break;
    case TableModelEvent.UPDATE:
      if (firstRow == TableModelEvent.HEADER_ROW) {
        if (index == TableModelEvent.ALL_COLUMNS) {
          System.out.println("A column was added");
        } else {
          System.out.println(index + "in header changed");
        }
      } else {
        for (int i = firstRow; i <= lastRow; i++) {
          if (index == TableModelEvent.ALL_COLUMNS) {
            System.out.println("All columns have changed");
          } else {
            System.out.println(index);
          }
        }
      }
      break;
    case TableModelEvent.DELETE:
      for (int i = firstRow; i <= lastRow; i++) {
        System.out.println(i);
      }
      break;
    }
  }
}





Listening for Clicks on a Column Header in a JTable Component

import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable(5, 5);
    JTableHeader header = table.getTableHeader();
    header.addMouseListener(new ColumnHeaderListener());
  }
}
class ColumnHeaderListener extends MouseAdapter {
  public void mouseClicked(MouseEvent evt) {
    JTable table = ((JTableHeader) evt.getSource()).getTable();
    TableColumnModel colModel = table.getColumnModel();
    int index = colModel.getColumnIndexAtX(evt.getX());
    if (index == -1) {
      return;
    }
    Rectangle headerRect = table.getTableHeader().getHeaderRect(index);
    if (index == 0) {
      headerRect.width -= 10;
    } else {
      headerRect.grow(-10, 0);
    }
    if (!headerRect.contains(evt.getX(), evt.getY())) {
      int vLeftColIndex = index;
      if (evt.getX() < headerRect.x) {
        vLeftColIndex--;
      }
    }
  }
}





Listening for Column-Related Changes in a JTable Component

import javax.swing.JTable;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    table.getColumnModel().addColumnModelListener(new MyTableColumnModelListener(table));
  }
}
class MyTableColumnModelListener implements TableColumnModelListener {
  JTable table;
  public MyTableColumnModelListener(JTable table) {
    this.table = table;
  }
  public void columnAdded(TableColumnModelEvent e) {
    int fromIndex = e.getFromIndex();
    int toIndex = e.getToIndex();
    System.out.println(fromIndex);
    System.out.println(toIndex);
  }
  public void columnRemoved(TableColumnModelEvent e) {
    int fromIndex = e.getFromIndex();
    int toIndex = e.getToIndex();
    System.out.println(fromIndex);
    System.out.println(toIndex);
  }
  public void columnMoved(TableColumnModelEvent e) {
    int fromIndex = e.getFromIndex();
    int toIndex = e.getToIndex();
    System.out.println(fromIndex);
    System.out.println(toIndex);
  }
  public void columnMarginChanged(ChangeEvent e) {
    System.out.println(e);
    
  }
  public void columnSelectionChanged(ListSelectionEvent e) {
    System.out.println(e);
  }
}





Listening for Selection Events in a JTable Component

import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    SelectionListener listener = new SelectionListener(table);
    table.getSelectionModel().addListSelectionListener(listener);
    table.getColumnModel().getSelectionModel().addListSelectionListener(listener);
  }
}
class SelectionListener implements ListSelectionListener {
  JTable table;
  SelectionListener(JTable table) {
    this.table = table;
  }
  public void valueChanged(ListSelectionEvent e) {
    if (e.getSource() == table.getSelectionModel() && table.getRowSelectionAllowed()) {
      int first = e.getFirstIndex();
      int last = e.getLastIndex();
    } else if (e.getSource() == table.getColumnModel().getSelectionModel()
        && table.getColumnSelectionAllowed()) {
      int first = e.getFirstIndex();
      int last = e.getLastIndex();
    }
    if (e.getValueIsAdjusting()) {
      System.out.println("The mouse button has not yet been released");
    }
  }
}





ListSelectionModel colSelMod = JTable.getColumnModel().getSelectionModel();

import java.awt.Dimension;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
public class Main implements ListSelectionListener {
  String[] headings = { "Name", "Customer ID", "Order #", "Status" };
  Object[][] data = { { "A", new Integer(3), "0", new Date() },
      { "B", new Integer(6), "4", new Date() }, { "C", new Integer(9), "9", new Date() },
      { "D", new Integer(7), "1", new Date() }, { "E", new Integer(4), "1", new Date() },
      { "F", new Integer(8), "2", new Date() }, { "G", new Integer(6), "1", new Date() } };
  JTable jtabOrders = new JTable(data, headings);
  TableModel tm;
  Main() {
    JFrame jfrm = new JFrame("JTable Event Demo");
    jfrm.setSize(400, 200);
    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    jtabOrders.setPreferredScrollableViewportSize(new Dimension(420, 62));
    ListSelectionModel rowSelMod = jtabOrders.getSelectionModel();
    ListSelectionModel colSelMod = jtabOrders.getColumnModel().getSelectionModel();
    rowSelMod.addListSelectionListener(this);
    colSelMod.addListSelectionListener(this);
    tm = jtabOrders.getModel();
    tm.addTableModelListener(new TableModelListener() {
      public void tableChanged(TableModelEvent tme) {
        if (tme.getType() == TableModelEvent.UPDATE) {
          System.out.println("Cell " + tme.getFirstRow() + ", " + tme.getColumn() + " changed."
              + " The new value: " + tm.getValueAt(tme.getFirstRow(), tme.getColumn()));
        }
      }
    });
    jfrm.add(new JScrollPane(jtabOrders));
    jfrm.setVisible(true);
  }
  public void valueChanged(ListSelectionEvent le) {
    String str = "Selected Row(s): ";
    int[] rows = jtabOrders.getSelectedRows();
    for (int i = 0; i < rows.length; i++)
      str += rows[i] + " ";
    str += "Selected Column(s): ";
    int[] cols = jtabOrders.getSelectedColumns();
    for (int i = 0; i < cols.length; i++)
      str += cols[i] + " ";
    str += "Selected Cell: " + jtabOrders.getSelectedRow() + ", "
        + jtabOrders.getSelectedColumn();
    System.out.println(str);
  }
  public static void main(String args[]) {
    new Main();
  }
}





ListSelectionModel rowSelMod = JTable.getSelectionModel();

import java.awt.Dimension;
import java.util.Date;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
public class Main implements ListSelectionListener {
  String[] headings = { "Name", "Customer ID", "Order #", "Status" };
  Object[][] data = { { "A", new Integer(3), "0", new Date() },
      { "B", new Integer(6), "4", new Date() }, { "C", new Integer(9), "9", new Date() },
      { "D", new Integer(7), "1", new Date() }, { "E", new Integer(4), "1", new Date() },
      { "F", new Integer(8), "2", new Date() }, { "G", new Integer(6), "1", new Date() } };
  JTable jtabOrders = new JTable(data, headings);
  TableModel tm;
  Main() {
    JFrame jfrm = new JFrame("JTable Event Demo");
    jfrm.setSize(400, 200);
    jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    jtabOrders.setPreferredScrollableViewportSize(new Dimension(420, 62));
    ListSelectionModel rowSelMod = jtabOrders.getSelectionModel();
    ListSelectionModel colSelMod = jtabOrders.getColumnModel().getSelectionModel();
    rowSelMod.addListSelectionListener(this);
    colSelMod.addListSelectionListener(this);
    tm = jtabOrders.getModel();
    tm.addTableModelListener(new TableModelListener() {
      public void tableChanged(TableModelEvent tme) {
        if (tme.getType() == TableModelEvent.UPDATE) {
          System.out.println("Cell " + tme.getFirstRow() + ", " + tme.getColumn() + " changed."
              + " The new value: " + tm.getValueAt(tme.getFirstRow(), tme.getColumn()));
        }
      }
    });
    jfrm.add(new JScrollPane(jtabOrders));
    jfrm.setVisible(true);
  }
  public void valueChanged(ListSelectionEvent le) {
    String str = "Selected Row(s): ";
    int[] rows = jtabOrders.getSelectedRows();
    for (int i = 0; i < rows.length; i++)
      str += rows[i] + " ";
    str += "Selected Column(s): ";
    int[] cols = jtabOrders.getSelectedColumns();
    for (int i = 0; i < cols.length; i++)
      str += cols[i] + " ";
    str += "Selected Cell: " + jtabOrders.getSelectedRow() + ", "
        + jtabOrders.getSelectedColumn();
    System.out.println(str);
  }
  public static void main(String args[]) {
    new Main();
  }
}





List UI Properties in a JTable and sortable

 
/*
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.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Date;
import java.util.Enumeration;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
public class ListProperties {
  static class CustomTableModel extends AbstractTableModel {
    Vector keys = new Vector();
    Vector values = new Vector();
    private static final String columnNames[] = { "Property String",
        "Value" };
    public int getColumnCount() {
      return columnNames.length;
    }
    public String getColumnName(int column) {
      return columnNames[column];
    }
    public int getRowCount() {
      return keys.size();
    }
    public Object getValueAt(int row, int column) {
      Object returnValue = null;
      if (column == 0) {
        returnValue = keys.elementAt(row);
      } else if (column == 1) {
        returnValue = values.elementAt(row);
      }
      return returnValue;
    }
    public synchronized void uiDefaultsUpdate(UIDefaults defaults) {
      Enumeration newKeys = defaults.keys();
      keys.removeAllElements();
      while (newKeys.hasMoreElements()) {
        keys.addElement(newKeys.nextElement());
      }
      Enumeration newValues = defaults.elements();
      values.removeAllElements();
      while (newValues.hasMoreElements()) {
        values.addElement(newValues.nextElement());
      }
      fireTableDataChanged();
    }
  }
  public static void main(String args[]) {
    final JFrame frame = new JFrame("List Properties");
    final CustomTableModel model = new CustomTableModel();
    model.uiDefaultsUpdate(UIManager.getDefaults());
    TableSorter sorter = new TableSorter(model);
    JTable table = new JTable(sorter);
    TableHeaderSorter.install(sorter, table);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
    UIManager.LookAndFeelInfo looks[] = UIManager
        .getInstalledLookAndFeels();
    ActionListener actionListener = new ActionListener() {
      public void actionPerformed(ActionEvent actionEvent) {
        final String lafClassName = actionEvent.getActionCommand();
        Runnable runnable = new Runnable() {
          public void run() {
            try {
              UIManager.setLookAndFeel(lafClassName);
              SwingUtilities.updateComponentTreeUI(frame);
              // Added
              model.uiDefaultsUpdate(UIManager.getDefaults());
            } catch (Exception exception) {
              JOptionPane.showMessageDialog(frame,
                  "Can"t change look and feel",
                  "Invalid PLAF", JOptionPane.ERROR_MESSAGE);
            }
          }
        };
        SwingUtilities.invokeLater(runnable);
      }
    };
    JToolBar toolbar = new JToolBar();
    for (int i = 0, n = looks.length; i < n; i++) {
      JButton button = new JButton(looks[i].getName());
      button.setActionCommand(looks[i].getClassName());
      button.addActionListener(actionListener);
      toolbar.add(button);
    }
    Container content = frame.getContentPane();
    content.add(toolbar, BorderLayout.NORTH);
    JScrollPane scrollPane = new JScrollPane(table);
    content.add(scrollPane, BorderLayout.CENTER);
    frame.setSize(400, 400);
    frame.setVisible(true);
  }
}
class TableSorter extends TableMap implements TableModelListener {
  int indexes[] = new int[0];
  Vector sortingColumns = new Vector();
  boolean ascending = true;
  public TableSorter() {
  }
  public TableSorter(TableModel model) {
    setModel(model);
  }
  public void setModel(TableModel model) {
    super.setModel(model);
    reallocateIndexes();
    sortByColumn(0);
    fireTableDataChanged();
  }
  public int compareRowsByColumn(int row1, int row2, int column) {
    Class type = model.getColumnClass(column);
    TableModel data = model;
    // Check for nulls
    Object o1 = data.getValueAt(row1, column);
    Object o2 = data.getValueAt(row2, column);
    // If both values are null return 0
    if (o1 == null && o2 == null) {
      return 0;
    } else if (o1 == null) { // Define null less than everything.
      return -1;
    } else if (o2 == null) {
      return 1;
    }
    if (type.getSuperclass() == Number.class) {
      Number n1 = (Number) data.getValueAt(row1, column);
      double d1 = n1.doubleValue();
      Number n2 = (Number) data.getValueAt(row2, column);
      double d2 = n2.doubleValue();
      if (d1 < d2)
        return -1;
      else if (d1 > d2)
        return 1;
      else
        return 0;
    } else if (type == String.class) {
      String s1 = (String) data.getValueAt(row1, column);
      String s2 = (String) data.getValueAt(row2, column);
      int result = s1.rupareTo(s2);
      if (result < 0)
        return -1;
      else if (result > 0)
        return 1;
      else
        return 0;
    } else if (type == java.util.Date.class) {
      Date d1 = (Date) data.getValueAt(row1, column);
      long n1 = d1.getTime();
      Date d2 = (Date) data.getValueAt(row2, column);
      long n2 = d2.getTime();
      if (n1 < n2)
        return -1;
      else if (n1 > n2)
        return 1;
      else
        return 0;
    } else if (type == Boolean.class) {
      Boolean bool1 = (Boolean) data.getValueAt(row1, column);
      boolean b1 = bool1.booleanValue();
      Boolean bool2 = (Boolean) data.getValueAt(row2, column);
      boolean b2 = bool2.booleanValue();
      if (b1 == b2)
        return 0;
      else if (b1) // Define false < true
        return 1;
      else
        return -1;
    } else {
      Object v1 = data.getValueAt(row1, column);
      String s1 = v1.toString();
      Object v2 = data.getValueAt(row2, column);
      String s2 = v2.toString();
      int result = s1.rupareTo(s2);
      if (result < 0)
        return -1;
      else if (result > 0)
        return 1;
      else
        return 0;
    }
  }
  public int compare(int row1, int row2) {
    for (int level = 0, n = sortingColumns.size(); level < n; level++) {
      Integer column = (Integer) sortingColumns.elementAt(level);
      int result = compareRowsByColumn(row1, row2, column.intValue());
      if (result != 0) {
        return (ascending ? result : -result);
      }
    }
    return 0;
  }
  public void reallocateIndexes() {
    int rowCount = model.getRowCount();
    indexes = new int[rowCount];
    for (int row = 0; row < rowCount; row++) {
      indexes[row] = row;
    }
  }
  public void tableChanged(TableModelEvent tableModelEvent) {
    super.tableChanged(tableModelEvent);
    reallocateIndexes();
    sortByColumn(0);
    fireTableStructureChanged();
  }
  public void checkModel() {
    if (indexes.length != model.getRowCount()) {
      System.err.println("Sorter not informed of a change in model.");
    }
  }
  public void sort() {
    checkModel();
    shuttlesort((int[]) indexes.clone(), indexes, 0, indexes.length);
    fireTableDataChanged();
  }
  public void shuttlesort(int from[], int to[], int low, int high) {
    if (high - low < 2) {
      return;
    }
    int middle = (low + high) / 2;
    shuttlesort(to, from, low, middle);
    shuttlesort(to, from, middle, high);
    int p = low;
    int q = middle;
    for (int i = low; i < high; i++) {
      if (q >= high || (p < middle && compare(from[p], from[q]) <= 0)) {
        to[i] = from[p++];
      } else {
        to[i] = from[q++];
      }
    }
  }
  private void swap(int first, int second) {
    int temp = indexes[first];
    indexes[first] = indexes[second];
    indexes[second] = temp;
  }
  public Object getValueAt(int row, int column) {
    checkModel();
    return model.getValueAt(indexes[row], column);
  }
  public void setValueAt(Object aValue, int row, int column) {
    checkModel();
    model.setValueAt(aValue, indexes[row], column);
  }
  public void sortByColumn(int column) {
    sortByColumn(column, true);
  }
  public void sortByColumn(int column, boolean ascending) {
    this.ascending = ascending;
    sortingColumns.removeAllElements();
    sortingColumns.addElement(new Integer(column));
    sort();
    super.tableChanged(new TableModelEvent(this));
  }
}
class TableHeaderSorter extends MouseAdapter {
  private TableSorter sorter;
  private JTable table;
  private TableHeaderSorter() {
  }
  public static void install(TableSorter sorter, JTable table) {
    TableHeaderSorter tableHeaderSorter = new TableHeaderSorter();
    tableHeaderSorter.sorter = sorter;
    tableHeaderSorter.table = table;
    JTableHeader tableHeader = table.getTableHeader();
    tableHeader.addMouseListener(tableHeaderSorter);
  }
  public void mouseClicked(MouseEvent mouseEvent) {
    TableColumnModel columnModel = table.getColumnModel();
    int viewColumn = columnModel.getColumnIndexAtX(mouseEvent.getX());
    int column = table.convertColumnIndexToModel(viewColumn);
    if (mouseEvent.getClickCount() == 1 && column != -1) {
      System.out.println("Sorting ...");
      int shiftPressed = (mouseEvent.getModifiers() & InputEvent.SHIFT_MASK);
      boolean ascending = (shiftPressed == 0);
      sorter.sortByColumn(column, ascending);
    }
  }
}
class TableMap extends AbstractTableModel implements TableModelListener {
  TableModel model;
  public TableModel getModel() {
    return model;
  }
  public void setModel(TableModel model) {
    if (this.model != null) {
      this.model.removeTableModelListener(this);
    }
    this.model = model;
    if (this.model != null) {
      this.model.addTableModelListener(this);
    }
  }
  public Class getColumnClass(int column) {
    return model.getColumnClass(column);
  }
  public int getColumnCount() {
    return ((model == null) ? 0 : model.getColumnCount());
  }
  public String getColumnName(int column) {
    return model.getColumnName(column);
  }
  public int getRowCount() {
    return ((model == null) ? 0 : model.getRowCount());
  }
  public Object getValueAt(int row, int column) {
    return model.getValueAt(row, column);
  }
  public void setValueAt(Object value, int row, int column) {
    model.setValueAt(value, row, column);
  }
  public boolean isCellEditable(int row, int column) {
    return model.isCellEditable(row, column);
  }
  public void tableChanged(TableModelEvent tableModelEvent) {
    fireTableChanged(tableModelEvent);
  }
}





Making a Cell Visible in a JTable Component

import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.JTable;
import javax.swing.JViewport;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable(10, 5);
    
    int rowIndex = 1;
    int vColIndex = 2;
    scrollToVisible(table, rowIndex, vColIndex);
  }
  public static void scrollToVisible(JTable table, int rowIndex, int vColIndex) {
    if (!(table.getParent() instanceof JViewport)) {
      return;
    }
    JViewport viewport = (JViewport) table.getParent();
    Rectangle rect = table.getCellRect(rowIndex, vColIndex, true);
    Point pt = viewport.getViewPosition();
    rect.setLocation(rect.x - pt.x, rect.y - pt.y);
    viewport.scrollRectToVisible(rect);
  }
}





Move the last visible column so it becomes the first visible column

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    table.moveColumn(table.getColumnCount() - 1, 0);
  }
}





Programmatically Starting Cell Editing in a JTable Component

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(true);
    int row = 1;
    int col = 3;
    boolean success = table.editCellAt(row, col);
    if (success) {
      boolean toggle = false;
      boolean extend = false;
      table.changeSelection(row, col, toggle, extend);
    }
  }
}





Property Table: Use JTable to display and edit properties

 
/*
 * Copyright (c) 2000 David Flanagan.  All rights reserved.
 * This code is from the book Java Examples in a Nutshell, 2nd Edition.
 * It is provided AS-IS, WITHOUT ANY WARRANTY either expressed or implied.
 * You may study, use, and modify it for any non-commercial purpose.
 * You may distribute it non-commercially as long as you retain this notice.
 * For a commercial use license, or to purchase the book (recommended),
 * visit http://www.davidflanagan.ru/javaexamples2.
 */
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.Arrays;
import java.util.ruparator;
import javax.swing.JFrame;
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.TableColumn;
import javax.swing.table.TableColumnModel;
/**
 * This class is a JTable subclass that displays a table of the JavaBeans
 * properties of any specified class.
 */
public class PropertyTable extends JTable {
  /** This main method allows the class to be demonstrated standalone */
  public static void main(String[] args) {
    // Specify the name of the class as a command-line argument
    Class beanClass = null;
    try {
      // Use reflection to get the Class from the classname
      beanClass = Class.forName("javax.swing.JLabel");
    } catch (Exception e) { // Report errors
      System.out.println("Can"t find specified class: " + e.getMessage());
      System.out.println("Usage: java TableDemo <JavaBean class name>");
      System.exit(0);
    }
    // Create a table to display the properties of the specified class
    JTable table = new PropertyTable(beanClass);
    // Then put the table in a scrolling window, put the scrolling
    // window into a frame, and pop it all up on to the screen
    JScrollPane scrollpane = new JScrollPane(table);
    JFrame frame = new JFrame("Properties of JavaBean: ");
    frame.getContentPane().add(scrollpane);
    frame.setSize(500, 400);
    frame.setVisible(true);
  }
  /**
   * This constructor method specifies what data the table will display (the
   * table model) and uses the TableColumnModel to customize the way that the
   * table displays it. The hard work is done by the TableModel implementation
   * below.
   */
  public PropertyTable(Class beanClass) {
    // Set the data model for this table
    try {
      setModel(new JavaBeanPropertyTableModel(beanClass));
    } catch (IntrospectionException e) {
      System.err.println("WARNING: can"t introspect: " + beanClass);
    }
    // Tweak the appearance of the table by manipulating its column model
    TableColumnModel colmodel = getColumnModel();
    // Set column widths
    colmodel.getColumn(0).setPreferredWidth(125);
    colmodel.getColumn(1).setPreferredWidth(200);
    colmodel.getColumn(2).setPreferredWidth(75);
    colmodel.getColumn(3).setPreferredWidth(50);
    // Right justify the text in the first column
    TableColumn namecol = colmodel.getColumn(0);
    DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
    renderer.setHorizontalAlignment(SwingConstants.RIGHT);
    namecol.setCellRenderer(renderer);
  }
  /**
   * This class implements TableModel and represents JavaBeans property data
   * in a way that the JTable component can display. If you"ve got some type
   * of tabular data to display, implement a TableModel class to describe that
   * data, and the JTable component will be able to display it.
   */
  static class JavaBeanPropertyTableModel extends AbstractTableModel {
    PropertyDescriptor[] properties; // The properties to display
    /**
     * The constructor: use the JavaBeans introspector mechanism to get
     * information about all the properties of a bean. Once we"ve got this
     * information, the other methods will interpret it for JTable.
     */
    public JavaBeanPropertyTableModel(Class beanClass)
        throws java.beans.IntrospectionException {
      // Use the introspector class to get "bean info" about the class.
      BeanInfo beaninfo = Introspector.getBeanInfo(beanClass);
      // Get the property descriptors from that BeanInfo class
      properties = beaninfo.getPropertyDescriptors();
      // Now do a case-insensitive sort by property name
      // The anonymous Comparator implementation specifies how to
      // sort PropertyDescriptor objects by name
      Arrays.sort(properties, new Comparator() {
        public int compare(Object p, Object q) {
          PropertyDescriptor a = (PropertyDescriptor) p;
          PropertyDescriptor b = (PropertyDescriptor) q;
          return a.getName().rupareToIgnoreCase(b.getName());
        }
        public boolean equals(Object o) {
          return o == this;
        }
      });
    }
    // These are the names of the columns represented by this TableModel
    static final String[] columnNames = new String[] { "Name", "Type",
        "Access", "Bound" };
    // These are the types of the columns represented by this TableModel
    static final Class[] columnTypes = new Class[] { String.class,
        Class.class, String.class, Boolean.class };
    // These simple methods return basic information about the table
    public int getColumnCount() {
      return columnNames.length;
    }
    public int getRowCount() {
      return properties.length;
    }
    public String getColumnName(int column) {
      return columnNames[column];
    }
    public Class getColumnClass(int column) {
      return columnTypes[column];
    }
    /**
     * This method returns the value that appears at the specified row and
     * column of the table
     */
    public Object getValueAt(int row, int column) {
      PropertyDescriptor prop = properties[row];
      switch (column) {
      case 0:
        return prop.getName();
      case 1:
        return prop.getPropertyType();
      case 2:
        return getAccessType(prop);
      case 3:
        return new Boolean(prop.isBound());
      default:
        return null;
      }
    }
    // A helper method called from getValueAt() above
    String getAccessType(PropertyDescriptor prop) {
      java.lang.reflect.Method reader = prop.getReadMethod();
      java.lang.reflect.Method writer = prop.getWriteMethod();
      if ((reader != null) && (writer != null))
        return "Read/Write";
      else if (reader != null)
        return "Read-Only";
      else if (writer != null)
        return "Write-Only";
      else
        return "No Access"; // should never happen
    }
  }
}





Removing the Column Headers from a Scrollable in a JTable Component

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    // Remove the column headers
    table.setTableHeader(null);
  }
}





Resize Table

 
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
public class ResizeTable {
  public static void main(String args[]) {
    Object rowData[][] = { { "1", "one", "ichi - \u4E00", "un", "I" },
        { "2", "two", "ni - \u4E8C", "deux", "II" },
        { "3", "three", "san - \u4E09", "trois", "III" },
        { "4", "four", "shi - \u56DB", "quatre", "IV" },
        { "5", "five", "go - \u4E94", "cinq", "V" },
        { "6", "six", "roku - \u516D", "treiza", "VI" },
        { "7", "seven", "shichi - \u4E03", "sept", "VII" },
        { "8", "eight", "hachi - \u516B", "huit", "VIII" },
        { "9", "nine", "kyu - \u4E5D", "neur", "IX" },
        { "10", "ten", "ju - \u5341", "dix", "X" } };
    String columnNames[] = { "#", "English", "Japanese", "French", "Roman" };
    final JTable table = new JTable(rowData, columnNames);
    JScrollPane scrollPane = new JScrollPane(table);
    String modes[] = { "Resize All Columns", "Resize Last Column",
        "Resize Next Column", "Resize Off", "Resize Subsequent Columns" };
    final int modeKey[] = { JTable.AUTO_RESIZE_ALL_COLUMNS,
        JTable.AUTO_RESIZE_LAST_COLUMN, JTable.AUTO_RESIZE_NEXT_COLUMN,
        JTable.AUTO_RESIZE_OFF, JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS };
    JComboBox resizeModeComboBox = new JComboBox(modes);
    int defaultMode = 4;
    table.setAutoResizeMode(modeKey[defaultMode]);
    resizeModeComboBox.setSelectedIndex(defaultMode);
    ItemListener itemListener = new ItemListener() {
      public void itemStateChanged(ItemEvent e) {
        JComboBox source = (JComboBox) e.getSource();
        int index = source.getSelectedIndex();
        table.setAutoResizeMode(modeKey[index]);
      }
    };
    resizeModeComboBox.addItemListener(itemListener);
    JFrame frame = new JFrame("Resizing Table");
    Container contentPane = frame.getContentPane();
    contentPane.add(resizeModeComboBox, BorderLayout.NORTH);
    contentPane.add(scrollPane, BorderLayout.CENTER);
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}





Retrieve the value in cell (1,2) from the model

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 3;
    int cols = 3;
    JTable table = new JTable(rows, cols);
    Object o = table.getModel().getValueAt(1, 1);
  }
}





Retrieve the value in the visible cell (1,2) in a JTable

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 3;
    int cols = 3;
    JTable table = new JTable(rows, cols);
    int rowIndex = 1;
    int vColIndex = 2;
    Object o = table.getValueAt(rowIndex, vColIndex);
  }
}





Row selection is enabled, Get the indices of the selected rows

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    if (!table.getColumnSelectionAllowed() && table.getRowSelectionAllowed()) {
      // 
      int[] rowIndices = table.getSelectedRows();
    }
  }
}





Save the current value in the cell being edited and stops the editing process

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    // Enable the ability to select a single cell
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(true);
    if (table.getCellEditor() != null) {
      table.getCellEditor().stopCellEditing();
    }
  }
}





Scrolling a Cell to the Center of a JTable Component

import java.awt.Rectangle;
import javax.swing.JTable;
import javax.swing.JViewport;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable(5, 5);
    int rowIndex = 1;
    int vColIndex = 2;
    scrollToCenter(table, rowIndex, vColIndex);
  }
  public static void scrollToCenter(JTable table, int rowIndex, int vColIndex) {
    if (!(table.getParent() instanceof JViewport)) {
      return;
    }
    JViewport viewport = (JViewport) table.getParent();
    Rectangle rect = table.getCellRect(rowIndex, vColIndex, true);
    Rectangle viewRect = viewport.getViewRect();
    rect.setLocation(rect.x - viewRect.x, rect.y - viewRect.y);
    int centerX = (viewRect.width - rect.width) / 2;
    int centerY = (viewRect.height - rect.height) / 2;
    if (rect.x < centerX) {
      centerX = -centerX;
    }
    if (rect.y < centerY) {
      centerY = -centerY;
    }
    rect.translate(centerX, centerY);
    viewport.scrollRectToVisible(rect);
  }
}





Scroll Table Sample

 
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JTable;
public class ScrollTableSample {
  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("Scrollless Table");
    JTable table = new JTable(rows, headers);
    frame.getContentPane().add(table, BorderLayout.CENTER);
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}





Select a cell: cell (2,1)

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(true);
    int row = 2;
    int col = 1;
    boolean toggle = false;
    boolean extend = false;
    table.changeSelection(row, col, toggle, extend);
  }
}





Select a column - column 0 in a JTable

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(false);
    // Select a column - column 0
    table.setColumnSelectionInterval(0, 0);
  }
}





Select all cells

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    // 
    table.selectAll();
  }
}





Select an additional range of columns - columns 1 to 2

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(false);
    // Select an additional range of columns - columns 1 to 2
    table.addColumnSelectionInterval(1, 2);
  }
}





Select an additional range of rows - rows 1 to 2

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(false);
    table.setColumnSelectionAllowed(false);
    table.setRowSelectionAllowed(true);
    table.addRowSelectionInterval(1, 2);
  }
}





Select a row - row 0

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(false);
    table.setColumnSelectionAllowed(false);
    table.setRowSelectionAllowed(true);
    table.setRowSelectionInterval(0, 0);
  }
}





Set the grid color

import java.awt.Color;
import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    table.setGridColor(Color.red);
  }
}





Setting Column Header Tool Tips in a JTable Components

import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    JTableHeader header = table.getTableHeader();
    ColumnHeaderToolTips tips = new ColumnHeaderToolTips();
    for (int c = 0; c < table.getColumnCount(); c++) {
      TableColumn col = table.getColumnModel().getColumn(c);
      tips.setToolTip(col, "Col " + c);
    }
    header.addMouseMotionListener(tips);
  }
}
class ColumnHeaderToolTips extends MouseMotionAdapter {
  TableColumn curCol;
  Map tips = new HashMap();
  public void setToolTip(TableColumn col, String tooltip) {
    if (tooltip == null) {
      tips.remove(col);
    } else {
      tips.put(col, tooltip);
    }
  }
  public void mouseMoved(MouseEvent evt) {
    JTableHeader header = (JTableHeader) evt.getSource();
    JTable table = header.getTable();
    TableColumnModel colModel = table.getColumnModel();
    int vColIndex = colModel.getColumnIndexAtX(evt.getX());
    TableColumn col = null;
    if (vColIndex >= 0) {
      col = colModel.getColumn(vColIndex);
    }
    if (col != curCol) {
      header.setToolTipText((String) tips.get(col));
      curCol = col;
    }
  }
}





Setting Tool Tips on Cells in a JTable Component

import java.awt.ruponent;
import javax.swing.JComponent;
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 (c instanceof JComponent) {
          JComponent jc = (JComponent) c;
          jc.setToolTipText((String) getValueAt(rowIndex, vColIndex));
        }
        return c;
      }
    };
  }
}





Show both horizontal and vertical grid lines (the default)

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();

    table.setShowGrid(true);
  }
}





Showing the Table Header in a Non-Scrollable JTable Component

import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.JTableHeader;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    JTableHeader header = table.getTableHeader();
    JPanel container = new JPanel(new BorderLayout());
    // Add header in NORTH slot
    container.add(header, BorderLayout.NORTH);
    // Add table itself to CENTER slot
    container.add(table, BorderLayout.CENTER);
  }
}





Show only horizontal grid lines

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    table.setShowGrid(false);
    table.setShowHorizontalLines(true);
  }
}





Show only vertical grid lines

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    JTable table = new JTable();
    table.setShowGrid(false);
    table.setShowVerticalLines(true);
  }
}





Simple demonstration of JTable

 
// : c14:JTableDemo.java
// Simple demonstration of JTable.
// <applet code=Table width=350 height=200></applet>
// From "Thinking in Java, 3rd ed." (c) Bruce Eckel 2002
// www.BruceEckel.ru. See copyright notice in CopyRight.txt.
import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.JApplet;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
public class JTableDemo extends JApplet {
  private JTextArea txt = new JTextArea(4, 20);
  // The TableModel controls all the data:
  class DataModel extends AbstractTableModel {
    Object[][] data = { { "one", "two", "three", "four" },
        { "five", "six", "seven", "eight" },
        { "nine", "ten", "eleven", "twelve" }, };
    // Prints data when table changes:
    class TML implements TableModelListener {
      public void tableChanged(TableModelEvent e) {
        txt.setText(""); // Clear it
        for (int i = 0; i < data.length; i++) {
          for (int j = 0; j < data[0].length; j++)
            txt.append(data[i][j] + " ");
          txt.append("\n");
        }
      }
    }
    public DataModel() {
      addTableModelListener(new TML());
    }
    public int getColumnCount() {
      return data[0].length;
    }
    public int getRowCount() {
      return data.length;
    }
    public Object getValueAt(int row, int col) {
      return data[row][col];
    }
    public void setValueAt(Object val, int row, int col) {
      data[row][col] = val;
      // Indicate the change has happened:
      fireTableDataChanged();
    }
    public boolean isCellEditable(int row, int col) {
      return true;
    }
  }
  public void init() {
    Container cp = getContentPane();
    JTable table = new JTable(new DataModel());
    cp.add(new JScrollPane(table));
    cp.add(BorderLayout.SOUTH, txt);
  }
  public static void main(String[] args) {
    run(new JTableDemo(), 350, 200);
  }
  public static void run(JApplet applet, int width, int height) {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(applet);
    frame.setSize(width, height);
    applet.init();
    applet.start();
    frame.setVisible(true);
  }
} ///:~





Sorting a Column in a JTable Component

import java.util.Arrays;
import java.util.ruparator;
import java.util.Vector;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    DefaultTableModel model = new DefaultTableModel();
    JTable table = new JTable(model);
    table.setAutoCreateColumnsFromModel(false);
    boolean ascending = false;
    Vector data = model.getDataVector();
    Object[] colData = new Object[model.getRowCount()];
    for (int i = 0; i < colData.length; i++) {
      colData[i] = ((Vector) data.get(i)).get(0);
    }
    Arrays.sort(colData, new ColumnSorter());
    for (int i = 0; i < colData.length; i++) {
      ((Vector) data.get(i)).set(0, colData[i]);
    }
    model.fireTableStructureChanged();
  }
}
class ColumnSorter implements Comparator {
  ColumnSorter() {
  }
  public int compare(Object a, Object b) {
    if (a instanceof String && ((String) a).length() == 0) {
      a = null;
    }
    if (b instanceof String && ((String) b).length() == 0) {
      b = null;
    }
    if (a == null && b == null) {
      return 0;
    } else if (a == null) {
      return 1;
    } else if (b == null) {
      return -1;
    } else if (a instanceof Comparable) {
      return ((Comparable) a).rupareTo(b);
    } else {
      return a.toString().rupareTo(b.toString());
    }
  }
}





Sorting and Filtering Tables

import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowSorter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public class Main {
  public static void main(String args[]) {
    JFrame frame = new JFrame("Sorting JTable");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Object rows[][] = { { "A", "A", 1 }, { "E", "E", 4 }, { "Y", "Y", 3 } };
    String columns[] = { "Symbol", "Name", "Price" };
    TableModel model = new DefaultTableModel(rows, columns) {
      public Class getColumnClass(int column) {
        Class returnValue;
        if ((column >= 0) && (column < getColumnCount())) {
          returnValue = getValueAt(0, column).getClass();
        } else {
          returnValue = Object.class;
        }
        return returnValue;
      }
    };
    JTable table = new JTable(model);
    RowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
    table.setRowSorter(sorter);
    JScrollPane pane = new JScrollPane(table);
    frame.add(pane, BorderLayout.CENTER);
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}





Sorting the Rows in a JTable Component Based on a Column

import java.util.Collections;
import java.util.ruparator;
import java.util.Vector;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    DefaultTableModel model = new DefaultTableModel();
    JTable table = new JTable(model);
    table.setAutoCreateColumnsFromModel(false);
    Vector data = model.getDataVector();
    Collections.sort(data, new ColumnSorter(0));
    model.fireTableStructureChanged();
  }
}
class ColumnSorter implements Comparator {
  int colIndex;
  ColumnSorter(int colIndex) {
    this.colIndex = colIndex;
  }
  public int compare(Object a, Object b) {
    Vector v1 = (Vector) a;
    Vector v2 = (Vector) b;
    Object o1 = v1.get(colIndex);
    Object o2 = v2.get(colIndex);
    if (o1 instanceof String && ((String) o1).length() == 0) {
      o1 = null;
    }
    if (o2 instanceof String && ((String) o2).length() == 0) {
      o2 = null;
    }
    if (o1 == null && o2 == null) {
      return 0;
    } else if (o1 == null) {
      return 1;
    } else if (o2 == null) {
      return -1;
    } else if (o1 instanceof Comparable) {
      return ((Comparable) o1).rupareTo(o2);
    } else {
      return o1.toString().rupareTo(o2.toString());
    }
  }
}





StockTable 4: Table Sorter

 
/*
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 StocksTable4 extends JFrame 
{
  protected JTable m_table;
  protected StockTableData m_data;
  protected JLabel m_title;
  public StocksTable4() {
    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(true);
    header.addMouseListener(m_data.new ColumnListener(m_table));
    header.setReorderingAllowed(true);
    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 StocksTable4();
  }
}
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;
  protected int     m_sortCol = 0;
  protected boolean m_sortAsc = true;
  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));
    Collections.sort(m_vector, new 
      StockComparator(m_sortCol, m_sortAsc));
  }
  public int getRowCount() {
    return m_vector==null ? 0 : m_vector.size(); 
  }
  public int getColumnCount() { 
    return m_columns.length; 
  } 
  public String getColumnName(int column) {
    String str = m_columns[column].m_title;
    if (column==m_sortCol)
      str += m_sortAsc ? ">>" : "<<";
    return str;
  }
 
  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);
  }
  class ColumnListener extends MouseAdapter
  {
    protected JTable m_table;
    public ColumnListener(JTable table) {
      m_table = table;
    }
    public void mouseClicked(MouseEvent e) {
      TableColumnModel colModel = m_table.getColumnModel();
      int columnModelIndex = colModel.getColumnIndexAtX(e.getX());
      int modelIndex = colModel.getColumn(columnModelIndex).getModelIndex();
      if (modelIndex < 0)
        return;
      if (m_sortCol==modelIndex)
        m_sortAsc = !m_sortAsc;
      else
        m_sortCol = modelIndex;
      for (int i=0; i < m_columns.length; i++) {
        TableColumn column = colModel.getColumn(i);
        column.setHeaderValue(getColumnName(column.getModelIndex()));    
      }
      m_table.getTableHeader().repaint();  
      Collections.sort(m_vector, new 
        StockComparator(modelIndex, m_sortAsc));
      m_table.tableChanged(
        new TableModelEvent(StockTableData.this)); 
      m_table.repaint();  
    }
  }
}
class StockComparator implements Comparator
{
  protected int     m_sortCol;
  protected boolean m_sortAsc;
  public StockComparator(int sortCol, boolean sortAsc) {
    m_sortCol = sortCol;
    m_sortAsc = sortAsc;
  }
  public int compare(Object o1, Object o2) {
    if(!(o1 instanceof StockData) || !(o2 instanceof StockData))
      return 0;
    StockData s1 = (StockData)o1;
    StockData s2 = (StockData)o2;
    int result = 0;
    double d1, d2;
    switch (m_sortCol) {
      case 0:    // symbol
        String str1 = (String)s1.m_symbol.m_data;
        String str2 = (String)s2.m_symbol.m_data;
        result = str1.rupareTo(str2);
        break;
      case 1:    // name
        result = s1.m_name.rupareTo(s2.m_name);
        break;
      case 2:    // last
        d1 = s1.m_last.doubleValue();
        d2 = s2.m_last.doubleValue();
        result = d1<d2 ? -1 : (d1>d2 ? 1 : 0);
        break;
      case 3:    // open
        d1 = s1.m_open.doubleValue();
        d2 = s2.m_open.doubleValue();
        result = d1<d2 ? -1 : (d1>d2 ? 1 : 0);
        break;
      case 4:    // change
        d1 = ((Fraction)s1.m_change.m_data).doubleValue();
        d2 = ((Fraction)s2.m_change.m_data).doubleValue();
        result = d1<d2 ? -1 : (d1>d2 ? 1 : 0);
        break;
      case 5:    // change %
        d1 = ((Double)s1.m_changePr.m_data).doubleValue();
        d2 = ((Double)s2.m_changePr.m_data).doubleValue();
        result = d1<d2 ? -1 : (d1>d2 ? 1 : 0);
        break;
      case 6:    // volume
        long l1 = s1.m_volume.longValue();
        long l2 = s2.m_volume.longValue();
        result = l1<l2 ? -1 : (l1>l2 ? 1 : 0);
        break;
    }
    if (!m_sortAsc)
      result = -result;
    return result;
  }
  public boolean equals(Object obj) {
    if (obj instanceof StockComparator) {
      StockComparator compObj = (StockComparator)obj;
      return (compObj.m_sortCol==m_sortCol) && 
        (compObj.m_sortAsc==m_sortAsc);
    }
    return false;
  }
}





StockTable 6: Action and Dynamic Display

 
/*
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 java.sql.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class StocksTable6 extends JFrame 
{
  protected JTable m_table;
  protected StockTableData m_data;
  protected JLabel m_title;
  public StocksTable6() {
    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(true);
    header.addMouseListener(m_data.new ColumnListener(m_table));
    header.setReorderingAllowed(true);
    m_table.getColumnModel().addColumnModelListener(
      m_data.new ColumnMovementListener());
    JScrollPane ps = new JScrollPane();
    ps.getViewport().add(m_table);
    getContentPane().add(ps, BorderLayout.CENTER);
    JMenuBar menuBar = createMenuBar();
      setJMenuBar(menuBar);
    WindowListener wndCloser = new WindowAdapter() {
      public void windowClosing(WindowEvent e) {
        System.exit(0);
      }
    };
    addWindowListener(wndCloser);
    setVisible(true);
  }
  protected JMenuBar createMenuBar() {
    JMenuBar menuBar = new JMenuBar();
        
    JMenu mFile = new JMenu("File");
    mFile.setMnemonic("f");
    JMenuItem mData = new JMenuItem("Retrieve Data...");
    mData.setMnemonic("r");
    ActionListener lstData = new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
        retrieveData(); 
      }
    };
    mData.addActionListener(lstData);
    mFile.add(mData);
    mFile.addSeparator();
    JMenuItem mExit = new JMenuItem("Exit");
    mExit.setMnemonic("x");
    ActionListener lstExit = new ActionListener() { 
      public void actionPerformed(ActionEvent e) {
        System.exit(0);
      }
    };
    mExit.addActionListener(lstExit);
    mFile.add(mExit);
    menuBar.add(mFile);
    JMenu mView = new JMenu("View");
    mView.setMnemonic("v");
    TableColumnModel model = m_table.getColumnModel();
    for (int k = 0; k < StockTableData.m_columns.length; k++) {
      JCheckBoxMenuItem item = new JCheckBoxMenuItem(
        StockTableData.m_columns[k].m_title);
      item.setSelected(true);
      TableColumn column = model.getColumn(k);
      item.addActionListener(new ColumnKeeper(column, 
        StockTableData.m_columns[k]));
      mView.add(item);
    }
    menuBar.add(mView);
    return menuBar;
  }
  public void retrieveData() {
    SimpleDateFormat frm = new SimpleDateFormat("MM/dd/yyyy");
    String currentDate = frm.format(m_data.m_date);
    String result = (String)JOptionPane.showInputDialog(this, 
      "Please enter date in form mm/dd/yyyy:", "Input", 
      JOptionPane.INFORMATION_MESSAGE, null, null, 
      currentDate);
    if (result==null)
      return;
    java.util.Date date = null;
    try { 
      date = frm.parse(result); 
    }
    catch (java.text.ParseException ex) { 
      date = null; 
    }
        
    if (date == null) {
      JOptionPane.showMessageDialog(this, 
        result+" is not a valid date",
        "Warning", JOptionPane.WARNING_MESSAGE);
      return;
    }
    setCursor( Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR) );
    switch (m_data.retrieveData(date)) {
      case 0:    // Ok with data
        m_title.setText(m_data.getTitle());
        m_table.tableChanged(new TableModelEvent(m_data)); 
        m_table.repaint();
        break;
      case 1: // No data
        JOptionPane.showMessageDialog(this, 
          "No data found for "+result,
          "Warning", JOptionPane.WARNING_MESSAGE);
        break;
      case -1: // Error
        JOptionPane.showMessageDialog(this, 
          "Error retrieving data",
          "Warning", JOptionPane.WARNING_MESSAGE);
        break;
    }
    setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  }
  class ColumnKeeper implements ActionListener
  {
    protected TableColumn m_column;
    protected ColumnData  m_colData;
    public ColumnKeeper(TableColumn column, ColumnData  colData) {
      m_column = column;
      m_colData = colData;
    }
    public void actionPerformed(ActionEvent e) {
      JCheckBoxMenuItem item = (JCheckBoxMenuItem)e.getSource();
      TableColumnModel model = m_table.getColumnModel();
      if (item.isSelected()) {
        model.addColumn(m_column);
      }
      else {
        model.removeColumn(m_column);
      }
      m_table.tableChanged(new TableModelEvent(m_data)); 
      m_table.repaint();
    }
  }
  public static void main(String argv[]) {
    new StocksTable6();
  }
}
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 java.util.Date m_date;
  protected int m_columnsCount = m_columns.length;
  protected int m_sortCol = 0;
  protected boolean m_sortAsc = true;
  protected int m_result = 0;
  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));
    Collections.sort(m_vector, new 
      StockComparator(m_sortCol, m_sortAsc));
  }
  public int getRowCount() {
    return m_vector==null ? 0 : m_vector.size(); 
  }
  public int getColumnCount() { 
    return m_columnsCount;
  } 
  public String getColumnName(int column) {
    String str = m_columns[column].m_title;
    if (column==m_sortCol)
      str += m_sortAsc ? ">>" : "<<";
    return str;
  }
 
  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);
  }
  public int retrieveData(final java.util.Date date) {
    GregorianCalendar calendar = new GregorianCalendar();
    calendar.setTime(date);
    int month = calendar.get(Calendar.MONTH)+1;
    int day = calendar.get(Calendar.DAY_OF_MONTH);
    int year = calendar.get(Calendar.YEAR);
    final String query = "SELECT data.symbol, symbols.name, "+
      "data.last, data.open, data.change, data.changeproc, "+
      "data.volume FROM DATA INNER JOIN SYMBOLS "+
      "ON DATA.symbol = SYMBOLS.symbol WHERE "+
      "month(data.date1)="+month+" AND day(data.date1)="+day+
      " AND year(data.date1)="+year;
    Thread runner = new Thread() {
      public void run() {
        try {
          // Load the JDBC-ODBC bridge driver
          Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
          Connection conn = DriverManager.getConnection(
            "jdbc:odbc:Market", "admin", "");
          Statement stmt = conn.createStatement();
          ResultSet results = stmt.executeQuery(query);
          boolean hasData = false;
          while (results.next()) {
            if (!hasData) {
              m_vector.removeAllElements();
              hasData = true;
            }
            String  symbol = results.getString(1);
            String  name = results.getString(2);
            double  last = results.getDouble(3);
            double  open = results.getDouble(4);
            double  change = results.getDouble(5);
            double  changePr = results.getDouble(6);
            long volume = results.getLong(7);
            m_vector.addElement(new StockData(symbol, name, last, 
              open, change, changePr, volume));
          }
          results.close();
          stmt.close();
          conn.close();
          if (!hasData)    // We"ve got nothing
            m_result = 1;
        }
        catch (Exception e) {
          e.printStackTrace();
          System.err.println("Load data error: "+e.toString());
          m_result = -1;
        }
        m_date = date;
        Collections.sort(m_vector, 
          new StockComparator(m_sortCol, m_sortAsc));
        m_result = 0;
      }
    };
    runner.start();
    return m_result;
  }
  class ColumnListener extends MouseAdapter
  {
    protected JTable m_table;
    public ColumnListener(JTable table) {
      m_table = table;
    }
    public void mouseClicked(MouseEvent e) {
      TableColumnModel colModel = m_table.getColumnModel();
      int columnModelIndex = colModel.getColumnIndexAtX(e.getX());
      int modelIndex = colModel.getColumn(columnModelIndex).getModelIndex();
      if (modelIndex < 0)
        return;
      if (m_sortCol==modelIndex)
        m_sortAsc = !m_sortAsc;
      else
        m_sortCol = modelIndex;
      for (int i=0; i < m_columnsCount; i++) { //NEW
        TableColumn column = colModel.getColumn(i);
        column.setHeaderValue(getColumnName(column.getModelIndex()));    
      }
      m_table.getTableHeader().repaint();  
      Collections.sort(m_vector, new 
        StockComparator(modelIndex, m_sortAsc));
      m_table.tableChanged(
        new TableModelEvent(StockTableData.this)); 
      m_table.repaint();  
    }
  }
  class ColumnMovementListener implements TableColumnModelListener
  {
    public void columnAdded(TableColumnModelEvent e) {
      m_columnsCount++;
    }
    public void columnRemoved(TableColumnModelEvent e) {
      m_columnsCount--;
      if (m_sortCol >= e.getFromIndex())
        m_sortCol = 0;
    }
    public void columnMarginChanged(ChangeEvent e) {}
    public void columnMoved(TableColumnModelEvent e) {}
    public void columnSelectionChanged(ListSelectionEvent e) {}
  }
}
class StockComparator implements Comparator
{
  protected int     m_sortCol;
  protected boolean m_sortAsc;
  public StockComparator(int sortCol, boolean sortAsc) {
    m_sortCol = sortCol;
    m_sortAsc = sortAsc;
  }
  public int compare(Object o1, Object o2) {
    if(!(o1 instanceof StockData) || !(o2 instanceof StockData))
      return 0;
    StockData s1 = (StockData)o1;
    StockData s2 = (StockData)o2;
    int result = 0;
    double d1, d2;
    switch (m_sortCol) {
      case 0:    // symbol
        String str1 = (String)s1.m_symbol.m_data;
        String str2 = (String)s2.m_symbol.m_data;
        result = str1.rupareTo(str2);
        break;
      case 1:    // name
        result = s1.m_name.rupareTo(s2.m_name);
        break;
      case 2:    // last
        d1 = s1.m_last.doubleValue();
        d2 = s2.m_last.doubleValue();
        result = d1<d2 ? -1 : (d1>d2 ? 1 : 0);
        break;
      case 3:    // open
        d1 = s1.m_open.doubleValue();
        d2 = s2.m_open.doubleValue();
        result = d1<d2 ? -1 : (d1>d2 ? 1 : 0);
        break;
      case 4:    // change
        d1 = ((Fraction)s1.m_change.m_data).doubleValue();
        d2 = ((Fraction)s2.m_change.m_data).doubleValue();
        result = d1<d2 ? -1 : (d1>d2 ? 1 : 0);
        break;
      case 5:    // change %
        d1 = ((Double)s1.m_changePr.m_data).doubleValue();
        d2 = ((Double)s2.m_changePr.m_data).doubleValue();
        result = d1<d2 ? -1 : (d1>d2 ? 1 : 0);
        break;
      case 6:    // volume
        long l1 = s1.m_volume.longValue();
        long l2 = s2.m_volume.longValue();
        result = l1<l2 ? -1 : (l1>l2 ? 1 : 0);
        break;
    }
    if (!m_sortAsc)
      result = -result;
    return result;
  }
  public boolean equals(Object obj) {
    if (obj instanceof StockComparator) {
      StockComparator compObj = (StockComparator)obj;
      return (compObj.m_sortCol==m_sortCol) && 
        (compObj.m_sortAsc==m_sortAsc);
    }
    return false;
  }
}





Table Selection mode

 
/* 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.
 */
/*
 * SimpleTableSelectionDemo.java is a 1.4 application that requires no other files.
 */
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JComponent;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/** 
 * SimpleTableSelectionDemo is just like SimpleTableDemo, 
 * except that it detects selections, printing information
 * about the current selection to standard output.
 */
public class SimpleTableSelectionDemo extends JPanel {
    private boolean DEBUG = false;
    private boolean ALLOW_COLUMN_SELECTION = false;
    private boolean ALLOW_ROW_SELECTION = true;
    public SimpleTableSelectionDemo() {
        super(new GridLayout(1,0));
        final String[] columnNames = {"First Name",
                                      "Last Name",
                                      "Sport",
                                      "# of Years",
                                      "Vegetarian"};
        final 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)}
        };
        final JTable table = new JTable(data, columnNames);
        table.setPreferredScrollableViewportSize(new Dimension(500, 70));
        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        if (ALLOW_ROW_SELECTION) { // true by default
            ListSelectionModel rowSM = table.getSelectionModel();
            rowSM.addListSelectionListener(new ListSelectionListener() {
                public void valueChanged(ListSelectionEvent e) {
                    //Ignore extra messages.
                    if (e.getValueIsAdjusting()) return;
                    ListSelectionModel lsm = (ListSelectionModel)e.getSource();
                    if (lsm.isSelectionEmpty()) {
                        System.out.println("No rows are selected.");
                    } else {
                        int selectedRow = lsm.getMinSelectionIndex();
                        System.out.println("Row " + selectedRow
                                           + " is now selected.");
                    }
                }
            });
        } else {
            table.setRowSelectionAllowed(false);
        }
        if (ALLOW_COLUMN_SELECTION) { // false by default
            if (ALLOW_ROW_SELECTION) {
                //We allow both row and column selection, which
                //implies that we *really* want to allow individual
                //cell selection.
                table.setCellSelectionEnabled(true);
            }
            table.setColumnSelectionAllowed(true);
            ListSelectionModel colSM =
                table.getColumnModel().getSelectionModel();
            colSM.addListSelectionListener(new ListSelectionListener() {
                public void valueChanged(ListSelectionEvent e) {
                    //Ignore extra messages.
                    if (e.getValueIsAdjusting()) return;
                    ListSelectionModel lsm = (ListSelectionModel)e.getSource();
                    if (lsm.isSelectionEmpty()) {
                        System.out.println("No columns are selected.");
                    } else {
                        int selectedCol = lsm.getMinSelectionIndex();
                        System.out.println("Column " + selectedCol
                                           + " is now selected.");
                    }
                }
            });
        }
        if (DEBUG) {
            table.addMouseListener(new MouseAdapter() {
                public void mouseClicked(MouseEvent e) {
                    printDebugData(table);
                }
            });
        }
        //Create the scroll pane and add the table to it.
        JScrollPane scrollPane = new JScrollPane(table);
        //Add the scroll pane to this panel.
        add(scrollPane);
    }
    private void printDebugData(JTable table) {
        int numRows = table.getRowCount();
        int numCols = table.getColumnCount();
        javax.swing.table.TableModel model = table.getModel();
        System.out.println("Value of data: ");
        for (int i=0; i < numRows; i++) {
            System.out.print("    row " + i + ":");
            for (int j=0; j < numCols; j++) {
                System.out.print("  " + model.getValueAt(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("SimpleTableSelectionDemo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //Create and set up the content pane.
        SimpleTableSelectionDemo newContentPane = new SimpleTableSelectionDemo();
        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();
            }
        });
    }
}





Table with tool tips for both cells and column headers

 
/* 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.
 */
/* 
 * TableToolTipsDemo.java is a 1.4 application that requires no other files.
 */
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import javax.swing.JComponent;
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.JTableHeader;
import javax.swing.table.TableModel;
/**
 * TableToolTipsDemo is just like TableDemo except that it sets up tool tips for
 * both cells and column headers.
 */
public class TableToolTipsDemo extends JPanel {
  private boolean DEBUG = false;
  protected String[] columnToolTips = { null, null,
      "The person"s favorite sport to participate in",
      "The number of years the person has played the sport",
      "If checked, the person eats no meat" };
  public TableToolTipsDemo() {
    super(new GridLayout(1, 0));
    JTable table = new JTable(new MyTableModel()) {
      //Implement table cell tool tips.
      public String getToolTipText(MouseEvent e) {
        String tip = null;
        java.awt.Point p = e.getPoint();
        int rowIndex = rowAtPoint(p);
        int colIndex = columnAtPoint(p);
        int realColumnIndex = convertColumnIndexToModel(colIndex);
        if (realColumnIndex == 2) { //Sport column
          tip = "This person"s favorite sport to "
              + "participate in is: "
              + getValueAt(rowIndex, colIndex);
        } else if (realColumnIndex == 4) { //Veggie column
          TableModel model = getModel();
          String firstName = (String) model.getValueAt(rowIndex, 0);
          String lastName = (String) model.getValueAt(rowIndex, 1);
          Boolean veggie = (Boolean) model.getValueAt(rowIndex, 4);
          if (Boolean.TRUE.equals(veggie)) {
            tip = firstName + " " + lastName + " is a vegetarian";
          } else {
            tip = firstName + " " + lastName
                + " is not a vegetarian";
          }
        } else {
          //You can omit this part if you know you don"t
          //have any renderers that supply their own tool
          //tips.
          tip = super.getToolTipText(e);
        }
        return tip;
      }
      //Implement table header tool tips.
      protected JTableHeader createDefaultTableHeader() {
        return new JTableHeader(columnModel) {
          public String getToolTipText(MouseEvent e) {
            String tip = null;
            java.awt.Point p = e.getPoint();
            int index = columnModel.getColumnIndexAtX(p.x);
            int realIndex = columnModel.getColumn(index)
                .getModelIndex();
            return columnToolTips[realIndex];
          }
        };
      }
    };
    table.setPreferredScrollableViewportSize(new Dimension(500, 70));
    //Create the scroll pane and add the table to it.
    JScrollPane scrollPane = new JScrollPane(table);
    //Add the scroll pane to this panel.
    add(scrollPane);
  }
  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 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("TableToolTipsDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    //Create and set up the content pane.
    JComponent newContentPane = new TableToolTipsDemo();
    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();
      }
    });
  }
}





the last column is moved to the first position

import javax.swing.JTable;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 3;
    int cols = 3;
    JTable table = new JTable(rows, cols);
    table.getTableHeader().setReorderingAllowed(false);
    table.moveColumn(table.getColumnCount() - 1, 0);
  }
}





Toggles the selection state, if it were called again, it exactly reverses the first call.

import javax.swing.JTable;
import javax.swing.ListSelectionModel;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 10;
    int cols = 5;
    JTable table = new JTable(rows, cols);
    table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
    table.setColumnSelectionAllowed(true);
    table.setRowSelectionAllowed(true);
    boolean toggle = true;
    boolean extend = false;
    table.changeSelection(1, 3, toggle, extend);
  }
}





Use a regexFilter to filter table content

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.regex.PatternSyntaxException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.RowFilter;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public class Main {
  public static void main(String args[]) {
    JFrame frame = new JFrame("Sorting JTable");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    MyTableModel model = new MyTableModel();
    JTable table = new JTable(model);
    final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
    table.setRowSorter(sorter);
    JScrollPane pane = new JScrollPane(table);
    frame.add(pane, BorderLayout.CENTER);
    JPanel panel = new JPanel(new BorderLayout());
    JLabel label = new JLabel("Filter");
    panel.add(label, BorderLayout.WEST);
    final JTextField filterText = new JTextField("Y");
    panel.add(filterText, BorderLayout.CENTER);
    frame.add(panel, BorderLayout.NORTH);
    JButton button = new JButton("Filter");
    button.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        String text = filterText.getText();
        try {
          sorter.setRowFilter(RowFilter.regexFilter(text));
        } catch (PatternSyntaxException pse) {
          System.err.println("Bad regex pattern");
        }
      }
    });
    frame.add(button, BorderLayout.SOUTH);
    frame.setSize(300, 250);
    frame.setVisible(true);
  }
}
class MyTableModel extends DefaultTableModel {
  Object rows[][] = { { "A", "A", 1 }, { "E", "E", 4 }, { "Y", "Y", 3 } };
  String columns[] = { "Symbol", "Name", "Price" };
  public Class getColumnClass(int column) {
    Class returnValue;
    if ((column >= 0) && (column < getColumnCount())) {
      returnValue = getValueAt(0, column).getClass();
    } else {
      returnValue = Object.class;
    }
    return returnValue;
  }
}