To preface, I realize this is probably an Event Dispatch Thread issue. I am just unsure where exactly the issue lies.
I have a JList that uses an AbstractListModel to query an object and display the results as a list:
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();
}
});
}
Initially, the JList looks fine – it displays the one sibling that all “Person”s are automatically constructed with. However, when I use something like person.addSibling(…) in another area of my code then the JList turns blank.
Is this an EDT issue? (It appears that after updating a Person the AbstractListModel’s methods are no longer called.)
If so, where should I add the SwingWorker code – inside of the AbstractListModel or inside of the person.addSibling(…)?
Thanks!
EDIT:
I am appending a simple, runnable version:
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();
}
}
}
This has nothing to do with the EDT or threading. You’re not calling any of the model’s notification methods,
fireXXXX(...)when the data nucleus of the model changes, and this is messing it up. I suggest you fix this. the AbstractListModel API will show the methods that are available for when data is added or removed from the list.Edit 1
Also your model should be in a non-anonymous class that extends
AbstractListModel<String>and that has anaddSibling(String sib)method. You should add the sibling to the model not the Person object.Edit 2 e.g.,