sdasdadas
sdasdadas

Reputation: 25096

Why does my JList dissapear when updated?

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();
        }

    }

}

Upvotes: 1

Views: 130

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285403

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 an addSibling(String sib) method. You should add the sibling to the model not the Person object.

Edit 2 e.g.,

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();
      }

   }

}

Upvotes: 3

Related Questions