-2

I want to create a java chat application with the message being displayed in the a list. Each list item will have the message details such as user's name, date, message and seen/not seen. I'm using a JPanel as my cellRenderer component and this JPanel has four JLabels. How can I dynamically insert elements to this JList? I want the GUI somewhat similar to image as given below:

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

My code for chat application frame is :

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*/
}

The JPanel "messagePanel" contains four labels for message details. While debugging, the values are stored correctly. But the frame either doesn't show any components or if it does, it doesn't show the message list items.

  • 2
    1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) Java GUIs have to work on different OS', screen size, screen resolution etc. using different PLAFs in different locales. As such, they are not conducive to pixel perfect layout. Instead use layout managers, or [combinations of them](http://stackoverflow.com/a/5630271/418556) along with layout padding and borders for [white space](http://stackoverflow.com/a/17874718/418556). 3) Use a logical and consistent form of indenting code lines and blocks. .. – Andrew Thompson Mar 19 '18 at 20:45
  • 1
    .. The indentation is intended to make the flow of the code easier to follow! – Andrew Thompson Mar 19 '18 at 20:45
  • 2
    1) Class names should start with an upper case character. Have you ever seen a class from the API that doesn't? Follow Java conventions. 2) We have no idea what "messagePanel" is or what those methods do. – camickr Mar 19 '18 at 20:48
  • 2
    *"How can I dynamically insert elements to this JList?"* ... you insert the message object into a mutable `ListModel` - perhaps you should start with the JavaDocs and tutorials first – MadProgrammer Mar 19 '18 at 20:54

1 Answers1

0

I have done something very similar to this in two different ways with a TabelCellRenderer<E>. The difference between TableCellRenderer and ListCellRenederer are minimal. In one case I derived a class from JTextPane. This allowed me to use various styles of Font Face, Font Size and Color to distinguish fields. I was also able to display multiple lines of text. The documentation for ListCellRenderer<E> and JTextPane should be useful. In the other case I derived my class from JPanel to which I set the LayoutManager and added a combination of JLabel(s) and JTextField(s). I kept references to the necessary fields in my derived class, you can update the necessary fields in your getListCellRenderer(). By creating a ListCellRenderer and setting it in the JList the same JPanel will be used for each row when it’s necessary to display the row. By doing it this way you can create a data object with the data you want to display which is passed into the getListCellRenderer(). Then you just need to add the data objects to the JList.

BillT
  • 26
  • 3