繁体   English   中英

使用Swing JTable重绘表问题

[英]Repaint Table issue with Swing JTable

我正在使用Swing JTable ,但在重新绘制表时遇到了麻烦。 我用以下代码绘制了一个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);

下面是我的表格渲染器代码..

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;

}

这就是我更新表中单元格内容的方式。

SelectionDialog.this.table.getModel().setValueAt("E7", 0, 0);

我正在通过SelectionDialog更新表模型数据,例如将行0,列0更改为E7等。在表模型中更改数据后,我尝试了以下选项,但是它们均未刷新视图中的表数据,但是该数据在JTable模型中已正确更新。 如果我即时添加新行,然后调用以下方法,则一切正常,但如果我修改现有行模型中的数据,则以下提到的解决方案均无法正常工作

//((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:只是添加了一个我想更早放置的音符,但不知道我怎么想念。 表格通常不会更新,但是如果我将注意力从进行更改的单元格中移开,或者我更改了表格的大小,那么它将立即将该特定单元格的内容更改为新的选定值。

问题解决了:

我将我的发现寄给面临类似问题的人。

我在表格的每个单元格内渲染了一个按钮和一个文本框。 单击按钮时(未提供编辑器代码,因为它似乎与我无关,请单击此处),将出现一个对话框,从用户输入值并更新特定的列和行。 我在帖子末尾(在编辑1之前)提到的行无法正常工作,但是渲染器无法执行,除非我手动将焦点从所选单元格中移出(单击了其按钮)或手动更改了jtable的大小,感觉就像按钮在编辑器中,单击按钮表明该单元已被编辑,除非完成编辑(这需要聚焦或输入键等),否则将不执行偏离路线的渲染器。我将以下代码用作

table.editCellAt(-1, -1);

它从已编辑的单元格(通过按钮进行编辑)中移出焦点,因此渲染器按预期执行并正常工作。

当您使用DefaultTableModel并想要更新某个值时,需要使用DefaultTableModel#setValueAt方法。

调用此方法(当然是在事件调度线程上)将更新您的模型并触发必要的事件。 这些事件将导致您的JTable自行更新。

有关渲染器的其他几点说明:

  • 在渲染器的每次调用中创建新组件都不是可行的方法。 对于大型表,这变得异常缓慢。 在渲染器的构造函数中一次创建所有组件,然后更新它们的状态
  • 除非还具有编辑器,否则将JButton添加到渲染器中的表无效。 该按钮将不可单击,并且您附加到该按钮的动作侦听器将永远不会被调用。 有关更多信息,请参见JTable教程中渲染器和编辑器部分
  • 无需在渲染器中调用getValueAt 该值作为参数之一传入

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM