Java/Swing JFC/Table Column
Версия от 18:01, 31 мая 2010; (обсуждение)
Содержание
- 1 A row header column with the TableColumnModel
- 2 Combine TableModel and ColumModel
- 3 Disable auto resizing, Set the first visible column to 100 pixels wide
- 4 Frozen Column Table Header
- 5 Get column count
- 6 Get the columns from TableColumnModel in the order that they appear in the view
- 7 Install Table Column to TableColumnModel
- 8 JTable with a custom column model
- 9 Locking the Width of a Column in a JTable Component
- 10 Multiline table header
- 11 Packing a Column of a JTable Component according to the header text
- 12 Packing a Column of a JTable Component according to the row data
- 13 Returns the TableColumn associated with the specified column index in the model
- 14 Row Number Table Header
- 15 Set column width based on cell renderer
- 16 Set table column auto-resize off
- 17 Setting the Column Resize Mode of a JTable Component: Disable auto resizing
- 18 Setting the Width of a Column in a JTable Component
- 19 Swing Table Column ToolTip Sample
- 20 Table ColumnModel and TableColumnModelListener
- 21 Table header: Label Header with icon
- 22 Table Headerless Sample
- 23 When the width of a column is changed, all columns to the right are resized
- 24 When the width of a column is changed, only the columns to the left and right of the margin change
- 25 When the width of a column is changed, the width of the right-most column is changed
- 26 When the width of a column is changed, the widths of all columns are changed
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);
}
}