如何使用始终更改的tableModel刷新JTable?

时间:2015-05-04 15:50:55

标签: java swing jtable defaulttablemodel

  

2015.5.5 22:11更新。我发现,当我创建一个分拣机并在MyTable的构造中调用setRowSorter()方法时,之后,它   将保留原始行号(数据仍在刷新   正确但不容易发现)即使里面的dataModel是   已经多次改变,可以证明   的printf(getModel()。getRowCount())。还有什么,   MyTable.getAutoCreateRowSorter()始终返回true。我必须明确   如果我调用的话,调用setAutoCreateRowSorter(true)来修复它的问题   setRowSorter()。我很高兴,但这仍然很奇怪。

  

[2015.5.5 6:19已更新]我找到了一种访问方式:制作一个" setRow"与insertRow()和removeRow()的组合,每次我   更新,我setrRow表中的所有行。它立即反映出来   用户界面。但是会出现一系列错误,以" AWT-EventQueue-0" java.lang.IndexOutOfBoundsException:索引无效"我猜它是关于摇摆线程问题的一些因素,因为我可以看到" RepaintManager"或"画"在错误中。当它在滚动条运行时移动时会发生这种情况。(但如果我不移动滚动条,它仍会出现)

我在JFrame的JScrollPane中有一个JTable。我用一个数据初始化一个MyTableModel并用它来创建一个JTable.Like这个

MyTableModel extends DefaultTableModel{
    Data data;
    //object

    MyTableModel (Data a){
    data = a;
    // do something to initial the table model,like build object[][] and add rows.   
    }
}
class main{
MyTableModel tm = new MyTableModel(data);
Jtable table = new JTable(tm);
JScrollpane jsp = new JScrollpane(table);
JFrame window = new JFrame();
window.getxxxpane().add(jsp);



}

因此,由于我的数据总是在更改/更新,而且更改的行是复数,无法计算。

while(true){
    data.change();

    refreshing the table to display the data immediately;

}

我的想法是简单地构建一个新的MyTableModel对象并将其设置为表的模型,如:

 table.setModel(new MyTableModel(data));   //data had been changed.

哪个不起作用。 我试过这个:

  tm = MyTableModel(data);
  tm.fireTableDataChanged();

也不起作用。 和组合:

  MyTableModol nm = new MyTableModel(data); //data had been changed
  table.setModel(nm);
  nm.fireTableDataChanged();

有人可以给我一些线索来改变不可更改的Jtable中的TableModel对象并每次更新。我不想更改tableModel对象,因为计算量很大,相反,我想总是用结构创建一个新对象方法的参数(已更改的数据)。

最糟糕的方法是删除JScrollpane并重建一个table / tablemodel / jscrollpane并重新添加它,我必须调用window.setVisible(true)。 window.repait()也不起作用,除非我移动它。 我创建了一个浪费空间但可运行的程序来进行演示,其中大部分都是无意义的。

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Formatter;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

class TM extends DefaultTableModel {
    int[] inside;
    static String[] columnNames = { "Hellium", "Radon",

    };

    TM(int[] data) {
        super(columnNames, 0);
        this.inside = data;
        update();
    }

    void update() {
        Object[][] data = new Object[2][columnNames.length];

        for (int i = 0; i < 2; ++i) {

            data[i][0] = inside[0];

            data[i][1] = inside[1];
           // setValueAt(aValue, row, column);
            addRow(data[i]);

        }
        fireTableDataChanged();
    }

}

class idkName {
    TM tm;
    JButton jb, jb2;
    int data[] = { 1, 2 };
    int data2[] = { 9, 10 };
    JTable table;
    JScrollPane jsp;
    JFrame twindow;

    idkName() {
        JFrame window = new JFrame();
        window.setSize(400, 400);
        window.setLayout(new BorderLayout());
        jb = new JButton("show");
        jb2 = new JButton("change model");
        window.add(jb, BorderLayout.EAST);
        window.add(jb2, BorderLayout.WEST);
        twindow = new JFrame();

        jb.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                tm = new TM(data);
                table = new JTable(tm);
                jsp = new JScrollPane(table);
                twindow.getContentPane().add(jsp);
                twindow.setSize(500, 500);
                twindow.setVisible(true);

            }
        });
        window.setVisible(true);

        jb2.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                // tm = new TM(data2);

                tm = new TM(data2);

                System.out.println(""+tm.getValueAt(0,0));
                tm.fireTableDataChanged(); 
                twindow.setVisible(true); 

            }
        });

    }
}
public class main2 {
    TM tm;
    public static void main(String[] args) {
        idkName i = new idkName();
    }

}

1 个答案:

答案 0 :(得分:1)

如果您要扩展DefaultTableModel,那么当数据发生变化时,您需要使用DefaultTableModelsetValueAt的内部代表中更新数据或setDataVector方法。如果您有大量更改(听起来像这样),请使用setDataVector方法立即更改所有单元格和表格结构。您的示例代码看起来似乎缺少某些更新,因为它没有将新值推送到DefaultTableModel的数据向量中。

但是,由于您有大量更新,因此最好避免DefaultTableModel,只使用您自己的自定义数据存储扩展AbstractTableModel,并调用相应的{{1}数据发生变化时的方法。就数据转换和引发的事件数量而言,这可能会更有效。

然后确保使用fireXxx()或其他线程支持在AWT事件线程上完成所有事件和值更改工作。