java JTable 插入行并刷新
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2936098/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JTable Insert row and refresh
提问by user269723
I am trying to create simple application where JTable gets updated and refreshed after data is changed.Structure is as follows. 1)Class Main which contains JFrame,JTable details. 2)SampleTableModel class which extends AbstractTableModel.I am overriding most of the methods.
我正在尝试创建简单的应用程序,其中 JTable 在数据更改后更新和刷新。结构如下。1) 包含 JFrame、JTable 详细信息的 Main 类。2)SampleTableModel 类,它扩展了 AbstractTableModel。我覆盖了大部分方法。
import javax.swing.table.*;
import java.util.*;
public class SampleTableModel extends AbstractTableModel {
public SampleTableModel() {
// this.addTableModelListener(
}
String[] columnNames = {"A", "B", "C", "D", "E"};
int[][] data = {{1, 2, 3, 4, 5}, {5, 6, 7, 8, 9}, {12, 13, 14, 15, 16}};
Vector dataVector = new Vector();
public Object getValueAt(int rowIndex, int columnIndex) {
return data[rowIndex][columnIndex];
}
public int getColumnCount() {
return 5;
}
public int getRowCount() {
return 3;
}
public String getColumnName(int columnIndex) {
return columnNames[columnIndex];
}
public void setValueAt(Object value, int row, int column) {
data[row][column] = 99;
}
public void notifyTable(AEMessage message) {
/*
* This method will be called from another class to update JTable.
* */
data[0][1] = 999;
data[0][2] = 8838;
data[1][1] = 8883;
fireTableRowsUpdated(0, 3);
}
}
As you can see, notifyTable will be called from another class(which is actually a thread-which calls this method frequently) Problem is I don't see data being changed in JTable.I see only the initialized data. In the Main class- I am setting like this-
如您所见,notifyTable 将从另一个类(实际上是一个线程-经常调用此方法)调用。问题是我没有看到 JTable 中的数据正在更改。我只看到初始化的数据。在主班-我是这样设置的-
RVJDataTable.setModel(new SampleTableModel());
I am using DefaultTableModel instead of Abstract one to insert data.
我使用 DefaultTableModel 而不是 Abstract 来插入数据。
This is he main JTable class-
这是他的主要 JTable 类-
import javax.swing.event.TableModelListener;
import javax.swing.event.TableModelEvent;
public class MainWindow extends javax.swing.JFrame implements TableModelListener {
public MainWindow() {
initComponents();
}
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
// RVTableModel model = new RVTableModel();
TableModelWrapper wrap = new TableModelWrapper();
RVDataTable = new javax.swing.JTable();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
RVDataTable.setModel(wrap.getModel());
RVDataTable.getModel().addTableModelListener(this);
// RVDataTable.
jScrollPane1.setViewportView(RVDataTable);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(57, 57, 57)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 552, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(105, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(25, Short.MAX_VALUE)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 193, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(82, 82, 82))
);
pack();
}// </editor-fold>
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MainWindow().setVisible(true);
}
});
}
public void tableChanged(TableModelEvent evt){
System.out.println(evt.getFirstRow());
}
// Variables declaration - do not modify
private javax.swing.JTable RVDataTable;
private javax.swing.JScrollPane jScrollPane1;
// End of variables declaration
} Following class is used to define DefaultTableModel:
以下类用于定义 DefaultTableModel:
import javax.swing.table.*;
import javax.swing.event.*;
import java.util.*;
public class TableModelWrapper {
public DefaultTableModel getModel(){
Vector dataVec = new Vector();
String[] arr = {"ABS","ASAAS","ASAsA","AsaSA"};
Vector rowVec = new Vector();
for(int i=0;i<4;i++)
rowVec.add(i,arr[i] );
for(int i=0;i<5;i++)
dataVec.add(i, rowVec);
Vector columnNames = new Vector();
columnNames.add("FIRST");
columnNames.add("SECOND");
columnNames.add("THIIRD");
columnNames.add("FOURTH");
//columnNames.add("FIFTH");
DefaultTableModel model = new DefaultTableModel(dataVec,columnNames);
return model;
}
public Object[] getRecord(){
String[] arr = {"hhaHHA","HHHDS","NHHHSS","PQPPPQ"};
return arr;
}
} and follwing class adds record every 5 seconds using Stock class.
并且以下类使用 Stock 类每 5 秒添加一次记录。
public class Updater {
public static void main(String[] args){
Stock stock =new Stock();
stock.start();
}
} class Stock extends Thread{
} 类股票扩展线程{
//RVTableModel model = null;
TableModelWrapper wrap = null;
public Stock(){
wrap = new TableModelWrapper();
}
public void run(){
try{
while(true){
wrap.getModel().addRow(wrap.getRecord());
wrap.getModel().fireTableRowsInserted(wrap.getModel().getRowCount() +1,wrap.getModel().getRowCount()+1);
sleep(5000);
}
}
catch(InterruptedException e){
System.out.println(e);
}
}
} I don't see JTable getting updated.
我没有看到 JTable 得到更新。
回答by trashgod
In general, Swing is not thread safe. Consider using EventQueue.invokeLater(), mentioned here.
通常,Swing 不是线程安全的。考虑使用EventQueue.invokeLater(),这里提到。
Addendum: Given your updated example, try something like this:
附录:鉴于您更新的示例,请尝试以下操作:
@Override
public void run() {
while (true) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
wrap.getModel().addRow(wrap.getRecord());
}
});
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
Addendum: SwingWorker, discussed hereis another alternative means of updating the GUI from another thread.
附录:SwingWorker,这里讨论的是从另一个线程更新 GUI 的另一种替代方法。
回答by camickr
Based on the code provided it looks like it should work but the code is not complete so I can't say for sure. Maybe your "other" class has a reference to the wrong TableModel?
根据提供的代码,它看起来应该可以工作,但代码不完整,所以我不能肯定。也许您的“其他”类引用了错误的 TableModel?
Also, there is nothing special about your data so why not just use the DefaultTableModel. You can then update the table using:
此外,您的数据没有什么特别之处,所以为什么不直接使用 DefaultTableModel。然后,您可以使用以下方法更新表:
table.setValueAt( 123, 0, 0 );
table.setValueAt( 456, 0, 1 );
If you need more help post your SSCCE.
如果您需要更多帮助,请发布您的SSCCE.

