第19章 表格

本文涉及的产品
网络型负载均衡 NLB,每月750个小时 15LCU
应用型负载均衡 ALB,每月750个小时 15LCU
简介: 第19章 表格 19.1 表格和滚动 例19-1 表格和滚动窗格 import javax.swing.*;import java.awt.

19章 表格

19.1 表格和滚动

19-1 表格和滚动窗格

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Test extends JFrame {
public Test() {
Container contentPane = getContentPane();

contentPane.setLayout(new FlowLayout());
contentPane.add(new JTable(10,10));
contentPane.add(new JScrollPane(new JTable(10,10)));
}
public static void main(String args[]) {
GraphicJavaWindowHandler.launch(new Test(),
"Tables and Scrollpanes",100,100,850,700);
}
}
class GraphicJavaWindowHandler extends WindowAdapter {
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
}

19.2 表格模型

 

 

19.2.1 表格数据模型

 

 

19.2.2 TableModel接口

 

 

19.2.3 AbstractTableModel

 

19-2 AbstractTableModel的一个简单扩展

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import java.util.*;

public class Test extends JFrame {
JTable table = new JTable(
new AbstractTableModel() {
int rows = 100, cols = 10;

public int getRowCount() { return rows; }
public int getColumnCount() { return cols; }

public Object getValueAt(int row, int col) {
return "(" + row + "," + col + ")";
}
});

public Test() {
getContentPane().add(new JScrollPane(table),
BorderLayout.CENTER);
}
public static void main(String args[]) {
GJApp.launch(
new Test(), "A Simple Model",300,300,450,300);
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
launch(f,title,x,y,w,h,null);
}
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h,
String propertiesFilename) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

if(propertiesFilename != null) {
resources = ResourceBundle.getBundle(
propertiesFilename, Locale.getDefault());
}

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}

 

19.2.4 DefaultTableModel

 

19-3 使用DefaultTableModel

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import java.util.*;

public class Test extends JFrame {
private int rows=3, cols=5;
private Object[] rowData = new Object[cols];

private DefaultTableModel model = new DefaultTableModel();
private JTable table = new JTable(model);

public Test() {
for(int c=0; c < cols; ++c)
model.addColumn("Column " + Integer.toString(c));

for(int r=0; r < rows; ++r) {
for(int c=0; c < cols; ++c) {
rowData[c] = "(" + r + "," + c + ")";
}
model.addRow(rowData);
}
getContentPane().add(new JScrollPane(table),
BorderLayout.CENTER);
getContentPane().add(new ControlPanel(),
BorderLayout.NORTH);
}
public static void main(String args[]) {
GJApp.launch(new Test(),
"Using DefaultTableModel",150,150,600,350);
}
class ControlPanel extends JPanel {
private JButton rowButton = new JButton("Add Row"),
colButton = new JButton("Add Column");

public ControlPanel() {
add(rowButton);
add(colButton);

rowButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int rowCount = model.getRowCount();
int colCount = model.getColumnCount();

if(colCount > rowData.length)
rowData = new Object[colCount];

for(int c=0; c < colCount; ++c) {
rowData[c] = "(" + rowCount + "," +
c + ")";
}
model.addRow(rowData);
}
});
colButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int colCount = model.getColumnCount();
model.addColumn("Column " + colCount);

// Bug: the call to sizeColumnsToFit()
// should not be necessary
table.sizeColumnsToFit(-1);
}
});
}
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
launch(f,title,x,y,w,h,null);
}
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h,
String propertiesFilename) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

if(propertiesFilename != null) {
resources = ResourceBundle.getBundle(
propertiesFilename, Locale.getDefault());
}

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}

19.2.5 表格模型、缺省绘制器和缺省编辑器

 

19-4 使用缺省绘制器和编辑器

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;

public class Test extends JFrame {
String[] columnNames = {
"Name", "Check-In Date", "Check-Out Date", "Smoking",
"Fax", "Laptop", "Room Rate", "Photo",
};

Date dayOne = (new GregorianCalendar(2000, 10, 5)).getTime();
Date dayTwo = (new GregorianCalendar(2000, 10, 7)).getTime();

Object[][] data = {
{ "Andrews", dayOne, dayTwo,
new Boolean(true), new Boolean(true),
new Boolean(true), new Double(79.99),
new ImageIcon("tenchi.jpg")},

{ "Anthony", dayOne, dayTwo,
new Boolean(false), new Boolean(false),
new Boolean(false), new Double(69.99),
new ImageIcon("washu.jpg")},

{ "Woodard", dayOne, dayTwo,
new Boolean(true), new Boolean(false),
new Boolean(false), new Double(99.99),
new ImageIcon("sasami.jpg")},

{ "Thomas", dayOne, dayTwo,
new Boolean(false), new Boolean(true),
new Boolean(true), new Double(79.99),
new ImageIcon("aeka.jpg")},

{ "Reed", dayOne, dayTwo,
new Boolean(true), new Boolean(true),
new Boolean(true), new Double(79.99),
new ImageIcon("tenchi.jpg")},

{ "Crenshaw", dayOne, dayTwo,
new Boolean(false), new Boolean(false),
new Boolean(false), new Double(69.99),
new ImageIcon("washu.jpg")},

{ "Royal", dayOne, dayTwo,
new Boolean(true), new Boolean(false),
new Boolean(false), new Double(99.99),
new ImageIcon("sasami.jpg")},

{ "Moore", dayOne, dayTwo,
new Boolean(false), new Boolean(true),
new Boolean(true), new Double(79.99),
new ImageIcon("aeka.jpg")},
};

JTable table = new JTable(new CustomModel(data, columnNames));
public Test() {
getContentPane().add(new JScrollPane(table),
BorderLayout.CENTER);
}
public static void main(String args[]) {
GJApp.launch(
new Test(),
"A Custom Table Model That Specifies Column Classes",
300,300,650,182);
}
}
class CustomModel extends DefaultTableModel {
public CustomModel(Object[][] data, Object[] columnNames) {
super(data, columnNames);
}
public Class getColumnClass(int col) {
// dataVector is a protected member of DefaultTableModel

Vector v = (Vector)dataVector.elementAt(0);
return v.elementAt(col).getClass();
}
public boolean isCellEditable(int row, int col) {
Class columnClass = getColumnClass(col);
return columnClass != ImageIcon.class &&
columnClass != Date.class;
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
launch(f,title,x,y,w,h,null);
}
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h,
String propertiesFilename) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

if(propertiesFilename != null) {
resources = ResourceBundle.getBundle(
propertiesFilename, Locale.getDefault());
}

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}

19.3 表格列

 

 

19.3.1 列调整大小模式

 

19-5 JTable调整大小模式

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class Test extends JFrame {
Object[] resizeModes = new Object[] {
"JTable.AUTO_RESIZE_OFF",
"JTable.AUTO_RESIZE_NEXT_COLUMN",
"JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS",
"JTable.AUTO_RESIZE_LAST_COLUMN",
"JTable.AUTO_RESIZE_ALL_COLUMNS",
};
int[] resizeConstants = {
JTable.AUTO_RESIZE_OFF,
JTable.AUTO_RESIZE_NEXT_COLUMN,
JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS,
JTable.AUTO_RESIZE_LAST_COLUMN,
JTable.AUTO_RESIZE_ALL_COLUMNS,
};
JTable table = new JTable(6,5);

public Test() {
Container contentPane = getContentPane();

contentPane.add(new ControlPanel(), BorderLayout.NORTH);
contentPane.add(new JScrollPane(table),
BorderLayout.CENTER);

}
class ControlPanel extends JPanel {
JComboBox resizeModeCombo = new JComboBox(resizeModes);

public ControlPanel() {
initializeCombo();

setBorder(BorderFactory.createTitledBorder(
"Resize Mode"));

setLayout(new FlowLayout(FlowLayout.LEFT,2,2));
add(resizeModeCombo);

resizeModeCombo.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
int index =
resizeModeCombo.getSelectedIndex();

table.setAutoResizeMode(
resizeConstants[index]);
}
});
}
private void initializeCombo() {
int resizeMode = table.getAutoResizeMode();

if(resizeMode == JTable.AUTO_RESIZE_OFF)
resizeModeCombo.setSelectedIndex(0);
else if(resizeMode == JTable.AUTO_RESIZE_NEXT_COLUMN)
resizeModeCombo.setSelectedIndex(1);
else if(resizeMode == JTable.AUTO_RESIZE_LAST_COLUMN)
resizeModeCombo.setSelectedIndex(2);
else if(resizeMode == JTable.AUTO_RESIZE_ALL_COLUMNS)
resizeModeCombo.setSelectedIndex(3);
else if(
resizeMode == JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS)
resizeModeCombo.setSelectedIndex(4);
}
}
public static void main(String args[]) {
GJApp.launch(
new Test(), "JTable Resize Modes", 300,300,425,210);
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
launch(f,title,x,y,w,h,null);
}
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h,
String propertiesFilename) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

if(propertiesFilename != null) {
resources = ResourceBundle.getBundle(
propertiesFilename, Locale.getDefault());
}

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}

 

19.3.2 列宽度

 

19-6 指定列宽度

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import java.util.*;

public class Test extends JFrame {
Object[] columnNames =
{"First Name", "MI", "Last Name"};

Object[][] names = {
{ "Lynn", "M.", "Seckinger" },
{ "Carol", "R.", "Seckinger" },
{ "Roy", "D.", "Martin" },
{ "Bill", "O.", "Veryveryveryverylonglastname" },
{ "Richard", "A.", "Tattersall" },
{ "Philip", "B.", "Edwards" },
{ "Moore", "T.", "Moore" },

// shorten scrollbar grip with these ...
{ "Lynn", "M.", "Seckinger" },
{ "Carol", "R.", "Seckinger" },
{ "Roy", "D.", "Martin" },
{ "Bill", "O.", "Veryveryveryverylonglastname" },
{ "Richard", "A.", "Tattersall" },
{ "Philip", "B.", "Edwards" },
{ "Moore", "T.", "Moore" },
};
JTable table = new JTable(names, columnNames);

public Test() {
TableColumn mid = table.getColumn(columnNames[1]);
TableColumn last = table.getColumn(columnNames[2]);

int midWidth = getPreferredWidthForColumn(mid),
lastWidth = getPreferredWidthForColumn(last);

mid.setMinWidth(midWidth);
mid.setMaxWidth(midWidth);

last.setMinWidth(lastWidth);

// sizeColumnsToFit() must be called due to a JTable
// bug ...
table.sizeColumnsToFit(0);

getContentPane().add(new JScrollPane(table),
BorderLayout.CENTER);
}
public int getPreferredWidthForColumn(TableColumn col) {
int hw = columnHeaderWidth(col), // hw = header width
cw = widestCellInColumn(col); // cw = column width

return hw > cw ? hw : cw;
}
private int columnHeaderWidth(TableColumn col) {
TableCellRenderer renderer = col.getHeaderRenderer();

Component comp = renderer.getTableCellRendererComponent(
table, col.getHeaderValue(),
false, false, 0, 0);

return comp.getPreferredSize().width;
}
private int widestCellInColumn(TableColumn col) {
int c = col.getModelIndex(), width=0, maxw=0;

for(int r=0; r < table.getRowCount(); ++r) {
TableCellRenderer renderer =
table.getCellRenderer(r,c);

Component comp =
renderer.getTableCellRendererComponent(
table, table.getValueAt(r,c),
false, false, r, c);

width = comp.getPreferredSize().width;
maxw = width > maxw ? width : maxw;
}
return maxw;
}
public static void main(String args[]) {
GJApp.launch(
new Test(),"Setting Column Widths",300,300,320,140);
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
launch(f,title,x,y,w,h,null);
}
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h,
String propertiesFilename) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

if(propertiesFilename != null) {
resources = ResourceBundle.getBundle(
propertiesFilename, Locale.getDefault());
}

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}

 

19.4 表格列模型

 

19.4.1 DefaultTableColumnModel

 

 

 

19.4.2 列边距

 

19-7 设置列边距

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.util.*;

public class Test extends JFrame {
JTable table = new JTable(
new AbstractTableModel() {
public int getRowCount() { return 10; }
public int getColumnCount() { return 10; }

public Object getValueAt(int row, int col) {
return "(" + Integer.toString(row) + "," +
Integer.toString(col) + ")";
}
});

public Test() {
Container cp = getContentPane();
cp.add(new JScrollPane(table), BorderLayout.CENTER);
cp.add(new ControlPanel(), BorderLayout.NORTH);
}
class ControlPanel extends JPanel {
private JSlider slider = new JSlider(
JSlider.HORIZONTAL,0,100,
table.getColumnModel().getColumnMargin());

private JLabel label = new JLabel();

public ControlPanel() {
add(new JLabel("Column Margin:"));
add(slider);
add(label);

label.setText(
Integer.toString(
table.getColumnModel().getColumnMargin()));

slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
table.getColumnModel().setColumnMargin(
slider.getValue());
}
});
table.getColumnModel().addColumnModelListener(
new TableColumnModelListener() {
public void columnMarginChanged(ChangeEvent e) {
TableColumnModel m = table.getColumnModel();
label.setText(
Integer.toString(m.getColumnMargin()));
}

// unfortunately, Swing does not have many
// event adapter classes ...
public void columnAdded(TableColumnModelEvent e) {
}
public void columnMoved(TableColumnModelEvent e) {
}
public void columnRemoved(
TableColumnModelEvent e) {
}
public void columnSelectionChanged(
ListSelectionEvent e) {
}
});
}
}
public static void main(String args[]) {
GJApp.launch(new Test(),
"Column Margins",150,150,500,200);
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
launch(f,title,x,y,w,h,null);
}
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h,
String propertiesFilename) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

if(propertiesFilename != null) {
resources = ResourceBundle.getBundle(
propertiesFilename, Locale.getDefault());
}

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}

 

19.4.3 隐藏列

 

19-8 添加和删除列

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class Test extends JFrame {
JTable table = new JTable(
new Object[][] {
{"Mouse", "Mighty", "M." },
{"Mouse", "Polly", "A." },
{"Doright", "Dudley", "L." }
},
new Object[] {
"Last Name", "First Name", "Middle Initial"
}
);
public Test() {
Container cp = getContentPane();

cp.add(new JScrollPane(table), BorderLayout.CENTER);
cp.add(new ControlPanel(), BorderLayout.NORTH);
}
class ControlPanel extends JPanel {
private JCheckBox checkBox = new JCheckBox(
"First Name Column Showing");
public ControlPanel() {
final TableColumnModel tcm = table.getColumnModel();
final TableColumn firstNameColumn =
table.getColumn("First Name");

checkBox.setSelected(true);
add(checkBox);

checkBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
if(checkBox.isSelected()) {
tcm.addColumn(firstNameColumn);
tcm.moveColumn(2,1);
}
else {
tcm.removeColumn(firstNameColumn);
}
table.sizeColumnsToFit(-1);
}
});
}
}
public static void main(String args[]) {
GJApp.launch(
new Test(), "Showing/Hiding Columns",300,300,450,175);
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
launch(f,title,x,y,w,h,null);
}
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h,
String propertiesFilename) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

if(propertiesFilename != null) {
resources = ResourceBundle.getBundle(
propertiesFilename, Locale.getDefault());
}

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}

 

19.4.4 锁定左边列

 

19-9 锁定表格的左列

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

public class Test extends JFrame {
Object[][] listings = new Object[][] {
{ "28 Pickelodan", "Mork and Mindy", "Dukes of Hazard",
"I Love Lucy", "Andy Griffith", "Mission Impossible" },

{ "29 Dizey", "Rulan", "<-- Mulan", "<-- Mulan",
"<-- Mulan", "<-- Mulan" },

{ "31 NBT", "Nightly News", "40/20",
"<-- 40/20", "LimeTime", "<-- LimeTime" },

{ "32 AnimalUniverse", "Amazing Animals","Animal Rescues",
"Cute Animals", "Killer Animals",
"Big and Small Animals" },

{ "34 DSPN", "Tuesday Night FootBall",
"<--Tuesday Night FootBall", "<--Tuesday Night FootBall",
"<--Tuesday Night FootBall", "<--Tuesday Night FootBall"},

{ "37 TLC", "Mind Mysteries", "Our World",
"Ancient Wonders", "UFOs", "Ancient Inventions" },

{ "38 THC", "The Civil War", "Stalin",
"Watergate", "Kent State", "WWII" },
};
Object[] columnNames = new Object[] {
"Channel", "7:30", "8:00", "8:30", "9:00", "9:30"
};
TableModel sharedModel = new DefaultTableModel(
listings, columnNames);
JTable table = new JTable(sharedModel),
headerTable = new JTable(sharedModel);

TableColumnModel tcm = table.getColumnModel();
TableColumn firstColumn = tcm.getColumn(0);

public Test() {
Container cp = getContentPane();

setActualPreferredColumnWidths(table);
setActualPreferredColumnWidths(headerTable);

table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
headerTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);

headerTable.getTableHeader().setReorderingAllowed(false);

headerTable.setPreferredScrollableViewportSize(
new Dimension(
firstColumn.getPreferredWidth() +
headerTable.getColumnModel().getColumnMargin(),
0));

cp.add(new ControlPanel(), BorderLayout.NORTH);
cp.add(new JScrollPane(table), BorderLayout.CENTER);
}
class ControlPanel extends JPanel {
JCheckBox checkBox = new JCheckBox("First Column Locked");

public ControlPanel() {
add(checkBox);

checkBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JScrollPane scrollPane = (JScrollPane)
SwingUtilities.getAncestorOfClass(
JScrollPane.class, table);

if(checkBox.isSelected()) {
tcm.removeColumn(firstColumn);
scrollPane.setRowHeaderView(headerTable);
scrollPane.setCorner(
JScrollPane.UPPER_LEFT_CORNER,
headerTable.getTableHeader());
}
else {
tcm.addColumn(firstColumn);

int numCols = tcm.getColumnCount();
tcm.moveColumn(numCols-1, 0);
scrollPane.setRowHeaderView(null);
}
}
});
}
}
public void setActualPreferredColumnWidths(JTable table) {
int columnCount = table.getColumnCount();

for(int i=0; i < columnCount; ++i) {
TableColumn c = table.getColumnModel().getColumn(i);
int w = getActualPreferredColumnWidth(c);

c.setPreferredWidth(w);
}
}
public int getActualPreferredColumnWidth(TableColumn col) {
int hw = columnHeaderWidth(col), // hw = header width
cw = widestCellInColumn(col); // cw = column width

return hw > cw ? hw : cw;
}
private int columnHeaderWidth(TableColumn col) {
TableCellRenderer renderer = col.getHeaderRenderer();

Component comp = renderer.getTableCellRendererComponent(
table, col.getHeaderValue(),
false, false, 0, 0);

return comp.getPreferredSize().width;
}
private int widestCellInColumn(TableColumn col) {
int c = col.getModelIndex(), width=0, maxw=0;

for(int r=0; r < table.getRowCount(); ++r) {
TableCellRenderer renderer =
table.getCellRenderer(r,c);

Component comp =
renderer.getTableCellRendererComponent(
table, table.getValueAt(r,c),
false, false, r, c);

width = comp.getPreferredSize().width;
maxw = width > maxw ? width : maxw;
}
return maxw;
}
public static void main(String args[]) {
GraphicJavaApplication.launch(
new Test(),"Locking the Left-Hand Column",
300,300,600,210);
}
}
class GraphicJavaApplication extends WindowAdapter {
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
}

19.5 表格选取

 

19-10 表格选取

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;

public class Test extends JFrame {
Object[] selectionModes = new Object[] {
"SINGLE_SELECTION",
"SINGLE_INTERVAL_SELECTION",
"MULTIPLE_INTERVAL_SELECTION",
};
int[] selectionConstants = {
ListSelectionModel.SINGLE_SELECTION,
ListSelectionModel.SINGLE_INTERVAL_SELECTION,
ListSelectionModel.MULTIPLE_INTERVAL_SELECTION,
};

JTable table = new JTable(10,10);

public Test() {
Container contentPane = getContentPane();
contentPane.add(new ControlPanel(), BorderLayout.NORTH);
contentPane.add(new JScrollPane(table),
BorderLayout.CENTER);

}
class ControlPanel extends JPanel {
JComboBox combo = new JComboBox(selectionModes);

public ControlPanel() {
setBorder(BorderFactory.createTitledBorder(
"Selection Modes"));
add(combo);
initializeCombo();

combo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int index = combo.getSelectedIndex();

table.setSelectionMode(
selectionConstants[index]);
}
});
}
private void initializeCombo() {
int mode =
table.getSelectionModel().getSelectionMode();

if(mode == ListSelectionModel.SINGLE_SELECTION) {
combo.setSelectedIndex(0);
}
else if(mode ==
ListSelectionModel.SINGLE_INTERVAL_SELECTION) {
combo.setSelectedIndex(1);
}
else if(mode ==
ListSelectionModel.MULTIPLE_INTERVAL_SELECTION) {
combo.setSelectedIndex(2);
}
}
}
public static void main(String args[]) {
GraphicJavaApplication.launch(
new Test(),"JTable Selection Modes",300,300,450,300);
}
}
class GraphicJavaApplication extends WindowAdapter {
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
}

 

19.6 绘制和编辑

 

 

19.6.1 使用表格单绘制器和编辑器

 

19-11 StereoDeckModel

import javax.swing.*;
import javax.swing.table.*;

class StereoDeckModel extends AbstractTableModel {
String[] columnNames = {
"In Use", "Manufacturer", "Model", "Price", "Dolby",
"Bass", "Volume"
};
Object[][] data = {
{ Boolean.FALSE, "Sony", "1501A",
new Double(129.99), Boolean.TRUE,
Boolean.TRUE, new Integer(50) },

{ Boolean.FALSE, "Phillips", "86A4",
new Double(159.99), Boolean.TRUE,
Boolean.FALSE, new Integer(35) },

{ Boolean.TRUE, "Kenwood", "33-801-A",
new Double(199.99), Boolean.FALSE,
Boolean.TRUE, new Integer(77) },

{ Boolean.FALSE, "Blaupunkt", "7622A",
new Double(229.99), Boolean.TRUE,
Boolean.FALSE, new Integer(19) },

{ Boolean.FALSE, "Akai", "9733",
new Double(259.99), Boolean.TRUE,
Boolean.FALSE, new Integer(68) },

{ Boolean.FALSE, "Sony", "1520B",
new Double(349.99), Boolean.FALSE,
Boolean.FALSE, new Integer(94) },

{ Boolean.FALSE, "Kenwood", "2289B",
new Double(499.99), Boolean.FALSE,
Boolean.FALSE, new Integer(44) },
};
public Object getValueAt(int row, int col) {
return data[row][col];
}
public int getRowCount() {
return data.length;
}
public int getColumnCount() {
return columnNames.length;
}
public String getColumnName(int col) {
return columnNames[col];
}
public Class getColumnClass(int col) {
return data[0][col].getClass();
}
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
public boolean isCellEditable(int row, int col) {
Class cls = getColumnClass(col);
String name = getColumnName(col);

return (cls == Boolean.class && !name.equals("Dolby")) ||
cls == Integer.class || cls == Double.class;
}
public void updateBulbs(int selectedRow) {
for(int r=0; r < getRowCount(); ++r) {
data[r][0] = new Boolean(r == selectedRow);
}
}
}

 

19-12 使用绘制器和编辑器

import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

public class Test extends JFrame {
JTable table = new JTable(new StereoDeckModel());

public Test() {
initializeInUseColumn();
initializePriceColumn();
initializeVolumeColumn();
sizeColumns();

table.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION);

table.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
StereoDeckModel model =
(StereoDeckModel)table.getModel();

if(!e.getValueIsAdjusting()) {
model.updateBulbs(table.getSelectedRow());
}
}
});
getContentPane().add(new JScrollPane(table),
BorderLayout.CENTER);
}
private void initializeInUseColumn() {
TableColumn inUseColumn = table.getColumn("In Use");

inUseColumn.setCellRenderer(new BulbRenderer());
inUseColumn.setCellEditor(new BulbEditor());
}
private void initializePriceColumn() {
TableColumn priceColumn = table.getColumn("Price");
JComboBox combo = new JComboBox();

// Combo box items are Numbers ...
combo.addItem(new Double(159.99));
combo.addItem(new Double(169.99));
combo.addItem(new Double(229.99));
combo.addItem(new Double(449.99));
combo.addItem(new Double(699.99));

combo.setRenderer(new ListCellCurrencyRenderer());

priceColumn.setCellRenderer(
new TableCellCurrencyRenderer());

priceColumn.setCellEditor(new PriceEditor(combo));
}
private void initializeVolumeColumn() {
TableColumn volumeColumn = table.getColumn("Volume");
TableCellRenderer renderer = new VolumeRenderer();
TableCellEditor editor = new VolumeEditor();

volumeColumn.setCellRenderer(renderer);
volumeColumn.setCellEditor(editor);

Dimension ps = ((JPanel)renderer).getPreferredSize();
table.setRowHeight(ps.height);
}
public static void main(String args[]) {
GraphicJavaApplication.launch(
new Test(), "Car Stereo Deck", 300,300,559,368);
}
private void sizeColumns() {
TableColumnModel tcm = table.getColumnModel();

for(int i=0; i < tcm.getColumnCount(); ++i) {
TableColumn column = tcm.getColumn(i);
int w = getPreferredWidthForColumn(column);

column.setMinWidth(w);
column.setMaxWidth(w);
}
}
public int getPreferredWidthForColumn(TableColumn col) {
int hw = columnHeaderWidth(col), // hw = header width
cw = widestCellInColumn(col); // cw = column width

return hw > cw ? hw+10 : cw+10;
}
private int columnHeaderWidth(TableColumn col) {
TableCellRenderer renderer = col.getHeaderRenderer();

Component comp = renderer.getTableCellRendererComponent(
table, col.getHeaderValue(),
false, false, 0, 0);

return comp.getPreferredSize().width;
}
private int widestCellInColumn(TableColumn col) {
int c = col.getModelIndex(), width=0, maxw=0;

for(int r=0; r < table.getRowCount(); ++r) {
TableCellRenderer renderer =
table.getCellRenderer(r,c);

Component comp =
renderer.getTableCellRendererComponent(
table, table.getValueAt(r,c),
false, false, r, c);

width = comp.getPreferredSize().width;
maxw = width > maxw ? width : maxw;
}
return maxw;
}
}
class ListCellCurrencyRenderer extends DefaultListCellRenderer {
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean hasFocus) {
JLabel c = (JLabel)
super.getListCellRendererComponent(
list, value, index,
isSelected, hasFocus);

Format format = NumberFormat.getCurrencyInstance();
c.setText(value == null ? "" : format.format(value));
return c;
}
}
class TableCellCurrencyRenderer extends DefaultTableCellRenderer {
public void setValue(Object value) {
Format format = NumberFormat.getCurrencyInstance();
super.setValue(value == null ? "" : format.format(value));
}
}
class GraphicJavaApplication extends WindowAdapter {
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
}

 

19.6.2 表格单绘制器

 

19-13 VolumeRenderer

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

class VolumeRenderer extends JPanel
implements TableCellRenderer {
private JSlider slider = new JSlider();
private JLabel label = new JLabel("value");

public VolumeRenderer() {
slider.setOrientation(SwingConstants.HORIZONTAL);
slider.setPreferredSize(new Dimension(200,30));
slider.putClientProperty("JSlider.isFilled",Boolean.TRUE);

label.setHorizontalAlignment(JLabel.CENTER);
label.setHorizontalTextPosition(JLabel.CENTER);

setLayout(new BorderLayout());
add(label, BorderLayout.NORTH);
add(slider, BorderLayout.CENTER);

slider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
label.setText(
Integer.toString(slider.getValue()));
}
});
}
public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected,
boolean hasFocus,
int row, int col) {
Integer v = (Integer)value;

slider.setValue(v.intValue());
label.setText(v.toString());

slider.setEnabled(isSelected);
label.setEnabled(isSelected);

return this;
}
public JSlider getSlider() {
return slider;
}
public JLabel getLabel() {
return label;
}
}

 

19.6.3 Default Table Cell Renderer

 

19-14 BulbRenderer

import java.awt.*;
import javax.swing.*;
import javax.swing.table.*;

class BulbRenderer extends DefaultTableCellRenderer {
private ImageIcon darkBulb = new ImageIcon("button.jpg"),
brightBulb = new ImageIcon("button_lit.jpg");

public BulbRenderer() {
setHorizontalAlignment(JLabel.CENTER);
}
public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected,
boolean hasFocus,
int row, int col) {
Boolean b = (Boolean)value;
setIcon(b.booleanValue() ? brightBulb : darkBulb);
return this;
}
}

 

19.6.4 表格格式化绘制器

 

 

19.6.5 单元编辑器

 

 

19.6.6 表格单编辑器

 

 

19.6.7 实现TableCellEditor接口

 

19-15 AbstractCellEditor

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.tree.*;
import java.awt.event.MouseEvent;
import java.util.EventObject;

abstract public class AbstractCellEditor
implements TableCellEditor {
protected EventListenerList listenerList =
new EventListenerList();
protected Object value;
protected ChangeEvent changeEvent = null;
protected int clickCountToStart = 1;

public Object getCellEditorValue() {
return value;
}
public void setCellEditorValue(Object value) {
this.value = value;
}
public void setClickCountToStart(int count) {
clickCountToStart = count;
}
public int getClickCountToStart() {
return clickCountToStart;
}
public boolean isCellEditable(EventObject anEvent) {
if (anEvent instanceof MouseEvent) {
if (((MouseEvent)anEvent).getClickCount() <
clickCountToStart)
return false;
}
return true;
}
public boolean shouldSelectCell(EventObject anEvent) {
return true;
}
public boolean stopCellEditing() {
fireEditingStopped();
return true;
}
public void cancelCellEditing() {
fireEditingCanceled();
}
public void addCellEditorListener(CellEditorListener l) {
listenerList.add(CellEditorListener.class, l);
}
public void removeCellEditorListener(CellEditorListener l) {
listenerList.remove(CellEditorListener.class, l);
}
protected void fireEditingStopped() {
Object[] listeners = listenerList.getListenerList();
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i] == CellEditorListener.class) {
if (changeEvent == null)
changeEvent = new ChangeEvent(this);
((CellEditorListener)
listeners[i+1]).editingStopped(changeEvent);
}
}
}
protected void fireEditingCanceled() {
Object[] listeners = listenerList.getListenerList();
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==CellEditorListener.class) {
if (changeEvent == null)
changeEvent = new ChangeEvent(this);
((CellEditorListener)
listeners[i+1]).editingCanceled(changeEvent);
}
}
}
}

19-16 VolumeEditor

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;
import java.util.EventObject;

class VolumeEditor extends AbstractCellEditor {
VolumeRenderer renderer = new VolumeRenderer();

public VolumeEditor() {
renderer.getLabel().addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
if(e.getClickCount() == 2)
cancelCellEditing();
}
});
}
public Component getTableCellEditorComponent(
JTable table, Object value,
boolean isSelected,
int row, int column) {
JSlider slider = renderer.getSlider();
slider.setValue(((Integer)value).intValue());
return renderer;
}
public boolean stopCellEditing() {
JSlider slider = renderer.getSlider();

setCellEditorValue(new Integer(slider.getValue()));

return super.stopCellEditing();
}
}

19-17 列出了PriceEdior

import javax.swing.*;
import java.util.EventObject;

class PriceEditor extends DefaultCellEditor {
public PriceEditor(JComboBox combo) {
super(combo);
}
public boolean isCellEditable(EventObject e) {
JPanel messagePanel = new JPanel();
JPasswordField pwf = new JPasswordField(10);

System.out.println(e);
messagePanel.add(new JLabel("Password:"));
messagePanel.add(pwf);

JOptionPane.showMessageDialog(null,
messagePanel, "Password Required",
JOptionPane.INFORMATION_MESSAGE);

if(pwf.getText().equals("dolby")) {
return true;
}
else {
JOptionPane.showMessageDialog(null,
"Wrong Password!", "Access Failed",
JOptionPane.INFORMATION_MESSAGE);
return false;
}
}
}

19.7 表格行

 

 

 

19.7.1 行高

 

19-18 计算和设置行高

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.util.*;

public class Test extends JFrame {
Object[] columnNames = {"Name", "Cost/Lb.", "Picture"};

Object[][] rowData = {
{ "cake", "$1.29", new ImageIcon("cake.gif") },
{ "pear", "$1.29", new ImageIcon("pear.gif") },
{ "pineapple", "$1.29", new ImageIcon("pineapple.gif") },
{ "apple", "$1.29", new ImageIcon("apple.gif") },
{ "bread", "$1.29", new ImageIcon("bread.gif") },
};
class RowSizingModel extends DefaultTableModel {
public RowSizingModel(Object[][] data,
Object[] colNames) {
super(data, colNames);
}
public Class getColumnClass(int c) {
if(c == 2) return ImageIcon.class;
else return super.getColumnClass(c);
}
}
JTable table = new JTable(new RowSizingModel(rowData,
columnNames));

public Test() {
table.setRowHeight(getMaxRowHeight());
getContentPane().add(new JScrollPane(table),
BorderLayout.CENTER);
}
public int getMaxRowHeight() {
int columnCount = table.getColumnCount(), h=0, maxh=0;

for(int i=0; i < columnCount; ++i) {
TableColumn column =
table.getColumnModel().getColumn(i);

h = getMaxRowHeightForColumn(column);
maxh = Math.max(h,maxh);
}
return maxh;
}
public int getMaxRowHeightForColumn(TableColumn column) {
int height = 0, maxh = 0, c = column.getModelIndex();

for(int r=0; r < table.getRowCount(); ++r) {
TableCellRenderer renderer =
table.getCellRenderer(r,c);
Component
comp = renderer.getTableCellRendererComponent(
table, table.getValueAt(r,c),
false, false, r, c);

height = comp.getMaximumSize().height;
maxh = height > maxh ? height : maxh;
}
return maxh;
}
public static void main(String args[]) {
GJApp.launch(
new Test(), "Sizing Rows", 300,300,450,300);
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
launch(f,title,x,y,w,h,null);
}
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h,
String propertiesFilename) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

if(propertiesFilename != null) {
resources = ResourceBundle.getBundle(
propertiesFilename, Locale.getDefault());
}

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}

 

19.7.2 绘制行

 

19-19 利用行和列进行绘制

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

public class Test extends JFrame {
JTable table = new JTable(
new AbstractTableModel() {
int rows = 100, cols = 10;

public int getRowCount() { return rows; }
public int getColumnCount() { return cols; }

public Object getValueAt(int row, int col) {
return "(" + Integer.toString(row) + "," +
Integer.toString(col) + ")";
}
});

public Test() {
TableColumn column;
int columnCount = table.getColumnCount();

for(int i=0; i < columnCount; ++i) {
column = table.getColumn(table.getColumnName(i));

if(i % 2 == 0)
column.setCellRenderer(new RowRenderer());
}
getContentPane().add(new JScrollPane(table),
BorderLayout.CENTER);
}
public static void main(String args[]) {
GraphicJavaApplication.launch(
new Test(), "Rendering By Columns and Rows",
300,300,450,300);
}
}
class RowRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected,
boolean hasFocus,
int row, int column) {
if(row % 2 == 0) setForeground(Color.blue);
else setForeground(Color.orange);

return super.getTableCellRendererComponent(table,
value, isSelected, hasFocus,
row, column);
}
}
class GraphicJavaApplication extends WindowAdapter {
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
}

 

19.8 表格装饰器

 

19-20 一个绘制装饰器

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.util.*;

public class Test extends JFrame {
JTable table = new JTable(new Object[][] {
{"apple", "$.39"}, {"mango", "$.49"},
{"papaya", "$1.19"}, {"lemon", "$.19"},
{"orange", "$.59"}, {"watermelon", "$.39"},
{"tangerine", "$1.09"}, {"cherry", "$.79"},
{"banana", "$.29"}, {"lime", "$.33"},
{"grapefruit", "$.69"}, {"grapes", "$.49"},
},
new Object[] { "Item", "Price/Lb." });

public Test() {
TableColumn column = table.getColumn("Price/Lb.");
TableCellRenderer renderer = column.getHeaderRenderer();

column.setHeaderRenderer(new RendererDecorator(renderer));

getContentPane().add(new JScrollPane(table),
BorderLayout.CENTER);
}
public static void main(String args[]) {
GJApp.launch(
new Test(), "A Renderer Decorator", 300,300,450,182);
}
}
class RendererDecorator implements TableCellRenderer {
TableCellRenderer realRenderer;
JPanel panel;
JLabel iconLabel = new JLabel(new ImageIcon("money.gif"));

public RendererDecorator(TableCellRenderer r) {
realRenderer = r;
iconLabel.setBorder(BorderFactory.createEtchedBorder());
}
public Component getTableCellRendererComponent(
JTable table, Object value,
boolean isSelected, boolean hasFocus,
int row, int col) {
Component c = realRenderer.getTableCellRendererComponent(
table, value, isSelected,
hasFocus, row, col);
embellishComponent(c);
return panel;
}
private void embellishComponent(Component c) {
if(panel == null) {
panel = new JPanel();

panel.setLayout(new BorderLayout());
panel.add(c, BorderLayout.CENTER);
panel.add(iconLabel, BorderLayout.WEST);
}
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
launch(f,title,x,y,w,h,null);
}
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h,
String propertiesFilename) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

if(propertiesFilename != null) {
resources = ResourceBundle.getBundle(
propertiesFilename, Locale.getDefault());
}

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}

19-21 利用装饰器排序

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

public class Test extends JFrame {
JTable table = new JTable(new Object[][] {
{"apple", "$.39"}, {"mango", "$.49"},
{"papaya", "$1.19"}, {"lemon", "$.19"},
{"orange", "$.59"}, {"watermelon", "$.39"},
{"tangerine", "$1.09"}, {"cherry", "$.79"},
{"banana", "$.29"}, {"lime", "$.33"},
{"grapefruit", "$.69"}, {"grapes", "$.49"},
},
new Object[] { "Item", "Price/Lb." });

public Test() {
final SortDecorator decorator =
new SortDecorator(table.getModel());

table.setModel(decorator);

JTableHeader hdr = (JTableHeader)table.getTableHeader();

hdr.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
TableColumnModel tcm = table.getColumnModel();
int vc = tcm.getColumnIndexAtX(e.getX());
int mc = table.convertColumnIndexToModel(vc);

decorator.sort(mc);
//table.repaint();
}
});
getContentPane().add(new JScrollPane(table),
BorderLayout.CENTER);
}
public static void main(String args[]) {
GJApp.launch(
new Test(),"A Sort Decorator",300,300,450,250);
}
}
class SortDecorator implements TableModel, TableModelListener {
private TableModel realModel;
private int indexes[];

public SortDecorator(TableModel model) {
if(model == null)
throw new IllegalArgumentException(
"null models are not allowed");
this.realModel = model;

realModel.addTableModelListener(this);
allocate();
}
public Object getValueAt(int row, int column) {
return realModel.getValueAt(indexes[row], column);
}
public void setValueAt(Object aValue, int row, int column) {
realModel.setValueAt(aValue, indexes[row], column);
}
public void tableChanged(TableModelEvent e) {
allocate();
}
public void sort(int column) {
int rowCount = getRowCount();

for(int i=0; i < rowCount; i++) {
for(int j = i+1; j < rowCount; j++) {
if(compare(indexes[i], indexes[j], column) < 0) {
swap(i,j);
}
}
}
}
public void swap(int i, int j) {
int tmp = indexes[i];
indexes[i] = indexes[j];
indexes[j] = tmp;
}
public int compare(int i, int j, int column) {
Object io = realModel.getValueAt(i,column);
Object jo = realModel.getValueAt(j,column);

int c = jo.toString().compareTo(io.toString());
return (c < 0) ? -1 : ((c > 0) ? 1 : 0);
}
private void allocate() {
indexes = new int[getRowCount()];

for(int i=0; i < indexes.length; ++i) {
indexes[i] = i;
}
}

// TableModel pass-through methods follow ...

public int getRowCount() {
return realModel.getRowCount();
}
public int getColumnCount() {
return realModel.getColumnCount();
}
public String getColumnName(int columnIndex) {
return realModel.getColumnName(columnIndex);
}
public Class getColumnClass(int columnIndex) {
return realModel.getColumnClass(columnIndex);
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return realModel.isCellEditable(rowIndex, columnIndex);
}
public void addTableModelListener(TableModelListener l) {
realModel.addTableModelListener(l);
}
public void removeTableModelListener(TableModelListener l) {
realModel.removeTableModelListener(l);
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
launch(f,title,x,y,w,h,null);
}
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h,
String propertiesFilename) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

if(propertiesFilename != null) {
resources = ResourceBundle.getBundle(
propertiesFilename, Locale.getDefault());
}

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}

19.9 表格头部

 

 

19.9.1 JTableHeader

 

 

19.9.2 列头部绘制器和头部工具提示

 

19-22 一个多行表格列头部和头部工具提示

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class Test extends JFrame {
String longTitle = "Last Name / Maiden Name (if divorced)";
MultilineHeaderRenderer multilineRenderer =
new MultilineHeaderRenderer(longTitle);

JTable table = new JTable(
new Object[][] {
{ "Lynn", "M.", "Seckinger" },
{ "Carol", "R.", "Seckinger" },
{ "Roy", "D.", "Martin" },
{ "Richard", "A.", "Tattersall" },
{ "Philip", "B.", "Edwards" },
{ "Moore", "T.", "Moore" },

// shorten scrollbar grip with these ...

{ "Lynn", "M.", "Seckinger" },
{ "Carol", "R.", "Seckinger" },
{ "Roy", "D.", "Martin" },
{ "Richard", "A.", "Tattersall" },
{ "Philip", "B.", "Edwards" },
{ "Moore", "T.", "Moore" },
},
new Object[] {"First Name", "MI", longTitle});

public Test() {
TableColumn middleColumn = table.getColumn("MI"),
lastColumn = table.getColumn(longTitle);

lastColumn.setHeaderRenderer(multilineRenderer);

TableCellRenderer hdrRenderer =
middleColumn.getHeaderRenderer();

Component hdrComponent =
hdrRenderer.getTableCellRendererComponent(table,
"MI", false, false, 0, 0);

if(hdrComponent instanceof JComponent) {
JComponent c = (JComponent)hdrComponent;
c.setToolTipText("Middle Initial");
}

table.getTableHeader().setToolTipText("Table Header!");

getContentPane().add(
new JScrollPane(table), BorderLayout.CENTER);
}
public static void main(String args[]) {
GJApp.launch(new Test(),
"Multi-Line Column Headers",300,300,300,250);
}
}
class MultilineHeaderRenderer implements TableCellRenderer {
MultilineHeader mll;
JScrollPane scrollPane;

public MultilineHeaderRenderer(String title) {
mll = new MultilineHeader(title);
scrollPane = new JScrollPane(mll);

scrollPane.setHorizontalScrollBarPolicy(
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

scrollPane.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_NEVER);

scrollPane.setBorder(null);
}
public Component getTableCellRendererComponent(JTable table,
Object value,
boolean isSelected,
boolean hasFocus,
int row, int col) {
mll.setText((String)value);
return scrollPane;
}
}
class MultilineHeader extends JTextArea {
public MultilineHeader(String s) {
super(s);
}
public void updateUI() {
super.updateUI();

// turn on wrapping and disable editing and highlighting

setLineWrap(true);
setWrapStyleWord(true);
setHighlighter(null);
setEditable(false);

// make the text area look like a table header

LookAndFeel.installColorsAndFont(this,
"TableHeader.background",
"TableHeader.foreground",
"TableHeader.font");

LookAndFeel.installBorder(this, "TableHeader.cellBorder");
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
launch(f,title,x,y,w,h,null);
}
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h,
String propertiesFilename) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

if(propertiesFilename != null) {
resources = ResourceBundle.getBundle(
propertiesFilename, Locale.getDefault());
}

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}

 

19.9.3 JTable属性

 

 

19.9.4 表格事件

 

 

19.9.5 表格模型事件

 

19-23 表格模型事件处理

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;

public class Test extends JFrame {
JTable table = new JTable(10,10);

public Test() {
Container contentPane = getContentPane();

contentPane.add(new JScrollPane(table),
BorderLayout.CENTER);

table.getModel().addTableModelListener(
new TableModelListener() {
public void tableChanged(TableModelEvent e) {
int firstRow = e.getFirstRow(),
column = e.getColumn();

String properties = " source=" + e.getSource() +
" firstRow= " +
(firstRow == TableModelEvent.HEADER_ROW ?
"HEADER_ROW" :
Integer.toString(firstRow)) +

" lastRow= " + e.getLastRow() +

" column= " +
(firstRow == TableModelEvent.ALL_COLUMNS ?
"ALL_COLUMNS" :
Integer.toString(column));

String typeString = new String();
int type = e.getType();

switch(type) {
case TableModelEvent.DELETE:
typeString = "DELETE"; break;
case TableModelEvent.INSERT:
typeString = "INSERT"; break;
case TableModelEvent.UPDATE:
typeString = "UPDATE"; break;
}
properties += " type=" + typeString;

JOptionPane.showMessageDialog(Test.this,
e.getClass().getName() +
"[" + properties + "]");
}
});
}
public static void main(String args[]) {
GraphicJavaApplication.launch(new Test(),
"Handling Table Model Events",300,300,450,220);
}
}
class GraphicJavaApplication extends WindowAdapter {
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
}

 

19.9.6 TableColumnModel事件

 

19-24 列模型事件的处理

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;

public class Test extends JApplet {
JTable table = new JTable(
new AbstractTableModel() {
int rows = 10, cols = 10;

public int getRowCount() { return rows; }
public int getColumnCount() { return cols; }

public Object getValueAt(int row, int col) {
return "(" + Integer.toString(row) + "," +
Integer.toString(col) + ")";
}
}
);

public void init() {
Container contentPane = getContentPane();

contentPane.add(new JScrollPane(table),
BorderLayout.CENTER);

table.getColumnModel().addColumnModelListener(
new TableColumnModelListener() {
public void columnAdded(TableColumnModelEvent e) { }
public void columnMarginChanged(ChangeEvent e) { }
public void columnRemoved(TableColumnModelEvent e) { }
public void columnSelectionChanged(
ListSelectionEvent e) { }

public void columnMoved(TableColumnModelEvent e) {
String s = "Column Moved From " +
e.getFromIndex() + " To " +
e.getToIndex();

showStatus(s);
}
});
}
}

 

19.9.7 列表选取事件

19-25 行选取事件的处理

import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class Test extends JFrame {
JTable table = new JTable(10,10);

public Test() {
Container contentPane = getContentPane();

contentPane.add(new JScrollPane(table),
BorderLayout.CENTER);

table.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if(e.getValueIsAdjusting()) {
System.out.println("Selection Model " +
"adjusting ...");
}
else {
System.out.println("Selection Model:" +
e.toString());
}
}
});
}
public static void main(String args[]) {
GJApp.launch(new Test(),
"Handling Row Selection",300,300,450,220);
}
}
class GJApp extends WindowAdapter {
static private JPanel statusArea = new JPanel();
static private JLabel status = new JLabel(" ");
static private ResourceBundle resources;

public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h) {
launch(f,title,x,y,w,h,null);
}
public static void launch(final JFrame f, String title,
final int x, final int y,
final int w, int h,
String propertiesFilename) {
f.setTitle(title);
f.setBounds(x,y,w,h);
f.setVisible(true);

statusArea.setBorder(BorderFactory.createEtchedBorder());
statusArea.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
statusArea.add(status);
status.setHorizontalAlignment(JLabel.LEFT);

f.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE);

if(propertiesFilename != null) {
resources = ResourceBundle.getBundle(
propertiesFilename, Locale.getDefault());
}

f.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
System.exit(0);
}
});
}
static public JPanel getStatusArea() {
return statusArea;
}
static public void showStatus(String s) {
status.setText(s);
}
static Object getResource(String key) {
if(resources != null) {
return resources.getString(key);
}
return null;
}
}

 

19.9.8 JTable类总结

 

 

19.9.9 AWT兼容

 

19.10 本章回顾

 

  略

相关实践学习
SLB负载均衡实践
本场景通过使用阿里云负载均衡 SLB 以及对负载均衡 SLB 后端服务器 ECS 的权重进行修改,快速解决服务器响应速度慢的问题
负载均衡入门与产品使用指南
负载均衡(Server Load Balancer)是对多台云服务器进行流量分发的负载均衡服务,可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。 本课程主要介绍负载均衡的相关技术以及阿里云负载均衡产品的使用方法。
目录
相关文章
|
7月前
|
JavaScript 前端开发 PHP
表格表单
表格表单
59 1
|
3月前
表格的表头
表格的表头。
22 4
|
3月前
有标题的表格
有标题的表格。
19 3
|
5月前
HTML【详解】表格 table 标签(table的属性,语义化表格,简易表格,合并单元格)
HTML【详解】表格 table 标签(table的属性,语义化表格,简易表格,合并单元格)
258 0
HTML【详解】表格 table 标签(table的属性,语义化表格,简易表格,合并单元格)
|
7月前
|
数据采集
分面中添加不同表格
分面中添加不同表格
62 0
|
7月前
POI(excel)中表格(单元格)样式应用实践总结
POI(excel)中表格(单元格)样式应用实践总结
122 0
|
SQL 自然语言处理 搜索推荐
|
监控 数据可视化 前端开发
S2 1.0:这个表格 「不简单」
S2 1.0:这个表格 「不简单」
287 0
|
数据安全/隐私保护
表格与表单
表格与表单
93 0