简体   繁体   English

按下按钮时JList的更新

[英]Occational updating of JList on button press

I was trying to update the contents of a JList when a button was pressed. 当按下按钮时,我试图更新JList的内容。 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 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 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. 我面临的问题是,当第一次创建列表时,它会更新JList。 When the button is pressed again, the JList only gets updated sometimes. 再次按下该按钮时,JList有时只会更新。 And for further presses of the button nothing is displayed in the JList. 并且为了进一步按下按钮,JList中不显示任何内容。

Could someone help me figure out what is causing this problem? 有人可以帮我找出造成这个问题的原因吗? Thanks. 谢谢。

Your core problem is probably related to updating the Swing GUI from a thread that isn't the AWT-EDT . 您的核心问题可能与从非AWT-EDT的线程更新Swing GUI有关。

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.) 您可能希望阅读和/或了解如何使用SwingWorker (Java 6附带,也可以下载以用于早期版本的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
}

One thing you are doing is creating a new Thread and then making changes to your GUI component outside of the EventDispatchThread. 您要做的一件事是创建一个新的Thread,然后在EventDispatchThread之外更改GUI组件。 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. 尝试运行updateList() ,它将在EDT上,因为按钮事件在该线程中处理。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM