Как обновить JList при добавлении или удалении элементов с помощью DefaultListModel()

Я знаю, что этот вопрос задавали много раз раньше. Тем не менее, я потратил несколько часов на изучение способа обновления JList, и я не смог справиться с этой проблемой. Я пытаюсь реализовать JList, который показывает, кто находится в сети или в автономном режиме (он содержит JLabels, я думаю, это единственный способ удерживать строку со значком). У меня есть собственное CellRenderer(), похожее на;

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, выглядит пустым, хотя он добавляет элементы в модель. буду признателен за каждый ответ. И все равно спасибо


person quartaela    schedule 14.04.2013    source источник
comment
Убедитесь, что ListModel изменяется в потоке отправки событий. .   -  person trashgod    schedule 14.04.2013


Ответы (3)


только комментарий, а не ответ

нет необходимости в одномерном JList

if(value instanceof ClientObject){

потому что Object из

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

возвращает то же значение, то для проверки этого значения if == or equeals ...

person mKorbel    schedule 14.04.2013
comment
поэтому тестирование этого объекта, такого как if(value.equals(clientObject)), сделает то же самое? - person quartaela; 14.04.2013

Прежде всего спасибо за все ваши ответы. С другой стороны, я исправил свою проблему с созданием новой модели всякий раз, когда ее нужно обновлять. Таким образом, сегмент кода выглядит следующим образом;

DefaultListModel tempModel = new DefaultListModel();

// add or remove elements from tempModel

buddyList.setModel( tempModel );

я не уверен, что это единственный правильный способ, но, по крайней мере, он работает.

person quartaela    schedule 14.04.2013
comment
создать XxxModel один раз, - person mKorbel; 15.04.2013

Вызов метода model.fireContentsChanged().

JavaDoc в модели AbstractListModel

person Augustus Thoo    schedule 14.04.2013
comment
я не могу вызвать этот метод, потому что я использую DefaultListModel(), который сам решает эту проблему - person quartaela; 14.04.2013
comment
@quartaela: вы не должны не запускать методы модели вне модели; вы должны изменить модель, используя методы DefaultListModel. - person trashgod; 14.04.2013
comment
хорошо, я исправил проблему. Каждый раз, когда модель должна получить обновление, я создаю новую модель и строю ее. позже я снова установил модель JList. - person quartaela; 15.04.2013