2013-04-14 2 views
1

이 질문을 여러 번 전에 알고 있습니다. 그러나 JList를 업데이트하는 방법을 연구하는 데 몇 시간을 보냈습니다.이 문제로 처리 할 수 ​​없었습니다. 나는 누가 온라인 또는 오프라인인지를 보여주는 JList를 구현하려고 시도하고있다. (이것은 JLabels를 보유하고 있는데, 이것은 아이콘이있는 문자열을 유지하는 유일한 방법이다). 나는 내 자신의 CellRenderer()을 가지고있다.DefaultListModel()을 사용하여 요소를 추가하거나 제거하는 동안 JList를 업데이트하는 방법

public class UserRenderer extends DefaultListCellRenderer { 


    @Override 
    public Component getListCellRendererComponent(JList list, Object value,int index, boolean isSelected, boolean hasFocus) { 

     if(value instanceof ClientObject){ 

      final ClientObject clientObject = (ClientObject) value; 
      JLabel label = (JLabel) super.getListCellRendererComponent(list, clientObject.getNickName(), index, isSelected, hasFocus); 

      if(clientObject.isIsOnline()){ 

       label.setIcon(iconArray[1]); 
      } 
      else{ 

       label.setIcon(iconArray[0]); 
      } 

      return label; 
     } 

     else { 

      return super.getListCellRendererComponent(list, value, index, isSelected, hasFocus); 
     } 
    } 

} 

또한이 방법으로 서버에 연결할 때마다 클라이언트의 목록을 구성합니다.

private void buildBuddyList(ClientObject tempClientObject){ 

    if(tempClientObject.getBuddyList().size() > 0){ 

     mainClient.setBuddyList(tempClientObject.getBuddyList()); 

     for (Iterator<ClientObject> iter = mainClient.getBuddyList().iterator(); iter.hasNext();) { 

      ClientObject tempon = iter.next(); 

       if(tempon.isIsOnline()){ 

        model.addElement(tempon); 
        labelIconList.put(tempon, iconArray[1]); 
       } 

       else{ 

        model.addElement(tempon); 
        labelIconList.put(tempon, iconArray[0]); 
       } 
     } 
    } 
} 

클라이언트 (온라인/오프라인이됩니다) 내가 model.clear() 모든 요소를 ​​제거하고 다시 목록을 구축하기 시작 얻을 것입니다 그/그녀의 상태를 변경할 때 내가 사용하는 트릭. 다음은 코드 세그먼트입니다.

 if(tempClientObject.isStatusChanged()){ 

      if(tempClientObject.isIsConnected()){ 

       System.out.println(tempClientObject.getUserName() + " is ONLINE"); 

       model.clear(); 

       for (Iterator<Map.Entry<ClientObject,ImageIcon>> iter = labelIconList.entrySet().iterator(); iter.hasNext();) { 

        Map.Entry<ClientObject,ImageIcon> pairs = iter.next(); 

        ClientObject changedOnlineStatusClient = (ClientObject) pairs.getKey(); 

        if(changedOnlineStatusClient.getUserName().equals(tempClientObject.getUserName())){ 

         changedOnlineStatusClient.setIsOnline(tempClientObject.isIsOnline()); 
        } 

        model.addElement(changedOnlineStatusClient); 
       } 
      } 

      else{ 

       System.out.println(tempClientObject.getUserName() + " is OFFLINE");     

       model.clear(); 

       for (Iterator<Map.Entry<ClientObject,ImageIcon>> iter = labelIconList.entrySet().iterator(); iter.hasNext();) { 
        Map.Entry<ClientObject,ImageIcon> pairs = iter.next(); 
        ClientObject changedOnlineStatusClient = (ClientObject) pairs.getKey(); 

        if(changedOnlineStatusClient.getUserName().equalsIgnoreCase(tempClientObject.getUserName())){ 

         changedOnlineStatusClient.setIsOnline(tempClientObject.isIsOnline()); 
        } 

        model.addElement(changedOnlineStatusClient); 
       }      
      } 
     } 

그 논리적 시스템이 잘 작동 드릴 수 있습니다. (그들은 배경에서 제대로 작동하는지 내가 작업을 확인할 수 있습니다). 모델에 요소를 추가하더라도 서버 JList에 연결된 클라이언트가 비어있는 경우에만 문제가 발생합니다. 나는 모든 대답을 주셔서 감사하겠습니다. 덕분 어쨌든

+0

[이벤트 발송 스레드] (http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html)에서'ListModel '이 변경되는지 확인하십시오. – trashgod

답변

0

. 반면에 새로운 모델을 생성 할 때마다 업데이트해야 할 때마다 문제를 해결했습니다. 따라서 코드 세그먼트는 다음과 같습니다.

DefaultListModel tempModel = new DefaultListModel(); 

// add or remove elements from tempModel 

buddyList.setModel(tempModel); 

유일한 올바른 방법 일지는 모르겠지만 적어도 작동하는 것은 확실하지 않습니다.

+1

한 번만 XxxModel을 만듭니다. – mKorbel

1

뿐만 아니라 대답,이

주석을 더 필요로 JList

if(value instanceof ClientObject){ 

차원 하나 때문에 Object

getListCellRendererComponent(JList list, Object value, int index, 
     boolean isSelected, boolean hasFocus) { 

에서 반환 동일한 값,하지 이 값을 테스트하려면 if == or equeals ...

+0

그래서이 객체를'if (value.equals (clientObject))'와 같이 테스트하면 똑같은 일을 할 수 있을까요? – quartaela

-1

model.fireContentsChanged() 방법으로 전화하십시오. 우선 귀하의 답변에 대한 모든 감사의

JavaDoc on AbstractListModel

+0

이 문제 자체를 처리하는'DefaultListModel()'을 사용하기 때문에이 메서드를 호출 할 수 없습니다. – quartaela

+1

@quartaela : 모델 외부에서 모델 메서드를 실행하지 말아야합니다. DefaultListModel 메소드를 사용하여 모델을 수정해야한다. – trashgod

+0

그래, 문제가 해결되었습니다. 모델을 업데이트해야 할 때마다 새 모델을 만들고 구성합니다. 나중에 JList의 모델을 다시 설정합니다. – quartaela

관련 문제