java - 在另一个线程上更新 DefaultListModel

标签 java multithreading swing jframe

我有一个程序需要更新 JList 的内容,它是另一个线程上的 DefaultListModel。由于内容的数量可能会不时发生变化,所以我只是在更新时清除所有内容并将新内容添加到DefaultListModel中。但似乎我遇到了一个问题,即 JFrame 在我的线程进行更新时开始刷新。我有这样的异常

Exception in thread "AWT-EventQueue-0" 
java.lang.ArrayIndexOutOfBoundsException: 3

这是一个代码示例

    DefaultListModel model;
    JList jList;
    JScrollPane jScrollPane;

    Thread thread;
    public Frame() {
        this.setTitle("ASM_SIMULATOR");
        this.setBounds(100, 100, 500, 500);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.getContentPane().setLayout(null);

        model = new DefaultListModel();
        jList = new JList(model);
        jScrollPane = new JScrollPane(jList);

        jList.setBounds(50, 50, 300, 200);
        jScrollPane.setBounds(50, 50, 300, 200);

        this.getContentPane().add(jScrollPane);

        this.setVisible(true);

        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {

                    makeData();
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }

        });

        thread.start();
    }

    public void makeData() {
        System.out.println("makeData()");
        model.clear();

        for (int i = 0; i < 20; i++) {
            model.addElement((int) (Math.random() * 100));
        }

    }

    public static void main(String[] args) {
        new Frame();

    }

最佳答案

您在该代码段中两次违反了基本的“所有 Swing 组件都应在事件调度线程 (=EDT) 上访问/修改,并且仅在 EDT 上”。

  1. 您的主要方法应该将 new Frame() 调用包装在 SwingUtilities#invokeLater 或一些类似的方法中
  2. 您的模型更新线程在后台线程上更改模型。更新模型将触发由 JList 接收的事件,JList 会在这些事件上更新自身(同样,在错误的线程上)。

两种可能的解决方案:

  • 在您的后台线程上创建一个新的 DefaultListModel,并在 EDT 上一次性替换它。
  • 不断更新现有模型,但要确保更新发生在 EDT 上。

关于java - 在另一个线程上更新 DefaultListModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13097935/

相关文章:

java - 从 PHP 向 Java 发送信息

c# - 不同的线程在 WPF 中拥有它

c# - 过期异步调用操作

java - JComboBox:如何获得适用于 HTML 条目的键选择?

java - 尝试使用关键监听器,但形状不会移动

java - Spring 和 Hibernate 运行时错误

java - 编辑 MultiPartEntity 的标题

Java 切换按钮事件在选择完成时不会触发,但在鼠标悬停时触发

java - 同步(oswego)与锁定(JDK5)

java - 在java中的分割 Pane 上添加jpanels