JList不可显示

时间:2017-12-13 19:52:25

标签: java swing jlist

我一直在研究这个问题几天,我无法理解我哪里出错了。我创建了一个服务器 - 客户端聊天程序,在服务器GUI上有一个显示用户列表的选项卡。此列表以我想要的各种方式工作。我想在客户端GUI中添加UserList并且JList就在那里,但是当我更新DefaultListModel时,JList只更新ServerGUI 。我尝试调试,发现ChatGUI上的JList无法显示,我不知道为什么或如何修复它。

这是我的(相关)代码:

客户等级

public class Client {
    String username;
    Socket socket;
    PrintWriter out;
    Scanner in;

    public Client (String username, Socket socket, PrintWriter out, Scanner in) {
        this.username = username;
        this.socket = socket;
        this.out = out;
        this.in = in;
    }
}

ServerGUI类 - (当客户端加入时,稍后在程序中调用register方法)

public class ServerGUI {
    public volatile static ArrayList<Client> users;
    public static DefaultListModel<String> model = new DefaultListModel<String>();
    static Client clientReg;

    public static void register(Client client) {
        clientReg = client;
        users.add(clientReg);
        model.addElement(clientReg.username);
         ServerView.userList.setModel(model);
        ChatView.userList.setModel(model);
    }
}

ChatView类

public class ChatView extends JFrame {
    public JPanel contentPane;
    public static JList<String> userList = new JList<String>();
    public static JTextArea chatOutput;
    private JTextField inputField;

    public ChatView() {
        setResizable(false);
        setTitle("Chat GUI");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 550, 475);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        JTabbedPane tabs = new JTabbedPane(JTabbedPane.TOP);
        tabs.setBounds(0, 0, 535, 435);
        contentPane.add(tabs);

        JPanel chatViewer = new JPanel();
        tabs.addTab("Chat", null, chatViewer, null);
        chatViewer.setLayout(null);

        // Code that makes up the chatViewer JPanel

        JPanel userListPane = new JPanel();
        tabs.addTab("User List", null, userListPane, null);
        userListPane.setLayout(null);

        JLabel label = new JLabel("User List:");
        label.setBounds(10, 10, 510, 20);
        userListPane.add(label);

        userList.setModel(new AbstractListModel<String>() {
            public String getElementAt(int index) {
                return ServerGUI.model.get(index);
            }

            public int getSize() {
                return ServerGUI.model.size();
            }
        });
        userList.setValueIsAdjusting(true);
        userList.setLayoutOrientation(JList.HORIZONTAL_WRAP);
        userList.setBounds(10, 40, 510, 395);

        userListPane.add(userList);
    }
}

我的大部分编程都是自学成才,所以如果有任何格式不正确请告诉我,以便我能够纠正它。

1 个答案:

答案 0 :(得分:2)

好的,我看到你是如何尝试通过静态字段和方法“共享”模型的:

userList.setModel(new AbstractListModel<String>() {
    public String getElementAt(int index) {
        return ServerGUI.model.get(index);
    }

    public int getSize() {
        return ServerGUI.model.size();
    }
});

这将永远不会起作用,而不是客户端和服务器如何传输信息。首先,是的,你有客户端可用的服务器静态字段和方法,实际的服务器类和实例在完全不同的JVM中运行,通常在不同的机器上完全运行,所以你得到的数据不是反映服务器本身的实际Server对象和静态类状态的真实状态,但它只是正确对象/类的阴影。

建议:

  • 为您的客户使用标准列表模型,并删除您正在使用的代码,它将无效
  • 如果这是通过套接字传输信息的真实客户端/服务器代码,则客户端必须通过套接字从服务器获取更新。我们不知道你是如何接线的,所以我不能给出其他的具体建议 - 从套接字中获取数据
  • 并在后台线程中执行此操作 - 即客户端应从Swing事件线程接收套接字数据
  • 但是然后使用收到的这些信息更新客户的列表模型 事件线程。一种方法是通过SwingWorker<Void, String>使用其进程/发布方法对。