2012-07-11 2 views
2

HashSet의 내용을 JList에 표시하고 싶습니다. 나는 다음과 같은 문이 달성 :JList 및 실시간 항목 업데이트에 HashSet 표시

JList list = new JList(hashset.toArray()); 

지금, hashset의 변화를 반영하기 위해 list을하고 싶습니다. 나는 hashset의 요소는 다음과 같이 변경 될 때 setListData()를 호출하여이 작업을 수행 할 수 있습니다 :

list.setListData(hashset.toArray()); 

이 그것을 할 수있는 적절한 방법이 될 것 같지 않습니다. tutorial에서 알 수 있듯이 ListModel을 확장/구현해야합니다. 내 의도에 해당하는 경우 ListModel의 오버로드에 대한 적절한 예를 제공하십시오. 그렇지 않으면 친절하게도 더 나은 접근 방식을 제안하십시오.

미리 감사드립니다.

+1

편집 : 나는 또한 [하는 AbstractListModel] 확장 할 것 (http://docs.oracle.com/javase/7/docs/api/javax/swing를 /AbstractListModel.html) 클래스를 사용하고 [ListModel] (http://docs.oracle.com/javase/7/docs/api/javax/swing/ListModel.html) 인터페이스 만 사용하면 안됩니다. 이렇게하면 데이터가 변경되면 모든 리스너에게 알리는'fireXXX (...)'메소드를 사용할 수 있습니다. –

+0

@HovercraftFullOfEels 답장을 보내 주셔서 감사합니다. :) 아마도 대신 TreeSet을 사용할 것입니다. 내 자신을 구현 ListModel에 관해서는 - 나는 실제로 시도했다. Set에 캡슐화하는 방법과 ListDataListeners로 처리하는 방법을 이해할 수 없었습니다. – Vlad

+0

엄밀히 말하면'HashSet'인가, 아니면 단순히 비슷한 기능과 성능을 지닌 속성일까요? –

답변

1

채팅에 관한 토론 에서처럼 가능한 해결책은 다음과 같습니다. 나는 디버깅도이 있으므로주의의 위험 부담 테스트하지 않았습니다 :

import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import java.util.Comparator; 
import java.util.Iterator; 
import java.util.TreeSet; 

import javax.swing.*; 

public class TreeSetInJListTest extends JPanel { 
    private static final long serialVersionUID = 1L; 
    private static final String[] DATA_ARRAY = { "one", "two", "three", "two", 
     "three", "this is a longer string" }; 
    TreeSetListModel<String> stringListModel = new TreeSetListModel<String>(
     String.CASE_INSENSITIVE_ORDER); 
    JList<String> jList = new JList<String>(stringListModel); 

    public TreeSetInJListTest() { 
     for (int i = 0; i < DATA_ARRAY.length; i++) { 
     stringListModel.add(DATA_ARRAY[i]); 
     } 

     add(new JScrollPane(jList)); 
     add(new JButton(new AddToListAction("Add To List", KeyEvent.VK_A))); 
    } 

    @SuppressWarnings("serial") 
    private class AddToListAction extends AbstractAction { 
     public AddToListAction(String name, int mnemonic) { 
     super(name); 
     putValue(MNEMONIC_KEY, mnemonic); 
     } 

     @Override 
     public void actionPerformed(ActionEvent arg0) { 
     String element = JOptionPane.showInputDialog(TreeSetInJListTest.this, 
       "Enter String:", "Insert Text Into JList", 
       JOptionPane.OK_CANCEL_OPTION); 
     stringListModel.add(element); 
     } 
    } 

    private static void createAndShowGui() { 
     TreeSetInJListTest mainPanel = new TreeSetInJListTest(); 

     JFrame frame = new JFrame("Example"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

class TreeSetListModel<T extends Comparable<T>> extends AbstractListModel<T> { 
    private static final long serialVersionUID = 1L; 
    private TreeSet<T> treeSet; 

    public TreeSetListModel() { 
     treeSet = new TreeSet<T>(); 
    } 

    public TreeSetListModel(Comparator<? super T> comparator) { 
     treeSet = new TreeSet<T>(comparator); 
    } 

    @Override 
    public T getElementAt(int index) { 
     if (index < 0 || index >= getSize()) { 
     String s = "index, " + index + ", is out of bounds for getSize() = " 
       + getSize(); 
     throw new IllegalArgumentException(s); 
     } 
     Iterator<T> iterator = treeSet.iterator(); 
     int count = 0; 
     while (iterator.hasNext()) { 
     T t = (T) iterator.next(); 
     if (index == count) { 
      return t; 
     } 
     count++; 
     } 
     // out of index. return null. will probably never reach this 
     return null; 
    } 

    @Override 
    public int getSize() { 
     return treeSet.size(); 
    } 

    public int getIndexOf(T t) { 
     int index = 0; 
     for (T treeItem : treeSet) { 
     if (treeItem.equals(treeItem)) { 
      return index; 
     } 
     index++; 
     } 
     return -1; 
    } 

    public boolean add(T t) { 
     boolean result = treeSet.add(t); 
     if (result) { 
     int index = getIndexOf(t); 
     fireIntervalAdded(this, index, index + 1); 
     } 
     return result; 
    } 

    public boolean remove(T t) { 
     int index = getIndexOf(t); 
     if (index < 0) { 
     return false; 
     } 
     boolean result = treeSet.remove(t); 
     fireIntervalRemoved(this, index, index + 1); 
     return result; 
    } 

} 
+0

도와 줘서 고마워! 나는 비슷한 것을 가지고있다. :) 모델에 대해 템플릿이 아닌 클래스를 만들고 익명 Comparator를 모델 생성자에 제공했습니다. getIndexOf()를 구현하지 않고 fireIntervalAdded (Object, 0, set.size())를 사용했습니다. 앞에서 설명한 것처럼 GUI 클래스 외부에서 모델에 액세스해야 할 수도 있습니다. 그것을위한 접근자를 만들겠습니까? 나머지는 분류 된 것으로 보인다. 다시 한번 감사드립니다. – Vlad

+1

@Vlad : 네, 접근자를 생성 할 수는 있지만 원래 세트가 변경되지 않도록 TreeSet의 * copy *를 반환해야합니다. –

+0

GUI 외부에서 add()를 사용해야하므로 모델에 접근하기를 원했습니다. :) TreeSet에 관해서는, 내가 돌아와야 할 필요가있을 때를 대비해,'Collections.unmodifiableSet (set); '가 작동 할까? – Vlad