Java 刷新JTable的最佳方法是什么?
有谁能告诉我刷新JTable的最佳方法吗?我曾尝试从另一个线程使用Java 刷新JTable的最佳方法是什么?,java,swing,jtable,tablemodel,thread-sleep,Java,Swing,Jtable,Tablemodel,Thread Sleep,有谁能告诉我刷新JTable的最佳方法吗?我曾尝试从另一个线程使用table.repaint(),但我不知道这是否是最好的方法 我的代码: 类别:型号 public class CLS_ValueUpdater extends Thread { private String sRowName; private String sValue; public CLS_ValueUpdater(String sRowName) { this.sRowName
table.repaint()
,但我不知道这是否是最好的方法
我的代码:
类别:型号
public class CLS_ValueUpdater extends Thread {
private String sRowName;
private String sValue;
public CLS_ValueUpdater(String sRowName) {
this.sRowName = sRowName;
this.start();
}
public String getValue() {
return this.sValue;
}
public String getRowName() {
return sRowName;
}
public void setRowName(String sRowName) {
this.sRowName = sRowName;
}
public void run() {
try {
for (int i = 0; i <= 100; i++) {
this.sValue = String.valueOf(i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
那么,有没有什么优雅的方法可以自动更新JTable?提前谢谢 DefaultTableModel#setValueAt()的javadoc说: 在列和行设置单元格的对象值。阿瓦鲁是 新的价值观。此方法将生成tableChanged通知 因此,如果通过调用
model.setValueAt()
更改内容,也将触发重新绘制
注意:model
是JTable
的TableModel
我尝试从另一个线程使用table.repaint()
如果没有另一条线,你的桌子就不会被重新粉刷了
您想用进度条更新jtable。您可能对使用SwingWorker
感兴趣。这是一份完整的报告
也许打电话比较好
void fireTableRowsInserted(int firstRow,int lastRow)
如果要每1秒刷新一次表,请使用单独的线程进行刷新;不要忘记使用invokeLater方法
new Thread(new Runnable(){
public void run()
{
while(true)
{
Thread.sleep(1000);
SwingUtilities.invokeLater(new Runnable(){
public void run()
{
_tableModel.fireTableDataChanged();
}
});
}
}
}).start();
这个问题的代码太多了。为什么不裁剪它以显示更新JTable的位置呢?这是
setValueAt
是您所需要的全部。如果在使用setValueAt
时视图未更新,则表模型中存在错误。我的代码是MVC实现。我需要一直自动更新Jtable的每一项(比如一些进度值)。那么你是在问如何更新你的表模型吗?或者什么。他没有使用默认的表格模式。你不明白我。。。我需要一直更新插入的值,因为我正在编写一个小型多重下载程序,我需要查看下载进度值,所以Jtable需要一直自动更新下载进度。对不起,我的英语不好。谢谢你的回复,我现在明白了。。你可能对SwingWorker感兴趣,为什么不使用一个JProgressBar
?@Radu Murzea-实际上,这里的问题是知道如何做一件事,而不是寻找替代品。但是谢谢你的回复。@SamuelPedrosa我编辑了答案,希望对你有帮助。我曾经尝试过这种方法,但是如果我选择了JTable的任何一行,它在刷新时会被取消选择,但是使用JTable.repaint不会发生。对不起,英语不好。感谢您的回复!sceleton是正确的,所有更新都必须在EDT上完成,但不要调用模型外的任何通知程序,这是模型的重要部分,请参见@nachokk,-1(强调@mKorbel)的回答,不要代表模型触发事件-永远不要
public class FRM_Main {
private JFrame frame;
private JTable table;
private CLS_Controller tModel = new CLS_Controller();
private JTextField textField;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
FRM_Main window = new FRM_Main();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public FRM_Main() {
try {
for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
if ("Windows".equals(info.getName())) {
UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 476, 283);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.getContentPane().add(panel, BorderLayout.CENTER);
JScrollPane scrollPane = new JScrollPane();
JButton btnNewButton = new JButton("Add");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
tModel.addRow(textField.getText());
}
});
JButton btnNewButton_1 = new JButton("Delete");
textField = new JTextField();
textField.setColumns(10);
GroupLayout gl_panel = new GroupLayout(panel);
gl_panel.setHorizontalGroup(gl_panel
.createParallelGroup(Alignment.LEADING)
.addGroup(
gl_panel.createSequentialGroup()
.addContainerGap()
.addGroup(
gl_panel.createParallelGroup(
Alignment.LEADING)
.addComponent(
scrollPane,
GroupLayout.DEFAULT_SIZE,
440, Short.MAX_VALUE)
.addGroup(
Alignment.TRAILING,
gl_panel.createSequentialGroup()
.addComponent(
textField,
GroupLayout.PREFERRED_SIZE,
GroupLayout.DEFAULT_SIZE,
GroupLayout.PREFERRED_SIZE)
.addPreferredGap(
ComponentPlacement.RELATED)
.addComponent(
btnNewButton)
.addPreferredGap(
ComponentPlacement.RELATED,
216,
Short.MAX_VALUE)
.addComponent(
btnNewButton_1)))
.addContainerGap()));
gl_panel.setVerticalGroup(gl_panel
.createParallelGroup(Alignment.LEADING)
.addGroup(
gl_panel.createSequentialGroup()
.addContainerGap()
.addComponent(scrollPane,
GroupLayout.PREFERRED_SIZE, 194,
GroupLayout.PREFERRED_SIZE)
.addPreferredGap(ComponentPlacement.RELATED)
.addGroup(
gl_panel.createParallelGroup(
Alignment.BASELINE)
.addComponent(btnNewButton_1)
.addComponent(
textField,
GroupLayout.PREFERRED_SIZE,
GroupLayout.DEFAULT_SIZE,
GroupLayout.PREFERRED_SIZE)
.addComponent(btnNewButton))
.addContainerGap(80, Short.MAX_VALUE)));
table = new JTable();
table.setShowVerticalLines(false);
table.setShowHorizontalLines(false);
table.setFillsViewportHeight(true);
table.setModel(tModel);
new tableUpdater(table);
scrollPane.setViewportView(table);
panel.setLayout(gl_panel);
}
}
class tableUpdater extends Thread {
private JTable tTable;
public tableUpdater(JTable tTable) {
this.tTable = tTable;
this.start();
}
public void run() {
try {
while (true) {
tTable.repaint();
Thread.sleep(2000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MySwingWorker extends SwingWorker <String,String>{ //what params you want here
@Override
protected String doInBackground()throws Exception{
//here you download heavy task
//and you call publish() when you want
}
@Override
protected void process(List<String> chunks){
// here you updated your gui
//setValueAt(row,col); and fireTableCellUpdated(row,col);
}
@Override
protected void done(){
//here is called when doInBackGround is finished
}
public void addRow(String sName) {
this.tListUpdater.add(new CLS_ValueUpdater(sName));
this.fireTableDataChanged();
}
new Thread(new Runnable(){
public void run()
{
while(true)
{
Thread.sleep(1000);
SwingUtilities.invokeLater(new Runnable(){
public void run()
{
_tableModel.fireTableDataChanged();
}
});
}
}
}).start();