0

嗨,我实现了一个JList包含JLabels 作为元素的。我的目标是为服务器/客户端聊天应用程序实现联系人列表。因此,当客户端连接到服务器时,JList 将构建以显示他/她的联系人列表。我选择使用 JLabels 因为它们也可以有图标和文本。但是,我在覆盖 cellrenderer 方法时遇到了一些麻烦。每当客户端联机/脱机时,JList 都会更新其状态并将所有项目设置为类似于最后添加的项目。是这样的,

这是第一次将离线状态客户端添加到一个人的朋友列表中;

在此处输入图像描述

之后,这是第二次添加不同的客户端

在此处输入图像描述

最后第三次...

在此处输入图像描述

此外,我记得在教程中提到 JList 覆盖痛苦方法并在列表发生更改时一次又一次地绘制整个元素。好吧,实际上我是这个渲染主题的新手,这件事变得非常烦人。在这里你可以看到我的渲染器类; 渲染器示例

并在我的主类中以这种方式将元素添加到模型中

labelSetText = tempon.getNickName();
onlineStatus = tempon.isIsOnline();
model.addElement(createPanel());

并且还createPanel()返回一个类似的 JLabel;

public static JLabel createPanel() {
    JLabel panel = new JLabel();
    return panel;
}

我希望我已经清楚我的问题。我必须实现这一点,当联系人更改他/她的状态或添加联系人时,此操作不应影响其他元素。我将非常感谢您的每一个答案(如果您可以添加简短的解释说明您所做的事情和原因,我将不胜感激。)无论如何,谢谢

4

1 回答 1

4

您不应该将诸如JLabelinto之类的组件放入JList. 相反,使用模型来保存数据并添加渲染器来自定义呈现。有关一些示例,请参见如何使用列表

这是添加图标的渲染器的一个非常基本的示例:

import java.awt.BorderLayout;
import java.awt.Component;
import javax.swing.*;

public class TestUserList {
    public static class UserRenderer extends DefaultListCellRenderer {
        @Override
        public Component getListCellRendererComponent(JList list, Object value,
                int index, boolean isSelected, boolean hasFocus) {
            if (value instanceof UserEntry) {
                UserEntry user = (UserEntry) value;
                JLabel label = (JLabel) super.getListCellRendererComponent(
                        list, user.getName(), index, isSelected, hasFocus);
                if (user.isOnline())
                    label.setIcon(UIManager
                            .getIcon("OptionPane.informationIcon"));
                else
                    label.setIcon(UIManager.getIcon("OptionPane.errorIcon"));
                return label;
            }
            return super.getListCellRendererComponent(list, value, index,
                    isSelected, hasFocus);
        }
    }

    public TestUserList() {
        JFrame frame = new JFrame("User List");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        final JList list = new JList();

        JScrollPane scrollPane = new JScrollPane(list);
        JPanel content = new JPanel(new BorderLayout());
        content.add(scrollPane, BorderLayout.CENTER);
        final DefaultListModel model = new DefaultListModel();
        model.addElement(new UserEntry("John", true));
        model.addElement(new UserEntry("Jesse", false));
        list.setModel(model);

        list.setCellRenderer(new UserRenderer());

        frame.add(content);
        frame.setLocationByPlatform(true);
        frame.pack();
        frame.setVisible(true);
    }

    public class UserEntry {
        private String name;
        private boolean online;

        public UserEntry(String name, boolean online) {
            super();
            this.name = name;
            this.online = online;
        }

        public String getName() {
            return name;
        }

        public Boolean isOnline() {
            return online;
        }
    }

    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestUserList();
            }
        });
    }
}
于 2013-03-29T00:12:34.993 回答