Как да актуализирате 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