1

はじめに、これはおそらくイベントディスパッチスレッドの問題であると思います。問題がどこにあるのかよくわかりません。

AbstractListModelを使用してオブジェクトをクエリし、結果をリストとして表示するJListがあります。

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」が自動的に作成される1つの兄弟が表示されます。ただし、コードの別の領域で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();
        }

    }

}
4

1 に答える 1

3

これは、EDTやスレッド化とは何の関係もありません。モデルのデータニュークリアスが変更されたときに、モデルの通知メソッドを呼び出していません。これにより、fireXXXX(...)モデルが台無しになります。これを修正することをお勧めします。AbstractListModel APIは、データがリストに追加またはリストから削除されたときに使用できるメソッドを表示します。

編集1また、モデルは、拡張され、 メソッドを持つ
非匿名クラスに含まれている必要があります。Personオブジェクトではなく、モデルに兄弟を追加する必要があります。AbstractListModel<String>addSibling(String sib)

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

   }

}
于 2012-12-04T20:04:26.817 に答える