1

私はこの質問が以前に何度も尋ねられたことを知っています。しかし、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 に接続されたクライアントがモデルに要素を追加しているにもかかわらず、空白に見える場合があることです。私はすべての答えに感謝します。とにかくありがとう

4

3 に答える 3

1

コメントのみで、回答ではありません

1次元は必要ありませんJList

if(value instanceof ClientObject){

なぜならObject、から

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

同じ値を返し、この値をテストするにはif == or equeals...

于 2013-04-14T13:37:57.833 に答える
0

まず、すべての返信に感謝します。一方、更新する必要があるたびに新しいモデルを作成するという問題を修正しました。コード セグメントは次のようになります。

DefaultListModel tempModel = new DefaultListModel();

// add or remove elements from tempModel

buddyList.setModel( tempModel );

それが唯一の正しい方法かどうかはわかりませんが、少なくとも機能します。

于 2013-04-14T22:03:54.480 に答える