按下按钮时偶尔更新列表

时间:2010-11-19 01:12:36

标签: java swing jlist

按下按钮时,我试图更新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中不会显示任何内容。

有人可以帮我找出造成这个问题的原因吗? 感谢。

2 个答案:

答案 0 :(得分:3)

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

您可能希望阅读和/或研究使用SwingWorker(Java 6附带以及available for download与早期版本的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
}

答案 1 :(得分:1)

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