使用Swing JTable重绘表问题

时间:2015-06-21 10:41:20

标签: java 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行的更改数据,colum 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);

从已编辑的单元格(使用按钮编辑)聚焦,因此渲染器按预期执行并工作。

1 个答案:

答案 0 :(得分:2)

当您使用group并且想要更新某个值时,需要使用res = re.match("^.*(?=(\())", search_result.text) if res: # ... 方法。

调用此方法(当然,在Event Dispatch Thread上)将更新模型并触发必要的事件。这些事件会导致DefaultTableModel自行更新。

关于渲染器的一些补充说明:

  • 在渲染器的每次调用中创建新组件都不是可行的方法。对于大型表来说,这变得非常慢。在渲染器的构造函数中创建一次所有组件,然后只更新其状态
  • 在渲染器中向表中添加DefaultTableModel#setValueAt无效,除非您还有编辑器。该按钮不可单击,并且永远不会调用您附加到该按钮的动作侦听器。有关详细信息,请参阅renderers and editors section in the JTable tutorial
  • 不需要在渲染器中调用JTable。该值作为参数之一
  • 传入