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();
}
}
答案 0 :(得分:1)
如果您要扩展DefaultTableModel
,那么当数据发生变化时,您需要使用DefaultTableModel
在setValueAt
的内部代表中更新数据或setDataVector
方法。如果您有大量更改(听起来像这样),请使用setDataVector
方法立即更改所有单元格和表格结构。您的示例代码看起来似乎缺少某些更新,因为它没有将新值推送到DefaultTableModel
的数据向量中。
但是,由于您有大量更新,因此最好避免DefaultTableModel
,只使用您自己的自定义数据存储扩展AbstractTableModel
,并调用相应的{{1}数据发生变化时的方法。就数据转换和引发的事件数量而言,这可能会更有效。
然后确保使用fireXxx()
或其他线程支持在AWT事件线程上完成所有事件和值更改工作。