我是靠谱客的博主 糟糕枫叶,这篇文章主要介绍再议将Swing组件与JTable的单元格组件,现在分享给大家,希望可以做个参考。

可以说JTable是Swing组件中最重要的组件,只要程序和数据库打交道的程序必然有表格组件,而且多数情况下又不会很直白的把数据填到表格里,一般都会把各种组件放在表格里以便于对特定数据的呈现,也因此表格组件成了Swing里最让人头痛的组件。网上有很多如何把某个组件加载到表格的中的例子,但那些程序都只是用了极少的数据来演示,并不需要对表格进行刷新,因此那些例子里都没有关闭单元格编辑状态的代码,而当数据量大到需要多页显示时就出了问题,表格中的某列单元格使用了自定义的组件(诸如按钮之类的),当这些单元格被点击后再刷新表格的时会抛数组越界异常,像这样:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
at java.util.Vector.elementAt(Unknown Source)
at javax.swing.table.DefaultTableModel.setValueAt(Unknown Source)
at javax.swing.JTable.setValueAt(Unknown Source)
at javax.swing.JTable.editingStopped(Unknown Source)
at javax.swing.AbstractCellEditor.fireEditingStopped(Unknown Source)
at javax.swing.AbstractCellEditor.stopCellEditing(Unknown Source)
at javax.swing.JTable.columnMarginChanged(Unknown Source)
at javax.swing.table.DefaultTableColumnModel.fireColumnMarginChanged(Unknown Source)
at javax.swing.table.DefaultTableColumnModel.propertyChange(Unknown Source)
at java.beans.PropertyChangeSupport.fire(Unknown Source)
像这种问题很多人会以为问题是出在像表格里加载数据时出了错,又或者是某个单元格没有得到值等原因。
但真实的原因是没有关闭单元格的编辑状态,当点击某单元格后程序会使单元格状态变为编辑状态,如果此时不对表格内的数据重新加载的话是不会抛上述异常的,但只要一重新加载数据就立马抛异常,因此需要使用fireEditingStopped方法来关闭编辑状态。

我因为学习SQLite的需要而专门编写了一个带有JTable的程序,更详细的就不多说了,再此直接贴出代码以供参考

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
private JScrollPane createTable() { String[] columnHeaders = { "书名", "库存", "单价", "类型", "评分", "入库日期", "出版社", "联系电话" }; tableModel = new DefaultTableModel(); // 创建表格头部字段 tableModel.addColumn(""); for (String header : columnHeaders) tableModel.addColumn(header); tableModel.addColumn("操作"); JTable table = new JTable(tableModel); table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); // 表格选择为单选 table.setRowHeight(25); // 设置行高 table.setShowVerticalLines(false);// 使表格的列线条不显示 // 使第一列的大小固定不变 table.getColumn("").setPreferredWidth(25); table.getColumn("").setMaxWidth(25); table.getColumn("").setMinWidth(25); // 设置表格排序,表格默认将所有值都作为字符串进行排序, // 所以对于表格中已有字符型列可以不用自定义排序类 // 但需要对非字符串的列进行自定义排序 TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(tableModel); sorter.setComparator(2, new Comparator<Integer>() { public int compare(Integer o1, Integer o2) { return o1.compareTo(o2); } }); // 对单价列进行排序,由于单位已经被格式化了货币字符串 // 所以要对字符串进行转换后再比较 sorter.setComparator(3, new Comparator<String>() { public int compare(String o1, String o2) { BigDecimal b1 = new BigDecimal(o1.substring(1)); BigDecimal b2 = new BigDecimal(o2.substring(1)); return b1.compareTo(b2); } }); sorter.setComparator(6, new Comparator<java.sql.Date>() { public int compare(Date o1, Date o2) { return o1.compareTo(o2); } }); table.setRowSorter(sorter); // 设置各列的呈现方式 new CheckBoxColumn(table.getColumn("")); new LabelColumn(table.getColumn("书名")); new LabelColumn(table.getColumn("单价"), null, Color.BLUE, SwingConstants.RIGHT); new ProgressColumn(table.getColumn("库存"), Book.STORAGE_MAXIMUM); new LabelColumn(table.getColumn("评分"), SwingConstants.CENTER); new LabelColumn(table.getColumn("类型")); new LabelColumn(table.getColumn("入库日期"), SwingConstants.LEFT); new LabelColumn(table.getColumn("出版社"), SwingConstants.CENTER); new ComboBoxColumn(table.getColumn("联系电话")); new ButtonColumn(table.getColumn("操作"), "编辑", center); return new JScrollPane(table); } public void updateTable() { // 清空表格模型内的数据 tableModel.getDataVector().clear(); tableModel.fireTableDataChanged(); new SwingWorker<List<BookView>, Vector>() { protected List<BookView> doInBackground() throws Exception { // 得到书籍的总数 bookTotal = center.getDataManager().getBookTotal(); // 根据当前的页数的返回一个结果集 List<BookView> books = center.getDataManager().getBookViewByPage(pageSize, pageNo); for (BookView book : books) { Vector rowData = new Vector(); rowData.add(new Boolean(false)); rowData.add(book.getBookName()); rowData.add(book.getStorage()); rowData.add(NumberFormat.getCurrencyInstance().format(book.getPrice().doubleValue())); rowData.add(book.getTypeName()); rowData.add(book.getGrade()); rowData.add(book.getStorageDate()); rowData.add(book.getPublishName()); rowData.add(book.getPublishPhone()); rowData.add(book.getId()); this.publish(rowData); } return books; } protected void process(List<Vector> chunks) { lblStatueBar.setText(StringHelper.LOADING); for (Vector rowData : chunks) { tableModel.addRow(rowData); } } protected void done() { lblStatueBar.setText("共有" + bookTotal + "条书籍记录!"); pageTotal = bookTotal / pageSize; pageTotal += bookTotal / pageSize > 0 ? 1 : 0; cboPage.removeAllItems(); for (int p = 1; p <= pageTotal; p++) cboPage.addItem(p); cboPage.setSelectedItem(pageNo); chkDeleteAll.setSelected(false); }; }.execute(); }

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package gui.tableColumn; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.AbstractCellEditor; import javax.swing.JCheckBox; import javax.swing.JTable; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; public class CheckBoxColumn extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { private JCheckBox chkRender; private JCheckBox chkEditor; private Object value; public CheckBoxColumn(TableColumn tc) { chkRender = new JCheckBox(); chkEditor = new JCheckBox(); chkEditor.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { fireEditingStopped(); } }); tc.setCellEditor(this); tc.setCellRenderer(this); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { chkRender.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground()); chkRender.setSelected((Boolean) value); return chkRender; } @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { chkEditor.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground()); if(value!=null) { Boolean res = (Boolean)value; res = !res; this.value = res; chkEditor.setSelected(res); } return chkEditor; } @Override public Object getCellEditorValue() { return this.value; } }

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package gui.tableColumn; import gui.BookDialog; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.AbstractCellEditor; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import manager.ManagerCenter; public class ButtonColumn extends AbstractCellEditor implements TableCellEditor, TableCellRenderer, ActionListener { private JButton btnRender; private JButton btnEditor; private Object value; private ManagerCenter center; public ButtonColumn(TableColumn tc, String name, ManagerCenter center) { this.center = center; btnRender = new JButton(name); btnEditor = new JButton(name); btnEditor.addActionListener(this); tc.setCellEditor(this); tc.setCellRenderer(this); } @Override public Object getCellEditorValue() { // TODO Auto-generated method stub return this.value; } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (hasFocus) { btnRender.setForeground(table.getForeground()); btnRender.setBackground(UIManager.getColor("Button.background ")); } else if (isSelected) { btnRender.setForeground(table.getSelectionForeground()); btnRender.setBackground(table.getSelectionBackground()); } else { btnRender.setForeground(table.getForeground()); btnRender.setBackground(UIManager.getColor("Button.background ")); } return btnRender; } @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { // TODO Auto-generated method stub this.value = value; if (isSelected) { btnEditor.setForeground(table.getSelectionForeground()); btnEditor.setBackground(table.getSelectionBackground()); } else { btnEditor.setForeground(table.getForeground()); btnEditor.setBackground(UIManager.getColor("Button.background ")); } return btnEditor; } public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub // System.out.println(value); fireEditingStopped(); new BookDialog(center, Integer.parseInt(value.toString())); } }

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package gui.tableColumn; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import javax.swing.AbstractCellEditor; import javax.swing.JComboBox; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; public class ComboBoxColumn extends AbstractCellEditor implements TableCellRenderer, TableCellEditor { private JComboBox cboRender; private JComboBox cboEditor; private Object value; private JTable table; public ComboBoxColumn(TableColumn tc) { tc.setCellEditor(this); tc.setCellRenderer(this); } public Object getCellEditorValue() { return value; } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { if (value != null) { String[] phones = value.toString().split("\|"); cboRender = new JComboBox(phones); } return cboRender; } @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { this.value = value; this.table = table; if (value != null) { String[] phones = value.toString().split("\|"); cboEditor = new JComboBox(phones); cboEditor.addFocusListener(new FocusListener() { public void focusGained(FocusEvent e) { } public void focusLost(FocusEvent e) { fireEditingStopped(); } }); } return cboEditor; } }

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
package gui.tableColumn; import java.awt.Color; import java.awt.Component; import java.awt.Font; import javax.swing.AbstractCellEditor; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.SwingConstants; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; public class LabelColumn extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { private Font font; private Color fontColor; private JLabel lblRender; public LabelColumn(TableColumn tc, Font font, Color fontColor, int alignment) { lblRender = new JLabel(); lblRender.setOpaque(true); tc.setCellEditor(this); tc.setCellRenderer(this); if (font != null) this.font = font; if (fontColor != null) this.fontColor = fontColor; if (alignment != -1) lblRender.setHorizontalAlignment(alignment); } public LabelColumn(TableColumn tc, Font font) { this(tc, font, null, SwingConstants.LEFT); } public LabelColumn(TableColumn tc, Color fontColor) { this(tc, null, fontColor, SwingConstants.LEFT); } public LabelColumn(TableColumn tc, int alignment) { this(tc, null, null, alignment); } public LabelColumn(TableColumn tc) { this(tc, null, null, SwingConstants.LEFT); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { lblRender.setText(value != null ? value.toString() : ""); lblRender.setFont(this.font == null ? table.getFont() : this.font); lblRender.setForeground(this.fontColor == null ? table.getForeground() : this.fontColor); lblRender.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground()); return lblRender; } @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { return null; } @Override public Object getCellEditorValue() { // TODO Auto-generated method stub return null; } }

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package gui.tableColumn; import java.awt.Component; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import javax.swing.AbstractCellEditor; import javax.swing.JProgressBar; import javax.swing.JTable; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; public class ProgressColumn extends AbstractCellEditor implements TableCellRenderer, TableCellEditor { private JProgressBar pbRender; public ProgressColumn(TableColumn tc, int maximum) { pbRender = new JProgressBar(); pbRender.setMaximum(maximum); pbRender.setBorder(null); tc.setCellEditor(this); tc.setCellRenderer(this); } public Object getCellEditorValue() { return null; } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { pbRender.setString(value.toString()); pbRender.setStringPainted(true); pbRender.setValue(Integer.parseInt(value.toString())); return pbRender; } @Override public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { return null; } }


最后

以上就是糟糕枫叶最近收集整理的关于再议将Swing组件与JTable的单元格组件的全部内容,更多相关再议将Swing组件与JTable内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(97)

评论列表共有 0 条评论

立即
投稿
返回
顶部