按下按钮时偶尔更新 JList

发布于 2024-10-03 02:51:33 字数 2179 浏览 0 评论 0原文

当按下按钮时,我试图更新 JList 的内容。因此,我清除了列表模型,然后清除了列表,然后继续向列表添加新值。这是剥离的代码:

testList.java

public class testList extends javax.swing.JFrame {

    private Thread t;
    public DefaultListModel model;
    public boolean first = true;

    public testList() {
        model = new DefaultListModel();
        initComponents();
        this.centre(this);
    }

    public static void centre(javax.swing.JFrame f) {
        Dimension us = f.getSize(), them = Toolkit.getDefaultToolkit().getScreenSize();
        int newX = (them.width - us.width) / 2;
        int newY = (them.height - us.height) / 2;
        f.setLocation(newX, newY);
    }

    class updateList implements Runnable {

        public void run() {
            tmp.getTheList();
            model.clear();
            ouputList.removeAll();

            for (int i = 0; i < tmp.returnList.size(); i++) {
                model.addElement(tmp.returnList.get(i));

            }
            if (first) {
                chList.setModel(model);
            }

        }
    }

    private void initComponents() {
    // generated by NetBeans 6.9
    }

    private void buttonActionPerformed(java.awt.event.ActionEvent evt) {
        t = new Thread(new updateList(), "List Updater");
        t.start();
    }

    public static void main(String args[]) {

        tmp = new aC();

        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new chapList().setVisible(true);
            }
        });
    }

    static aC tmp;

    private javax.swing.JButton button;
    public static javax.swing.JList outputList;
    private javax.swing.JScrollPane jScrollPane1;
}

ac.java

public class aC extends testList {

    ArrayList returnList = new ArrayList();

    void getTheList() {
        returnList.clear();
        generateList();
    }

    void generateList() {
    // populate returnList with random values of random size using returnlist.add()
    }
}

我面临的问题是,当第一次创建列表时,它会更新 JList。当再次按下按钮时,JList 有时只会更新。进一步按下该按钮,JList 中不会显示任何内容。

有人可以帮我找出导致这个问题的原因吗? 谢谢。

I was trying to update the contents of a JList when a button was pressed. So, I cleared the list model, then cleared the list and then proceeded to add new values to the list. Here is the stripped code:

testList.java

public class testList extends javax.swing.JFrame {

    private Thread t;
    public DefaultListModel model;
    public boolean first = true;

    public testList() {
        model = new DefaultListModel();
        initComponents();
        this.centre(this);
    }

    public static void centre(javax.swing.JFrame f) {
        Dimension us = f.getSize(), them = Toolkit.getDefaultToolkit().getScreenSize();
        int newX = (them.width - us.width) / 2;
        int newY = (them.height - us.height) / 2;
        f.setLocation(newX, newY);
    }

    class updateList implements Runnable {

        public void run() {
            tmp.getTheList();
            model.clear();
            ouputList.removeAll();

            for (int i = 0; i < tmp.returnList.size(); i++) {
                model.addElement(tmp.returnList.get(i));

            }
            if (first) {
                chList.setModel(model);
            }

        }
    }

    private void initComponents() {
    // generated by NetBeans 6.9
    }

    private void buttonActionPerformed(java.awt.event.ActionEvent evt) {
        t = new Thread(new updateList(), "List Updater");
        t.start();
    }

    public static void main(String args[]) {

        tmp = new aC();

        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new chapList().setVisible(true);
            }
        });
    }

    static aC tmp;

    private javax.swing.JButton button;
    public static javax.swing.JList outputList;
    private javax.swing.JScrollPane jScrollPane1;
}

ac.java

public class aC extends testList {

    ArrayList returnList = new ArrayList();

    void getTheList() {
        returnList.clear();
        generateList();
    }

    void generateList() {
    // populate returnList with random values of random size using returnlist.add()
    }
}

The problem I am facing is that when the list created for the first time, it updates the JList. When the button is pressed again, the JList only gets updated sometimes. And for further presses of the button nothing is displayed in the JList.

Could someone help me figure out what is causing this problem?
Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

狼性发作 2024-10-10 02:51:33

您的核心问题可能与从不是 AWT-EDT 的线程更新 Swing GUI 有关

您可能想阅读和/或研究使用 < strong>SwingWorker(随 Java 6 一起提供,并且可供下载 用于早期版本的 Java。)

或者,看看这种方法:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class BackgroundWorkerFrame extends javax.swing.JFrame {
    public BackgroundWorkerFrame() {
        initComponents();
        jList.setModel(new DefaultListModel());
    }

    private void jButtonGoActionPerformed(ActionEvent evt) {                                          
        Thread t = new Thread(new WorkerRunnable());
        t.start();
    }                                         

    public class WorkerRunnable implements Runnable {
        public void run() {
            System.out.println("Working hard...");
            sleep(1000);
            ArrayList<Integer> list = new ArrayList();
            for (int i = 0; i < 5; i++) {
                list.add((int) (Math.random() * 100));
            }
            System.out.println("Updating GUI...");
            SwingUtilities.invokeLater(new UpdateRunnable(list));
        }
    }

    public class UpdateRunnable implements Runnable {
        private final ArrayList<Integer> list;
        private UpdateRunnable(ArrayList<Integer> list) {
            this.list = list;
        }
        public void run() {
            DefaultListModel model = (DefaultListModel) jList.getModel();
            model.clear();
            for (Integer i : list) {
                model.addElement(i);
            }
        }
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jButtonGo = new JButton();
        jScrollPane = new JScrollPane();
        jList = new JList();

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        jButtonGo.setText("Go");
        jButtonGo.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                jButtonGoActionPerformed(evt);
            }
        });
        getContentPane().add(jButtonGo, BorderLayout.PAGE_START);

        jScrollPane.setViewportView(jList);

        getContentPane().add(jScrollPane, BorderLayout.CENTER);

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-309)/2, (screenSize.height-338)/2, 309, 338);
    }// </editor-fold>

    public static void sleep(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
            Thread.currentThread().interrupt();
        }
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new BackgroundWorkerFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    JButton jButtonGo;
    JList jList;
    JScrollPane jScrollPane;
    // End of variables declaration
}

Your core problem is probably related to updating the Swing GUI from a thread that isn't the AWT-EDT.

You might want to read about and/or look into using SwingWorker (shipped with Java 6 and also available for download for use with earlier versions of Java.)

Alternatively, have a look at this approach:

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;

public class BackgroundWorkerFrame extends javax.swing.JFrame {
    public BackgroundWorkerFrame() {
        initComponents();
        jList.setModel(new DefaultListModel());
    }

    private void jButtonGoActionPerformed(ActionEvent evt) {                                          
        Thread t = new Thread(new WorkerRunnable());
        t.start();
    }                                         

    public class WorkerRunnable implements Runnable {
        public void run() {
            System.out.println("Working hard...");
            sleep(1000);
            ArrayList<Integer> list = new ArrayList();
            for (int i = 0; i < 5; i++) {
                list.add((int) (Math.random() * 100));
            }
            System.out.println("Updating GUI...");
            SwingUtilities.invokeLater(new UpdateRunnable(list));
        }
    }

    public class UpdateRunnable implements Runnable {
        private final ArrayList<Integer> list;
        private UpdateRunnable(ArrayList<Integer> list) {
            this.list = list;
        }
        public void run() {
            DefaultListModel model = (DefaultListModel) jList.getModel();
            model.clear();
            for (Integer i : list) {
                model.addElement(i);
            }
        }
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    private void initComponents() {

        jButtonGo = new JButton();
        jScrollPane = new JScrollPane();
        jList = new JList();

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        jButtonGo.setText("Go");
        jButtonGo.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                jButtonGoActionPerformed(evt);
            }
        });
        getContentPane().add(jButtonGo, BorderLayout.PAGE_START);

        jScrollPane.setViewportView(jList);

        getContentPane().add(jScrollPane, BorderLayout.CENTER);

        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        setBounds((screenSize.width-309)/2, (screenSize.height-338)/2, 309, 338);
    }// </editor-fold>

    public static void sleep(long ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException ex) {
            ex.printStackTrace();
            Thread.currentThread().interrupt();
        }
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new BackgroundWorkerFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify
    JButton jButtonGo;
    JList jList;
    JScrollPane jScrollPane;
    // End of variables declaration
}
沫雨熙 2024-10-10 02:51:33

您要做的一件事是创建一个新线程,然后在 EventDispatchThread 之外对 GUI 组件进行更改。这通常不是一个好主意。尝试就地运行 updateList() ,这将在 EDT 上,因为按钮事件是在该线程中处理的。

One thing you are doing is creating a new Thread and then making changes to your GUI component outside of the EventDispatchThread. This is generally not a great idea. Try running the updateList() in place, which will be on the EDT, as the button events are handled in that thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文