前言,我意识到这可能是一个Event Dispatch Thread问题。我只是不确定问题究竟在哪里。
我有一个JList,它使用AbstractListModel查询对象并将结果显示为列表:
public class View {
public View(final Person person) {
JList list = new JList(new AbstractListModel() {
@Override
public Object getElementAt(int index) {
return person.getSibling(index);
}
@Override
public int getSize() {
return person.getNumSiblings();
}
});
}
最初,JList看起来很好 - 它显示了所有“Person”自动构造的兄弟姐妹。但是,当我在我的代码的另一个区域使用person.addSibling(...)之类的东西时,JList变成空白。
这是EDT问题吗? (看来在更新Person之后,不再调用AbstractListModel的方法。)
如果是这样,我应该在哪里添加SwingWorker代码 - 在AbstractListModel内部或在person.addSibling(...)内部?
谢谢!
编辑:
我附加一个简单的,可运行的版本:
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
final Person person = new Person();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
JFrame frame = new JFrame();
frame.setPreferredSize(new Dimension(1024, 768));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setExtendedState(frame.getExtendedState() | JFrame.MAXIMIZED_BOTH);
JPanel panel = new JPanel();
frame.setContentPane(panel);
JList list = new JList(new AbstractListModel() {
@Override
public Object getElementAt(int index) {
return person.getSibling(index);
}
@Override
public int getSize() {
return person.getNumSiblings();
}
});
panel.add(list);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
person.addSibling("Bob");
} catch (Throwable ex) {
ex.printStackTrace();
}
}
});
}
private static class Person {
List<String> siblings = new ArrayList<String>();
public Person() {
siblings.add("Janice");
}
public void addSibling(String sibling) {
siblings.add(sibling);
}
public Object getSibling(int index) {
return siblings.get(index);
}
public int getNumSiblings() {
return siblings.size();
}
}
}
答案 0 :(得分:3)
这与EDT或线程无关。当模型的数据核发生变化时,你不会调用任何模型的通知方法fireXXXX(...)
,而这会弄乱它。我建议你解决这个问题。 AbstractListModel API将显示在列表中添加或删除数据时可用的方法。
编辑1
此外,您的模型应该在一个非匿名类中,该类扩展AbstractListModel<String>
并且具有addSibling(String sib)
方法。您应该将兄弟添加到模型而不是Person对象。
编辑2 ,例如
import java.util.List;
import javax.swing.AbstractListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
final Person person = new Person();
final SibListModel listModel = new SibListModel(person);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.setContentPane(panel);
JList<String> list = new JList<String>(listModel);
panel.add(new JScrollPane(list));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
// person.addSibling("Bob");
listModel.addSibling("Bob");
} catch (Throwable ex) {
ex.printStackTrace();
}
}
});
}
private static class SibListModel extends AbstractListModel<String> {
private Person person;
public SibListModel(Person person) {
this.person = person;
}
@Override
public String getElementAt(int index) {
return person.getSibling(index);
}
@Override
public int getSize() {
return person.getNumSiblings();
}
public void addSibling(String sib) {
person.addSibling(sib);
fireIntervalAdded(this, person.getNumSiblings() - 1, person.getNumSiblings());
}
}
private static class Person {
List<String> siblings = new ArrayList<String>();
public Person() {
siblings.add("Janice");
}
public void addSibling(String sibling) {
siblings.add(sibling);
}
public String getSibling(int index) {
return siblings.get(index);
}
public int getNumSiblings() {
return siblings.size();
}
}
}