-2

我想创建一个 java 聊天应用程序,消息显示在列表中。每个列表项都将包含消息详细信息,例如用户名、日期、消息和已查看/未查看。我使用 JPanel 作为我的 cellRenderer 组件,这个 JPanel 有四个 JLabel。如何将元素动态插入此 JList?我希望 GUI 有点类似于下面给出的图像:

https://i.stack.imgur.com/cept4.png

我的聊天应用程序框架代码是:

import java.awt.Component;
import javax.swing.ListCellRenderer;
import javax.swing.JList;
import java.util.Scanner;
import java.util.Date;
import javax.swing.DefaultListModel;


class TextCellRenderer extends messagePanel implements ListCellRenderer<textData> {

    @Override
    public Component getListCellRendererComponent(JList<? extends textData> list, textData value, int index, boolean isSelected, boolean cellHasFocus) {
        //To change body of generated methods, choose Tools | Templates.
        setName(value.name);
        setMessage(value.text);
        setDate(value.d.toString());
        setSeen(value.seen);

        return this;
    }
}

public class ChatGUI extends javax.swing.JFrame {

    ListCellRenderer cRenderer = new TextCellRenderer();
    static textData td[] = new textData[5];

    static void getData() {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter name and message: ");
        for (int i = 0; i < 5; i++) {
            System.out.println("Message #" + (i + 1));
            td[i] = new textData();
            td[i].name = sc.next();
            td[i].text = sc.next();
            td[i].d = new Date();
            td[i].seen = false;
        }
    }

    public ChatGUI() {
        getData();
        initComponents();
        this.setSize(1366, 768);
    }

    @SuppressWarnings("unchecked")
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        contactList = new javax.swing.JList<>();
        jScrollPane2 = new javax.swing.JScrollPane();
        messageList = new javax.swing.JList<>();
        jScrollPane3 = new javax.swing.JScrollPane();
        textInput = new javax.swing.JTextArea();
        sendText = new javax.swing.JButton();
        exit = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().setLayout(null);

        contactList.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
        contactList.setModel(new javax.swing.AbstractListModel<String>() {
            String[] strings = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"};

            public int getSize() {
                return strings.length;
            }

            public String getElementAt(int i) {
                return strings[i];
            }
        });
        jScrollPane1.setViewportView(contactList);

        getContentPane().add(jScrollPane1);
        jScrollPane1.setBounds(260, 130, 189, 430);

        messageList.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
        messageList.setCellRenderer(cRenderer);
        messageList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        DefaultListModel<textData> dlm = new DefaultListModel<>();
        for (int i = 0; i < td.length; i++) {
            dlm.addElement(td[i]);
        }
        messageList.setModel(dlm);
        messageList.setCellRenderer(cRenderer);
        jScrollPane2.setViewportView(messageList);

        getContentPane().add(jScrollPane2);
        jScrollPane2.setBounds(540, 130, 415, 281);

        textInput.setColumns(20);
        textInput.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
        textInput.setRows(5);
        jScrollPane3.setViewportView(textInput);

        getContentPane().add(jScrollPane3);
        jScrollPane3.setBounds(550, 440, 283, 120);

        sendText.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        sendText.setText("Send");
        sendText.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                sendTextActionPerformed(evt);
            }
        });
        getContentPane().add(sendText);
        sendText.setBounds(870, 450, 92, 40);

        exit.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        exit.setText("Exit");
        getContentPane().add(exit);
        exit.setBounds(870, 500, 92, 35);

        pack();
    }
    /*main method*/
}

JPanel“messagePanel”包含四个用于消息详细信息的标签。在调试时,这些值被正确存储。但是框架要么不显示任何组件,要么不显示消息列表项。

4

1 回答 1

0

我用两种不同的方式做了一些与此非常相似的事情TabelCellRenderer<E>TableCellRenderer和之间的差异ListCellRenederer很小。在一种情况下,我从JTextPane. 这使我可以使用各种样式的字体、字体大小和颜色来区分字段。我还能够显示多行文本。ListCellRenderer<E>JTextPane应该有用的文档。在另一种情况下,我派生了JPanel我设置的类,LayoutManager并添加了JLabel(s) 和JTextField(s) 的组合。我在派生类中保留了对必要字段的引用,您可以更新getListCellRenderer(). 通过创建一个ListCellRenderer并将其设置JList为相同的JPanel当需要显示行时,将用于每一行。通过这种方式,您可以使用要显示的数据创建一个数据对象,该数据传递到getListCellRenderer(). 然后,您只需将数据对象添加到JList.

于 2018-03-21T04:52:02.883 回答