简体   繁体   English

使用Swing JTable重绘表问题

[英]Repaint Table issue with Swing JTable

I am working with swing JTable and have a trouble with repainting table. 我正在使用Swing JTable ,但在重新绘制表时遇到了麻烦。 I draw a JTable with thr following code 我用以下代码绘制了一个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);

Below is my table renderer code .. 下面是我的表格渲染器代码..

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;

}

this is how i am updating contents of a cell in table.. 这就是我更新表中单元格内容的方式。

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

I am updating the table model data via the SelectionDialog for eg change data at row 0, colum 0 to E7 etc. After changing data in table model i have tried the following options but none of them has refreshed the table data in view however the data in model of JTable was updated correctly. 我正在通过SelectionDialog更新表模型数据,例如将行0,列0更改为E7等。在表模型中更改数据后,我尝试了以下选项,但是它们均未刷新视图中的表数据,但是该数据在JTable模型中已正确更新。 If I add a new row on the fly and then call the below methods then every thing work fine but if I modify data in the model of an existing row then none of the solution mentioned below is working 如果我即时添加新行,然后调用以下方法,则一切正常,但如果我修改现有行模型中的数据,则以下提到的解决方案均无法正常工作

//((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();

Please provide any insights about the problem as I am to swing and may have missed some very prominent things. 请提供有关此问题的任何见解,因为我可能会错过一些非常突出的事情。

Edit 1: Just adding one more note which i wanted to place earlier but don't know how i missed. 编辑1:只是添加了一个我想更早放置的音符,但不知道我怎么想念。 Table is not updated in general but if i focus out from the cell in which change was made or i change the size of table then it immediately change the contents of that particular cell to fresh selected value. 表格通常不会更新,但是如果我将注意力从进行更改的单元格中移开,或者我更改了表格的大小,那么它将立即将该特定单元格的内容更改为新的选定值。

Problem Solved: 问题解决了:

I am placing my findings for someone who is facing similar problem. 我将我的发现寄给面临类似问题的人。

I rendered a button and a text box inside each cell in my table. 我在表格的每个单元格内渲染了一个按钮和一个文本框。 When button was clicked (Editor code is not provided as it looks irrelevant to me to place here) a dialog appear which inputs value from user and update the specific column and row. 单击按钮时(未提供编辑器代码,因为它似乎与我无关,请单击此处),将出现一个对话框,从用户输入值并更新特定的列和行。 The lines i mentioned as not working at the end of my post (before edit 1) were working correctly however renderer was not executing unless i manually focus out from the selected cell (whose button was clicked) or manually change the size of jtable which make sense as button was inside editor and button click shows that cell is edited and off-course renderer will not execute unless editing is finished which requires focus out or enter key etc. I applied the following code as 我在帖子末尾(在编辑1之前)提到的行无法正常工作,但是渲染器无法执行,除非我手动将焦点从所选单元格中移出(单击了其按钮)或手动更改了jtable的大小,感觉就像按钮在编辑器中,单击按钮表明该单元已被编辑,除非完成编辑(这需要聚焦或输入键等),否则将不执行偏离路线的渲染器。我将以下代码用作

table.editCellAt(-1, -1);

It focus out from the edited cell (edited with the button) and hence renderer executes and work as expected. 它从已编辑的单元格(通过按钮进行编辑)中移出焦点,因此渲染器按预期执行并正常工作。

When you are using a DefaultTableModel and you want to update a certain value, you need to use the DefaultTableModel#setValueAt method. 当您使用DefaultTableModel并想要更新某个值时,需要使用DefaultTableModel#setValueAt方法。

Calling this method (on the Event Dispatch Thread of course) will update your model and fire the necessary events. 调用此方法(当然是在事件调度线程上)将更新您的模型并触发必要的事件。 Those events will cause your JTable to update itself. 这些事件将导致您的JTable自行更新。

A few additional remarks about your renderer: 有关渲染器的其他几点说明:

  • Creating new components in each call of your renderer is not the way to go. 在渲染器的每次调用中创建新组件都不是可行的方法。 This becomes incredibly slow for large tables. 对于大型表,这变得异常缓慢。 Create all components once in the constructor of your renderer, and just update their state 在渲染器的构造函数中一次创建所有组件,然后更新它们的状态
  • Adding a JButton to your table in the renderer has no effect, unless you have an editor as well. 除非还具有编辑器,否则将JButton添加到渲染器中的表无效。 The button will not be clickable, and the action listener you attach to it will never be called. 该按钮将不可单击,并且您附加到该按钮的动作侦听器将永远不会被调用。 See the renderers and editors section in the JTable tutorial for more information. 有关更多信息,请参见JTable教程中渲染器和编辑器部分
  • There should be no need to call getValueAt in your renderer. 无需在渲染器中调用getValueAt The value is passed in as one of the arguments 该值作为参数之一传入

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

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