重新绘制 Table Swing JTable 问题
Repaint Table issue with Swing JTable
我正在使用 swing JTable
,但在重绘时遇到了问题 table。我用下面的代码
画了一个 JTable
Object[] column = new Object[]{"Entity", "Attribute"};
Object[][] rowData = new Object[][]{{"E1", "A1"},{"E2", "A2"}};
TableCellRenderer cellRenderer = new TableCellRenderer();
JTable table = new JTable(new DefaultTableModel(rowData, column));
table.setCellSelectionEnabled(true);
table.getColumnModel().getColumn(0).setCellRenderer(cellRenderer);
下面是我的 table 渲染器代码 ..
public class TableCellRenderer implements javax.swing.table.TableCellRenderer {
//private JPanel panel;
JTextField field;
private JTable table;
@Override
public Component getTableCellRendererComponent(final JTable table, final Object value,
boolean isSelected, boolean hasFocus, final int row, final int column) {
this.table = table;
//JTextField field = null;
System.out.println("Rendere : Row : " + row + "Column : " + column);
final JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
JButton button = new JButton("?");
button.setPreferredSize(new Dimension(20, panel.getHeight()));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SelectionDialog(panel, table, value, row, column);
}
});
if(table.getValueAt(row, column) != null){
field = new JTextField(table.getValueAt(row, column).toString());
}else{
field = new JTextField(table.getValueAt(row, column).toString());
}
field.setPreferredSize(new Dimension(30, panel.getHeight()));
panel.add(field, BorderLayout.WEST);
panel.add(button, BorderLayout.EAST);
return panel;
}
这就是我更新 table..
中单元格内容的方式
SelectionDialog.this.table.getModel().setValueAt("E7", 0, 0);
我正在通过 SelectionDialog
更新 table 模型数据,例如将第 0 行、第 0 列的数据更改为 E7 等。更改 table 模型中的数据后,我尝试了以下选项,但其中 none 已刷新视图中的 table 数据,但是 JTable
模型中的数据已正确更新。如果我即时添加一个新行,然后调用以下方法,那么一切正常,但如果我修改现有行模型中的数据,则下面提到的解决方案 none 正在工作
//((DefaultTableModel)SelectionDialog.this.table.getModel()).addRow(new Object[]{"E3", "A3"});
//((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableCellUpdated(SelectionDialog.this.row, SelectionDialog.this.column);
//((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableChanged(new TableModelEvent(SelectionDialog.this.table.getModel()));
//((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableStructureChanged();
//SelectionDialog.this.table.repaint();
// SelectionDialog.this.table.revalidate();
请提供有关该问题的任何见解,因为我正在摇摆并且可能遗漏了一些非常重要的事情。
编辑 1:只是添加了一个我想早点放但不知道怎么错过的便条。 Table 通常不会更新,但如果我从进行更改的单元格中移出焦点,或者我更改 table 的大小,那么它会立即将该特定单元格的内容更改为新的选定值。
问题已解决:
我将我的发现提供给面临类似问题的人。
我在 table 的每个单元格内渲染了一个按钮和一个文本框。单击按钮时(未提供编辑器代码,因为它看起来与我无关,无法放置在这里)会出现一个对话框,该对话框从用户输入值并更新特定的列和行。
我提到的行在我的 post 末尾(编辑 1 之前)工作正常,但是渲染器没有执行,除非我手动从选定的单元格(其按钮被单击)或手动更改大小jtable 是有意义的,因为按钮在编辑器内部,按钮单击显示单元格已被编辑,并且偏离路线的渲染器将不会执行,除非编辑完成,这需要聚焦或输入键等。
我将以下代码应用为
table.editCellAt(-1, -1);
它从编辑的单元格(使用按钮编辑)聚焦出来,因此渲染器按预期执行和工作。
当你使用DefaultTableModel
并且你想更新某个值时,你需要使用DefaultTableModel#setValueAt
方法。
调用此方法(当然是在事件调度线程上)将更新您的模型并触发必要的事件。这些事件将导致您的 JTable
自行更新。
关于您的渲染器的一些附加说明:
- 在渲染器的每次调用中创建新组件不是正确的方法。对于大 tables,这变得非常慢。在渲染器的构造函数中创建所有组件一次,然后更新它们的状态
- 在渲染器中向 table 添加
JButton
没有任何效果,除非您也有编辑器。该按钮将不可点击,您附加到它的动作侦听器将永远不会被调用。有关详细信息,请参阅 renderers and editors section in the JTable
tutorial。
- 应该不需要在渲染器中调用
getValueAt
。该值作为参数之一传入
我正在使用 swing JTable
,但在重绘时遇到了问题 table。我用下面的代码
JTable
Object[] column = new Object[]{"Entity", "Attribute"};
Object[][] rowData = new Object[][]{{"E1", "A1"},{"E2", "A2"}};
TableCellRenderer cellRenderer = new TableCellRenderer();
JTable table = new JTable(new DefaultTableModel(rowData, column));
table.setCellSelectionEnabled(true);
table.getColumnModel().getColumn(0).setCellRenderer(cellRenderer);
下面是我的 table 渲染器代码 ..
public class TableCellRenderer implements javax.swing.table.TableCellRenderer {
//private JPanel panel;
JTextField field;
private JTable table;
@Override
public Component getTableCellRendererComponent(final JTable table, final Object value,
boolean isSelected, boolean hasFocus, final int row, final int column) {
this.table = table;
//JTextField field = null;
System.out.println("Rendere : Row : " + row + "Column : " + column);
final JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
JButton button = new JButton("?");
button.setPreferredSize(new Dimension(20, panel.getHeight()));
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
new SelectionDialog(panel, table, value, row, column);
}
});
if(table.getValueAt(row, column) != null){
field = new JTextField(table.getValueAt(row, column).toString());
}else{
field = new JTextField(table.getValueAt(row, column).toString());
}
field.setPreferredSize(new Dimension(30, panel.getHeight()));
panel.add(field, BorderLayout.WEST);
panel.add(button, BorderLayout.EAST);
return panel;
}
这就是我更新 table..
中单元格内容的方式SelectionDialog.this.table.getModel().setValueAt("E7", 0, 0);
我正在通过 SelectionDialog
更新 table 模型数据,例如将第 0 行、第 0 列的数据更改为 E7 等。更改 table 模型中的数据后,我尝试了以下选项,但其中 none 已刷新视图中的 table 数据,但是 JTable
模型中的数据已正确更新。如果我即时添加一个新行,然后调用以下方法,那么一切正常,但如果我修改现有行模型中的数据,则下面提到的解决方案 none 正在工作
//((DefaultTableModel)SelectionDialog.this.table.getModel()).addRow(new Object[]{"E3", "A3"});
//((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableCellUpdated(SelectionDialog.this.row, SelectionDialog.this.column);
//((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableChanged(new TableModelEvent(SelectionDialog.this.table.getModel()));
//((DefaultTableModel)SelectionDialog.this.table.getModel()).fireTableStructureChanged();
//SelectionDialog.this.table.repaint();
// SelectionDialog.this.table.revalidate();
请提供有关该问题的任何见解,因为我正在摇摆并且可能遗漏了一些非常重要的事情。
编辑 1:只是添加了一个我想早点放但不知道怎么错过的便条。 Table 通常不会更新,但如果我从进行更改的单元格中移出焦点,或者我更改 table 的大小,那么它会立即将该特定单元格的内容更改为新的选定值。
问题已解决:
我将我的发现提供给面临类似问题的人。
我在 table 的每个单元格内渲染了一个按钮和一个文本框。单击按钮时(未提供编辑器代码,因为它看起来与我无关,无法放置在这里)会出现一个对话框,该对话框从用户输入值并更新特定的列和行。 我提到的行在我的 post 末尾(编辑 1 之前)工作正常,但是渲染器没有执行,除非我手动从选定的单元格(其按钮被单击)或手动更改大小jtable 是有意义的,因为按钮在编辑器内部,按钮单击显示单元格已被编辑,并且偏离路线的渲染器将不会执行,除非编辑完成,这需要聚焦或输入键等。 我将以下代码应用为
table.editCellAt(-1, -1);
它从编辑的单元格(使用按钮编辑)聚焦出来,因此渲染器按预期执行和工作。
当你使用DefaultTableModel
并且你想更新某个值时,你需要使用DefaultTableModel#setValueAt
方法。
调用此方法(当然是在事件调度线程上)将更新您的模型并触发必要的事件。这些事件将导致您的 JTable
自行更新。
关于您的渲染器的一些附加说明:
- 在渲染器的每次调用中创建新组件不是正确的方法。对于大 tables,这变得非常慢。在渲染器的构造函数中创建所有组件一次,然后更新它们的状态
- 在渲染器中向 table 添加
JButton
没有任何效果,除非您也有编辑器。该按钮将不可点击,您附加到它的动作侦听器将永远不会被调用。有关详细信息,请参阅 renderers and editors section in theJTable
tutorial。 - 应该不需要在渲染器中调用
getValueAt
。该值作为参数之一传入