按下按钮时,我试图更新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中不会显示任何内容。
有人可以帮我找出造成这个问题的原因吗? 感谢。
答案 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上,因为按钮事件在该线程中处理。