【问题标题】:Insert Row in JTable using Thread使用线程在 JTable 中插入行
【发布时间】:2018-02-26 09:31:11
【问题描述】:

我是 Java 新手Swing。我花了很多时间试图找到一种使用run() 方法将行插入JTable 的方法,但还没有找到。所以,谁能给我一个解决方案。

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

public class ShowTable extends JFrame {
    JFrame f=new JFrame();
    JTable jt=new JTable(new DefaultTableModel());
    DefaultTableModel model=(DefaultTableModel)jt.getModel();

    public void showdata(int count, String host, String ip, String os_name, String os_arch, String os_version, String pro_detail, String Mac_add, float  disk_size, float max_memory) {
        System.out.println("Row  :"+count);
        Object data[] = {host, ip, os_name, os_arch, os_version, pro_detail, Mac_add, disk_size, max_memory};
        if (count == 0)
        {       
            model.addColumn("HOSTNAME");
            model.addColumn("IP ADDRESS");
            model.addColumn("OS NAME");
            model.addColumn("OS ARCHITECTURE");
            model.addColumn("OS VERSION");
            model.addColumn("PROCESSOR DETAIL");
            model.addColumn("MAC ADDRESS");
            model.addColumn("HARD DISK");
            model.addColumn("RAM SIZE");
            model.addRow(data);  
        }
        else
        {
            model.addRow(data);
        }
        jt.setBounds(30,40,200,300);
        jt.setFocusable(false);
        jt.setRowSelectionAllowed(false);
        JScrollPane sp = new JScrollPane(jt);
        f.add(sp);
        f.setSize(1300,100);
        f.setVisible(true);
    }

    public static void main() {
        JScrollPane jScrollPane1;
        JTable jTable1;
    }
}

我编写了这段代码,但每次执行run() 方法时它只显示一个空白框。

【问题讨论】:

  • 排序答案是,不要。 Swing 不是线程安全的,您不应从事件调度线程的上下文之外对 UI 进行修改。相反,您可以使用SwingWorker,这将允许您在 EDT 之外执行操作(并且不会阻止 UI),但它提供了一种安全更新 UI 的简化方法。 For example
  • example
  • @MadProgrammer 感谢您的宝贵回答。实际上,我正在使用套接字编程制作客户端服务器应用程序。其中它们是由服务器使用多线程处理的多个客户端。所以,我必须在 JTable 中基本展示客户端的硬件级别规范

标签: java multithreading swing jframe jtable


【解决方案1】:

其他线程的修改应由 SwingUtilities.invokeLater 进行,例如:

SwingUtilities.invokeLater(() -> {
    // code to be invoked in awt thread
});

下面的工作示例(每秒添加新行):

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.tree.DefaultMutableTreeNode;
import java.awt.*;

public class ShowTable extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            startApp();
        });

    }

    static void startApp(){
        JFrame frame = new JFrame();


        DefaultTableModel model = new DefaultTableModel(0, 1);
        JTable table = new JTable(model);
        frame.getContentPane().add(new JScrollPane(table));

        frame.setSize(new Dimension(800, 600));
        frame.setVisible(true);

        new Thread(){
            @Override
            public void run() {
                while(true) {
                    SwingUtilities.invokeLater(() -> {
                        model.addRow(new Object[]{"some data"});

                    });
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
    }
}

【讨论】:

  • 密钥是使用SwingUtilties.invokeLater(...)。这将确保代码在Event Dispatch Thread (EDT) 上执行。请参阅Concurrency 上的 Swing 教程,了解为什么这很重要。本教程还介绍了SwingWorker 的用法
  • 是的,这很重要。也许直接将其添加到我的答案中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-11
  • 2021-11-21
相关资源
最近更新 更多