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

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

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

A row header column with the TableColumnModel

 
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O"Reilly 
*/
// RowHeaderTable.java
//A simple application that demonstrates the use of the TableColumnModel
//class to build a row header column that scrolls with the regular data
//rows.
//
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JViewport;
import javax.swing.ScrollPaneConstants;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
public class RowHeaderTable extends JFrame {
  public RowHeaderTable() {
    super("Row Header Test");
    setSize(300, 200);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    TableModel tm = new AbstractTableModel() {
      String data[] = { "", "a", "b", "c", "d", "e" };
      String headers[] = { "Row #", "Column 1", "Column 2", "Column 3",
          "Column 4", "Column 5" };
      public int getColumnCount() {
        return data.length;
      }
      public int getRowCount() {
        return 1000;
      }
      public String getColumnName(int col) {
        return headers[col];
      }
      // Synthesize some entries using the data values & the row #
      public Object getValueAt(int row, int col) {
        return data[col] + row;
      }
    };
    // Create a column model for the main table. This model ignores the
    // first
    // column added, and sets a minimum width of 150 pixels for all others.
    TableColumnModel cm = new DefaultTableColumnModel() {
      boolean first = true;
      public void addColumn(TableColumn tc) {
        // Drop the first column . . . that"ll be the row header
        if (first) {
          first = false;
          return;
        }
        tc.setMinWidth(150); // just for looks, really...
        super.addColumn(tc);
      }
    };
    // Create a column model that will serve as our row header table. This
    // model picks a maximum width and only stores the first column.
    TableColumnModel rowHeaderModel = new DefaultTableColumnModel() {
      boolean first = true;
      public void addColumn(TableColumn tc) {
        if (first) {
          tc.setMaxWidth(tc.getPreferredWidth());
          super.addColumn(tc);
          first = false;
        }
        // Drop the rest of the columns . . . this is the header column
        // only
      }
    };
    JTable jt = new JTable(tm, cm);
    // Set up the header column and get it hooked up to everything
    JTable headerColumn = new JTable(tm, rowHeaderModel);
    jt.createDefaultColumnsFromModel();
    headerColumn.createDefaultColumnsFromModel();
    // Make sure that selections between the main table and the header stay
    // in sync (by sharing the same model)
    jt.setSelectionModel(headerColumn.getSelectionModel());
    // Make the header column look pretty
    //headerColumn.setBorder(BorderFactory.createEtchedBorder());
    headerColumn.setBackground(Color.lightGray);
    headerColumn.setColumnSelectionAllowed(false);
    headerColumn.setCellSelectionEnabled(false);
    // Put it in a viewport that we can control a bit
    JViewport jv = new JViewport();
    jv.setView(headerColumn);
    jv.setPreferredSize(headerColumn.getMaximumSize());
    // With out shutting off autoResizeMode, our tables won"t scroll
    // correctly (horizontally, anyway)
    jt.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    // We have to manually attach the row headers, but after that, the
    // scroll
    // pane keeps them in sync
    JScrollPane jsp = new JScrollPane(jt);
    jsp.setRowHeader(jv);
    jsp.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER, headerColumn
        .getTableHeader());
    getContentPane().add(jsp, BorderLayout.CENTER);
  }
  public static void main(String args[]) {
    RowHeaderTable rht = new RowHeaderTable();
    rht.setVisible(true);
  }
}





Combine TableModel and ColumModel

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





Disable auto resizing, Set the first visible column to 100 pixels wide

import javax.swing.JTable;
import javax.swing.table.TableColumn;
public class Main {
  public static void main(String[] argv) {
    int rows = 3;
    int cols = 3;
    JTable table = new JTable(rows, cols);
    // 
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);    
    TableColumn col = table.getColumnModel().getColumn(0);
    int width = 100;
    col.setPreferredWidth(width);
  }
}





Frozen Column Table Header

 
 
 
import java.awt.ruponent;
import java.awt.Dimension;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class FrozenColumnHeader extends JScrollPane {
  protected JTable mainTable;
  protected JTable headerTable;
  protected int columnCount;
  public FrozenColumnHeader(JTable table, int columns) {
    super();
    mainTable = table;
    headerTable = new JTable(mainTable.getModel());
    getViewport().setView(headerTable);
    columnCount = columns;
  }
  public void addNotify() {
    TableColumn column;
    super.addNotify();
    TableColumnModel mainModel = mainTable.getColumnModel();
    TableColumnModel headerModel = new DefaultTableColumnModel();
    int frozenWidth = 0;
    for (int i = 0; i < columnCount; i++) {
      column = mainModel.getColumn(0);
      mainModel.removeColumn(column);
      headerModel.addColumn(column);
      frozenWidth += column.getPreferredWidth() + headerModel.getColumnMargin();
    }
    headerTable.setColumnModel(headerModel);
    Component columnHeader = getColumnHeader().getView();
    getColumnHeader().setView(null);
    JScrollPane mainScrollPane = (JScrollPane) SwingUtilities.getAncestorOfClass(JScrollPane.class, mainTable);
    mainScrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, new JLabel("..."));
    
    headerTable.setPreferredScrollableViewportSize(new Dimension(frozenWidth, 0));
  }
}





Get column count

import java.util.Enumeration;
import javax.swing.JTable;
import javax.swing.table.TableColumn;
public class Main {
  public static void main(String[] argv) throws Exception {
  }
  public TableColumn[] getColumnsInView(JTable table) {
    TableColumn[] result = new TableColumn[table.getColumnCount()];
    // Use a for loop
    for (int c = 0; c < table.getColumnCount(); c++) {
      result[c] = table.getColumnModel().getColumn(c);
    }
    return result;
  }
}





Get the columns from TableColumnModel in the order that they appear in the view

import java.util.Enumeration;
import javax.swing.JTable;
import javax.swing.table.TableColumn;
public class Main {
  public static void main(String[] argv) throws Exception {
  }
  public TableColumn[] getColumnsInView(JTable table) {
    TableColumn[] result = new TableColumn[table.getColumnCount()];
    // Use an enumeration
    Enumeration e = table.getColumnModel().getColumns();
    for (int i = 0; e.hasMoreElements(); i++) {
      result[i] = (TableColumn) e.nextElement();
    }
    return result;
  }
}





Install Table Column to TableColumnModel

 
import java.awt.BorderLayout;
import javax.swing.DefaultListSelectionModel;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
public class TableColumnTester {
  public static void main(String args[]) {
    Object rows[][] = { { "one", "ichi" }, { "two", "ni" },
        { "three", "san" }, { "four", "shi" }, { "five", "go" },
        { "six", "roku" }, { "seven", "shichi" }, { "eight", "hachi" },
        { "nine", "kyu" }, { "ten", "ju" } };
    Object headers[] = { "English", "Japanese" };
    String title = (args.length == 0 ? "JTable Sample" : args[0]);
    JFrame frame = new JFrame(title);
    TableModel model = new DefaultTableModel(rows, headers);
    TableColumnModel columnModel = new DefaultTableColumnModel();
    TableColumn firstColumn = new TableColumn(1);
    firstColumn.setHeaderValue(headers[1]);
    columnModel.addColumn(firstColumn);
    TableColumn secondColumn = new TableColumn(0);
    secondColumn.setHeaderValue(headers[0]);
    columnModel.addColumn(secondColumn);
    ListSelectionModel selectionModel = new DefaultListSelectionModel();
    selectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    //    JTable table = new JTable(model, columnModel, selectionModel);
    JTable table = new JTable(rows, headers);
    JScrollPane scrollPane = new JScrollPane(table);
    frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}





JTable with a custom column model

 
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
public class ColumnExample extends JFrame {
  public ColumnExample() {
    super("Abstract Model JTable Test");
    setSize(300, 200);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    DefaultTableModel dtm = new DefaultTableModel(new String[][] {
        { "1", "2", "3" }, { "4", "5", "6" } }, new String[] { "Names",
        "In", "Order" });
    SortingColumnModel scm = new SortingColumnModel();
    JTable jt = new JTable(dtm, scm);
    jt.createDefaultColumnsFromModel();
    JScrollPane jsp = new JScrollPane(jt);
    getContentPane().add(jsp, BorderLayout.CENTER);
  }
  public static void main(String args[]) {
    ColumnExample ce = new ColumnExample();
    ce.setVisible(true);
  }
}
class SortingColumnModel extends DefaultTableColumnModel {
  public void addColumn(TableColumn tc) {
    super.addColumn(tc);
    int newIndex = sortedIndexOf(tc);
    if (newIndex != tc.getModelIndex()) {
      moveColumn(tc.getModelIndex(), newIndex);
    }
  }
  protected int sortedIndexOf(TableColumn tc) {
    // just do a linear search for now
    int stop = getColumnCount();
    String name = tc.getHeaderValue().toString();
    for (int i = 0; i < stop; i++) {
      if (name.rupareTo(getColumn(i).getHeaderValue().toString()) <= 0) {
        return i;
      }
    }
    return stop;
  }
}





Locking the Width of a Column in a JTable Component

import javax.swing.JTable;
import javax.swing.table.TableColumn;
public class Main {
  public static void main(String[] argv) throws Exception {
    int rows = 3;
    int cols = 3;
    JTable table = new JTable(rows, cols);
    TableColumn col = table.getColumnModel().getColumn(0);
    col.setMinWidth(100);
    col.setMaxWidth(100);
    col.setPreferredWidth(100);
  }
}





Multiline table header

 
 
 

import java.awt.BorderLayout;
import java.awt.ruponent;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.NumberFormat;
import java.util.Calendar;
import java.util.EventObject;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.StringTokenizer;
import java.util.TreeSet;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.LookAndFeel;
import javax.swing.SwingConstants;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.EventListenerList;
import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;
class SortedTableModel extends AbstractTableModel {
  protected TableModel sourceModel;
  protected int[] indexValues;
  public SortedTableModel(TableModel model) {
    super();
    sourceModel = model;
  }
  public int getRowCount() {
    return sourceModel.getRowCount();
  }
  public int getColumnCount() {
    return sourceModel.getColumnCount();
  }
  public Object getValueAt(int row, int column) {
    if (indexValues != null) {
      row = getSourceIndex(row);
    }
    return sourceModel.getValueAt(row, column);
  }
  public void setValueAt(Object value, int row, int column) {
    if (indexValues != null) {
      row = getSourceIndex(row);
    }
    sourceModel.setValueAt(value, row, column);
  }
  public boolean isCellEditable(int row, int column) {
    return sourceModel.isCellEditable(row, column);
  }
  public String getColumnName(int column) {
    return sourceModel.getColumnName(column);
  }
  public Class getColumnClass(int column) {
    return sourceModel.getColumnClass(column);
  }
  public int getSourceIndex(int index) {
    if (indexValues != null) {
      return indexValues[index];
    }
    return -1;
  }
  public void sortRows(int column, boolean ascending) {
    fireTableDataChanged();
  }
  public void clearSort() {
    indexValues = null;
    fireTableDataChanged();
  }
}

class SortedColumnHeaderRenderer implements TableCellRenderer {
  protected TableCellRenderer textRenderer;
  protected SortedTableModel sortedModel;
  protected int sortColumn = -1;
  protected boolean sortAscending = true;
  public SortedColumnHeaderRenderer(SortedTableModel model,
      TableCellRenderer renderer) {
    sortedModel = model;
    textRenderer = renderer;
  }
  public SortedColumnHeaderRenderer(SortedTableModel model) {
    this(model, null);
  }
  public Component getTableCellRendererComponent(JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) {
    Component text;
    JPanel panel = new JPanel();
    panel.setLayout(new BorderLayout());
    if (textRenderer != null) {
      text = textRenderer.getTableCellRendererComponent(table, value,
          isSelected, hasFocus, row, column);
    } else {
      text = new JLabel((String) value, JLabel.CENTER);
      LookAndFeel.installColorsAndFont((JComponent) text,
          "TableHeader.background", "TableHeader.foreground",
          "TableHeader.font");
    }
    panel.add(text, BorderLayout.CENTER);
    if (column == sortColumn) {
      BasicArrowButton bab = new BasicArrowButton(
          (sortAscending ? SwingConstants.NORTH : SwingConstants.SOUTH));
      panel.add(bab, BorderLayout.WEST);
    }
    LookAndFeel.installBorder(panel, "TableHeader.cellBorder");
    return panel;
  }
  public void columnSelected(int column) {
    if (column != sortColumn) {
      sortColumn = column;
      sortAscending = true;
    } else {
      sortAscending = !sortAscending;
      if (sortAscending)
        sortColumn = -1;
    }
    if (sortColumn != -1) {
      sortedModel.sortRows(sortColumn, sortAscending);
    } else {
      sortedModel.clearSort();
    }
  }
}
class TableValues extends AbstractTableModel {
  public final static int FIRST_NAME = 0;
  public final static int LAST_NAME = 1;
  public final static int DATE_OF_BIRTH = 2;
  public final static int ACCOUNT_BALANCE = 3;
  public final static int GENDER = 4;
  public final static boolean GENDER_MALE = true;
  public final static boolean GENDER_FEMALE = false;
  public final static String[] columnNames = { "First\nName", "Last\nName",
      "Date of\nBirth", "Account\nBalance", "Gender" };
  public Object[][] values = {
      { "A", "B",
          new GregorianCalendar(1962, Calendar.FEBRUARY, 20).getTime(),
          new Float(12345.67), new Boolean(GENDER_MALE) },
      { "C", "D",
          new GregorianCalendar(1987, Calendar.JANUARY, 6).getTime(),
          new Float(23456.78), new Boolean(GENDER_MALE) },
      { "E", "F",
          new GregorianCalendar(1989, Calendar.AUGUST, 31).getTime(),
          new Float(34567.89), new Boolean(GENDER_FEMALE) },
      { "G", "H",
          new GregorianCalendar(1945, Calendar.JANUARY, 16).getTime(),
          new Float(-456.70), new Boolean(GENDER_FEMALE) },
      { "I", "J",
          new GregorianCalendar(1907, Calendar.AUGUST, 2).getTime(),
          new Float(567.00), new Boolean(GENDER_FEMALE) } };
  public int getRowCount() {
    return values.length;
  }
  public int getColumnCount() {
    return values[0].length;
  }
  public Object getValueAt(int row, int column) {
    return values[row][column];
  }
  public String getColumnName(int column) {
    return columnNames[column];
  }
  public Class getColumnClass(int column) {
    Class dataType = super.getColumnClass(column);
    if (column == ACCOUNT_BALANCE) {
      dataType = Float.class;
    } else if (column == DATE_OF_BIRTH) {
      dataType = java.util.Date.class;
    } else if ((column == FIRST_NAME) || (column == LAST_NAME)) {
      dataType = String.class;
    } else if (column == GENDER) {
      dataType = Boolean.class;
    }
    return dataType;
  }
  public boolean isCellEditable(int row, int column) {
    if (column == GENDER) {
      return true;
    }
    return false;
  }
  public void setValueAt(Object value, int row, int column) {
    values[row][column] = value;
  }
}
public class SimpleTableTestMultilineHeader extends JFrame {
  protected JTable table;
  protected SortedColumnHeaderRenderer renderer;
  public static void main(String[] args) {
    SimpleTableTestMultilineHeader stt = new SimpleTableTestMultilineHeader();
    stt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    stt.setSize(400, 200);
    stt.setVisible(true);
  }
  public SimpleTableTestMultilineHeader() {
    Container pane = getContentPane();
    pane.setLayout(new BorderLayout());
    TableValues tv = new TableValues();
    SortedTableModel stm = new SortedTableModel(tv);
    stm.sortRows(TableValues.ACCOUNT_BALANCE, true);
    table = new JTable(stm);
    table.setRowSelectionAllowed(false);
    table.setColumnSelectionAllowed(true);
    TableColumnModel tcm = table.getColumnModel();
    TableColumn tc = tcm.getColumn(TableValues.GENDER);
    MultiLineHeaderRenderer mlhr = new MultiLineHeaderRenderer();
    tc = tcm.getColumn(TableValues.ACCOUNT_BALANCE);
    tc.setHeaderRenderer(mlhr);
    renderer = new SortedColumnHeaderRenderer(stm, mlhr);
    int count = tcm.getColumnCount();
    for (int i = 0; i < count; i++) {
      tc = tcm.getColumn(i);
      tc.setHeaderRenderer(renderer);
    }
    JTableHeaderToolTips jthtt = new JTableHeaderToolTips(table
        .getColumnModel());
    jthtt.setToolTips(new String[] { "Customer"s First Name",
        "Customer"s Last Name", "Customer"s Date of Birth",
        "Customer"s Account Balance", "Customer"s Gender" });
    table.setTableHeader(jthtt);
    JScrollPane jsp = new JScrollPane(table);
    pane.add(jsp, BorderLayout.CENTER);
    addHeaderListener();
  }
  public void addHeaderListener() {
    table.getTableHeader().addMouseListener(new MouseAdapter() {
      public void mousePressed(MouseEvent event) {
        JTableHeader header = (JTableHeader) (event.getSource());
        int index = header.columnAtPoint(event.getPoint());
        Class dataType = table.getModel().getColumnClass(index);
        Class[] interfaces = dataType.getInterfaces();
        for (int i = 0; i < interfaces.length; i++) {
          if (interfaces[i].equals(java.lang.ruparable.class)) {
            renderer.columnSelected(index);
            break;
          }
        }
        table.setColumnSelectionInterval(index, index);
      }
    });
  }
}
class JTableHeaderToolTips extends JTableHeader {
  protected String[] toolTips;
  public JTableHeaderToolTips(TableColumnModel tcm) {
    super(tcm);
  }
  public void setToolTips(String[] tips) {
    toolTips = tips;
  }
  public String getToolTipText(MouseEvent event) {
    String tip = super.getToolTipText(event);
    int column = columnAtPoint(event.getPoint());
    if ((toolTips != null) && (column < toolTips.length)
        && (toolTips[column] != null)) {
      tip = toolTips[column];
    }
    return tip;
  }
}
class MultiLineHeaderRenderer extends JPanel implements TableCellRenderer {
  public Component getTableCellRendererComponent(JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) {
    JLabel label;
    removeAll();
    String[] header = ((String) value).split("\n");
    setLayout(new GridLayout(header.length, 1));
    for(String s: header){
      label = new JLabel(s, JLabel.CENTER);
      LookAndFeel.installColorsAndFont(label, "TableHeader.background",
          "TableHeader.foreground", "TableHeader.font");
      add(label);
    }
    LookAndFeel.installBorder(this, "TableHeader.cellBorder");
    return this;
  }
}





Packing a Column of a JTable Component according to the header text

import java.awt.ruponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class Main {
  public Main() {
    JTable table = new JTable(3, 3);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    for(int i=0;i<table.getColumnCount();i++){
      DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel();
      TableColumn col = colModel.getColumn(i);
      int width = 0;
      TableCellRenderer renderer = col.getHeaderRenderer();
      if (renderer == null) {
        renderer = table.getTableHeader().getDefaultRenderer();
      }
      Component comp = renderer.getTableCellRendererComponent(table, col.getHeaderValue(), false,
          false, 0, 0);
      width = comp.getPreferredSize().width;
      col.setPreferredWidth(width+2);
    }
    JFrame f = new JFrame();
    f.add(new JScrollPane(table));
    f.setSize(300, 300);
    f.setVisible(true);
  }
  public static void main(String[] argv) {
    new Main();
  }
}





Packing a Column of a JTable Component according to the row data

import java.awt.ruponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class Main {
  public Main() {
    JTable table = new JTable(3, 3);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    for (int i = 0; i < table.getColumnCount(); i++) {
      DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel();
      TableColumn col = colModel.getColumn(i);
      int width = 0;
      TableCellRenderer renderer = col.getHeaderRenderer();
      for (int r = 0; r < table.getRowCount(); r++) {
        renderer = table.getCellRenderer(r, i);
        Component comp = renderer.getTableCellRendererComponent(table, table.getValueAt(r, i),
            false, false, r, i);
        width = Math.max(width, comp.getPreferredSize().width);
      }
      col.setPreferredWidth(width + 2);
    }
    JFrame f = new JFrame();
    f.add(new JScrollPane(table));
    f.setSize(300, 300);
    f.setVisible(true);
  }
  public static void main(String[] argv) {
    new Main();
  }
}





Returns the TableColumn associated with the specified column index in the model

import java.util.Enumeration;
import javax.swing.JTable;
import javax.swing.table.TableColumn;
public class Main {
  public static void main(String[] argv) throws Exception {
  }
  public TableColumn findTableColumn(JTable table, int columnModelIndex) {
    Enumeration e = table.getColumnModel().getColumns();
    for (; e.hasMoreElements();) {
      TableColumn col = (TableColumn) e.nextElement();
      if (col.getModelIndex() == columnModelIndex) {
        return col;
      }
    }
    return null;
  }
}





Row Number Table Header

 
 
 
 
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.LookAndFeel;
import javax.swing.table.AbstractTableModel;
public class RowNumberHeader extends JTable {
  protected JTable mainTable;
  public RowNumberHeader(JTable table) {
    super();
    mainTable = table;
    setModel(new RowNumberTableModel());
    setPreferredScrollableViewportSize(getMinimumSize());
    setRowSelectionAllowed(false);
    JComponent renderer = (JComponent) getDefaultRenderer(Object.class);
    LookAndFeel.installColorsAndFont(renderer, "TableHeader.background",
        "TableHeader.foreground", "TableHeader.font");
    LookAndFeel.installBorder(this, "TableHeader.cellBorder");
  }
  public int getRowHeight(int row) {
    return mainTable.getRowHeight();
  }
  class RowNumberTableModel extends AbstractTableModel {
    public int getRowCount() {
      return mainTable.getModel().getRowCount();
    }
    public int getColumnCount() {
      return 1;
    }
    public Object getValueAt(int row, int column) {
      return new Integer(row + 1);
    }
  }
  public static void main(String[] a) {
    JFrame f = new JFrame();
    f.add(new RowNumberHeader(new JTable(3, 4)));
    f.setSize(300, 300);
    f.setVisible(true);
  }
}





Set column width based on cell renderer

import java.awt.ruponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class Main {
  public Main() {
    JTable table = new JTable(3, 3);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    for (int i = 0; i < table.getColumnCount(); i++) {
      DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel();
      TableColumn col = colModel.getColumn(i);
      int width = 0;
      TableCellRenderer renderer = col.getHeaderRenderer();
      for (int r = 0; r < table.getRowCount(); r++) {
        renderer = table.getCellRenderer(r, i);
        Component comp = renderer.getTableCellRendererComponent(table, table.getValueAt(r, i),
            false, false, r, i);
        width = Math.max(width, comp.getPreferredSize().width);
      }
      col.setPreferredWidth(width + 2);
    }
    JFrame f = new JFrame();
    f.add(new JScrollPane(table));
    f.setSize(300, 300);
    f.setVisible(true);
  }
  public static void main(String[] argv) {
    new Main();
  }
}





Set table column auto-resize off

import java.awt.ruponent;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
public class Main {
  public Main() {
    JTable table = new JTable(3, 3);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    for(int i=0;i<table.getColumnCount();i++){
      DefaultTableColumnModel colModel = (DefaultTableColumnModel) table.getColumnModel();
      TableColumn col = colModel.getColumn(i);
      int width = 0;
      TableCellRenderer renderer = col.getHeaderRenderer();
      if (renderer == null) {
        renderer = table.getTableHeader().getDefaultRenderer();
      }
      Component comp = renderer.getTableCellRendererComponent(table, col.getHeaderValue(), false,
          false, 0, 0);
      width = comp.getPreferredSize().width;
      col.setPreferredWidth(width+2);      
    }    
    JFrame f = new JFrame();
    f.add(new JScrollPane(table));
    f.setSize(300, 300);
    f.setVisible(true);
  }
  public static void main(String[] argv) {
    new Main();
  }
}





Setting the Column Resize Mode of a JTable Component: Disable auto resizing

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);
    
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
  }
}





Setting the Width of a Column in a JTable Component

import javax.swing.JTable;
import javax.swing.table.TableColumn;
public class Main {
  public static void main(String[] argv) {
    int rows = 3;
    int cols = 3;
    JTable table = new JTable(rows, cols);
    // 
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);    
    TableColumn col = table.getColumnModel().getColumn(0);
    int width = 100;
    col.setPreferredWidth(width);
  }
}





Swing Table Column ToolTip Sample

 
/*
Definitive Guide to Swing for Java 2, Second Edition
By John Zukowski     
ISBN: 1-893115-78-X
Publisher: APress
*/
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class SwingToolTipSample {
  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("Tooltip Sample");
    JTable table = new JTable(rows, headers);
    JLabel headerRenderer = new DefaultTableCellRenderer();
    String columnName = table.getModel().getColumnName(0);
    headerRenderer.setText(columnName);
    headerRenderer.setToolTipText("Wave");
    TableColumnModel columnModel = table.getColumnModel();
    TableColumn englishColumn = columnModel.getColumn(0);
    englishColumn.setHeaderRenderer((TableCellRenderer) headerRenderer);
    JScrollPane scrollPane = new JScrollPane(table);
    frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}





Table ColumnModel and TableColumnModelListener

 
/*
Definitive Guide to Swing for Java 2, Second Edition
By John Zukowski     
ISBN: 1-893115-78-X
Publisher: APress
*/
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.event.TableColumnModelListener;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class ColumnModelSample {
  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);
    TableColumnModelListener tableColumnModelListener = new TableColumnModelListener() {
      public void columnAdded(TableColumnModelEvent e) {
        System.out.println("Added");
      }
      public void columnMarginChanged(ChangeEvent e) {
        System.out.println("Margin");
      }
      public void columnMoved(TableColumnModelEvent e) {
        System.out.println("Moved");
      }
      public void columnRemoved(TableColumnModelEvent e) {
        System.out.println("Removed");
      }
      public void columnSelectionChanged(ListSelectionEvent e) {
        System.out.println("Selection Changed");
      }
    };
    TableColumnModel columnModel = table.getColumnModel();
    columnModel.addColumnModelListener(tableColumnModelListener);
    columnModel.setColumnMargin(12);
    TableColumn column = new TableColumn(1);
    columnModel.addColumn(column);
    frame.getContentPane().add(table, BorderLayout.CENTER);
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}





Table header: Label Header with icon

 
/*
Definitive Guide to Swing for Java 2, Second Edition
By John Zukowski     
ISBN: 1-893115-78-X
Publisher: APress
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.ruponent;
import java.awt.Graphics;
import java.awt.Polygon;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
public class LabelHeaderSample {
  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" } };
    JFrame frame = new JFrame("Label Header");
    String headers[] = { "English", "Japanese" };
    JTable table = new JTable(rows, headers);
    JScrollPane scrollPane = new JScrollPane(table);
    Icon redIcon = new DiamondIcon(Color.red);
    Icon blueIcon = new DiamondIcon(Color.blue);
    Border headerBorder = UIManager.getBorder("TableHeader.cellBorder");
    JLabel blueLabel = new JLabel(headers[0], blueIcon, JLabel.CENTER);
    blueLabel.setBorder(headerBorder);
    JLabel redLabel = new JLabel(headers[1], redIcon, JLabel.CENTER);
    redLabel.setBorder(headerBorder);
    TableCellRenderer renderer = new JComponentTableCellRenderer();
    TableColumnModel columnModel = table.getColumnModel();
    TableColumn column0 = columnModel.getColumn(0);
    TableColumn column1 = columnModel.getColumn(1);
    column0.setHeaderRenderer(renderer);
    column0.setHeaderValue(blueLabel);
    column1.setHeaderRenderer(renderer);
    column1.setHeaderValue(redLabel);
    frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
}
class DiamondIcon implements Icon {
  private Color color;
  private boolean selected;
  private int width;
  private int height;
  private Polygon poly;
  private static final int DEFAULT_WIDTH = 10;
  private static final int DEFAULT_HEIGHT = 10;
  public DiamondIcon(Color color) {
    this(color, true, DEFAULT_WIDTH, DEFAULT_HEIGHT);
  }
  public DiamondIcon(Color color, boolean selected) {
    this(color, selected, DEFAULT_WIDTH, DEFAULT_HEIGHT);
  }
  public DiamondIcon(Color color, boolean selected, int width, int height) {
    this.color = color;
    this.selected = selected;
    this.width = width;
    this.height = height;
    initPolygon();
  }
  private void initPolygon() {
    poly = new Polygon();
    int halfWidth = width / 2;
    int halfHeight = height / 2;
    poly.addPoint(0, halfHeight);
    poly.addPoint(halfWidth, 0);
    poly.addPoint(width, halfHeight);
    poly.addPoint(halfWidth, height);
  }
  public int getIconHeight() {
    return height;
  }
  public int getIconWidth() {
    return width;
  }
  public void paintIcon(Component c, Graphics g, int x, int y) {
    g.setColor(color);
    g.translate(x, y);
    if (selected) {
      g.fillPolygon(poly);
    } else {
      g.drawPolygon(poly);
    }
    g.translate(-x, -y);
  }
}
class JComponentTableCellRenderer implements TableCellRenderer {
  public Component getTableCellRendererComponent(JTable table, Object value,
      boolean isSelected, boolean hasFocus, int row, int column) {
    return (JComponent) value;
  }
}





Table Headerless Sample

 
import java.awt.BorderLayout;
import java.awt.Container;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JViewport;
import javax.swing.UIManager;
public class HeaderlessSample {
  public static void main(String args[]) {
    Object rowData[][] = {
        { "Row1-Column1", "Row1-Column2", "Row1-Column3" },
        { "Row2-Column1", "Row2-Column2", "Row2-Column3" } };
    Object columnNames[] = { "Column 1", "Column 2", "Column 3" };
    //    JTable table = new HeaderlessTable(rowData, columnNames);
    JTable table = new JTable(rowData, columnNames);
    table.setTableHeader(null);
    JScrollPane scrollPane = new JScrollPane(table);
    //    scrollPane.setColumnHeaderView(null);
    JFrame frame = new JFrame("Headerless Table");
    frame.getContentPane().add(scrollPane, BorderLayout.CENTER);
    frame.setSize(300, 150);
    frame.setVisible(true);
  }
  static class HeaderlessTable extends JTable {
    public HeaderlessTable(Object rowData[][], Object columnNames[]) {
      super(rowData, columnNames);
    }
    protected void configureEnclosingScrollPane() {
      Container container = getParent();
      if (container instanceof JViewport) {
        Container viewParent = container.getParent();
        if (viewParent instanceof JScrollPane) {
          JScrollPane scrollPane = (JScrollPane) viewParent;
          JViewport viewport = scrollPane.getViewport();
          if (viewport == null || viewport.getView() != this) {
            return;
          }
          // scrollPane.setColumnHeaderView(getTableHeader());
          scrollPane.setBorder(UIManager
              .getBorder("Table.scrollPaneBorder"));
        }
      }
    }
  }
}





When the width of a column is changed, all columns to the right are resized

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);
    
    table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
  }
}





When the width of a column is changed, only the columns to the left and right of the margin change

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);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
  }
}





When the width of a column is changed, the width of the right-most column is changed

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);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
  }
}





When the width of a column is changed, the widths of all columns are changed

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

    table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
  }
}