Превратить ArrayList<JTextArea> в JScrollPane

У меня есть список массивов из «n» разных чатов, которые обернуты шириной ниже, это код для блока TextArea

JTextArea chat2 = new JTextArea();
 chat2.setText("this is chat 2"); 
 chat2.setWrapStyleWord(true);
 chat2.setLineWrap(true);
 chat.setColumns(20); 
 chat2.setEditable(false);
 chat2.setBorder(borderLine);   
 chat2.setVisible(true);

И список массивов, который выглядит как

ArrayList<JTextArea> c = new ArrayList<JTextArea>();
c.add(chat2)

Уже пробовал

Vector itemsVector = new Vector(c);
JList chats = new JList(itemsVector);
 //CHAT PANEL SCROLLABLE
 JScrollPane scrollChats = new JScrollPane(chats);
 scrollChats.setBounds(0,60,1100,600);
 main.add(scrollChats); 

Это не сработало, вместо этого получил этот вывод:

JList - это то, что нужно, но вы, похоже, путаете модель с дисплеем. Модель должна содержать строки чата или списки строк, а дисплей (или средство визуализации списка) будет там, где могут располагаться JTextAreas.

Hovercraft Full Of Eels 19.12.2020 18:54

Поэтому я отправляю список строк в Jlist вместо списка JTextArea. Я могу это сделать, но как потом мне добавить обертку или другие свойства пользовательского интерфейса? @HovercraftFullOfEels

Jaison Thomas 19.12.2020 18:58

Вы заявляете, что отображаете несколько коллекций чатов, предполагая, что ваша модель JList будет содержать List<List<String>> или что-то в этом роде. Затем вам придется работать над рендерером списка, который отображает каждый List<String> в визуализируемом JTextArea. Это всего лишь один из способов сделать это.

Hovercraft Full Of Eels 19.12.2020 19:02

Вы НИКОГДА не будете передавать компоненты Swing в модель JList, поскольку это определенно не так, как это работает (как вы узнаете)

Hovercraft Full Of Eels 19.12.2020 19:03

Извините, что не сделал это более понятным для коллекции чатов, я имел в виду один список чатов, поэтому это будет только List<String>. Итак, я предполагаю, что дальше идентификатор должен отображать ячейки Jlist?

Jaison Thomas 19.12.2020 19:06

Тогда это может быть просто — создайте DefaultListModel<String>, заполните его текстом чата, а затем добавьте его в свой список. Сделанный.

Hovercraft Full Of Eels 19.12.2020 19:10

становится сложнее, если вы хотите изменить отображение в зависимости от того, кто опубликовал чат, но это можно сделать с помощью правильного использования средств визуализации.

Hovercraft Full Of Eels 19.12.2020 19:12

Постараюсь реализовать ререндер, откомментирую, как получилось

Jaison Thomas 19.12.2020 19:19
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
8
99
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Итак, представьте себе класс Chat, который содержит String, представляющий болтовню (или, лучше, четко определенный объект типа User), а также текст, который отправляет этот пользователь:

public class Chat {
    String name;
    String text;

    public Chat(String name, String text) {
        super();
        this.name = name;
        this.text = text;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

}

Затем вы можете создать модель списка и JList, которые содержат объекты этого типа:

private DefaultListModel<Chat> chatListModel = new DefaultListModel<Chat>();
private JList<Chat> chatList = new JList<Chat>(chatListModel);

Затем вы можете создать средство визуализации, которое отображает текст Chatter в качестве текста средства визуализации по умолчанию и имя болтовни в рамке с заголовком, которая окружает отдельное средство визуализации (средство визуализации по умолчанию — это JLabel):

private class ChatRenderer extends DefaultListCellRenderer {
    @Override
    public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
            boolean cellHasFocus) {
        Chat chat = (Chat) value;
        String text = chat.getText();
        String name = chat.getName();
        JLabel rendererComponent = (JLabel) super.getListCellRendererComponent(list, text, index, isSelected, cellHasFocus);
        rendererComponent.setBorder(BorderFactory.createTitledBorder(name));
        return rendererComponent;
    }
}

Все это может выглядеть так:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class FooGui01 extends JPanel {
    private DefaultListModel<Chat> chatListModel = new DefaultListModel<Chat>();
    private JList<Chat> chatList = new JList<Chat>(chatListModel);
    private JTextField inputField = new JTextField(20);
    private JButton submitButton = new JButton("Submit");
    
    public FooGui01() {
        chatList.setCellRenderer(new ChatRenderer());
        chatList.setPrototypeCellValue(new Chat("John", "abc def ghi jkl abc def ghi jkl abc def ghi jkl abc def ghi jkl abc def ghi jkl abc def ghi jkl "));
        chatList.setVisibleRowCount(10);
        JScrollPane scrollPane = new JScrollPane(chatList);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        
        ActionListener listener = new SubmitListener();
        inputField.addActionListener(listener);
        submitButton.addActionListener(listener);
        submitButton.setMnemonic(KeyEvent.VK_S);
        
        JPanel submitPanel = new JPanel();
        submitPanel.setLayout(new BoxLayout(submitPanel, BoxLayout.LINE_AXIS));
        submitPanel.add(inputField);
        submitPanel.add(submitButton);
        
        setLayout(new BorderLayout());
        add(scrollPane);
        add(submitPanel, BorderLayout.PAGE_END);
    }
    
    // public method called by outside code that is wanting to pass chat to you
    public void submitChat(Chat chat) {
        if (SwingUtilities.isEventDispatchThread()) {
            chatListModel.addElement(chat);
        } else {
            SwingUtilities.invokeLater(() -> chatListModel.addElement(chat));
        }
    }

    private class SubmitListener implements ActionListener {
        @Override
        public void actionPerformed(ActionEvent e) {
            String text = inputField.getText();
            chatListModel.addElement(new Chat("Me", text));
            inputField.selectAll();
            inputField.requestFocusInWindow();
            
            // here you would send the chat text or object to a socket's output stream
        }
    }
    
    private class ChatRenderer extends DefaultListCellRenderer {
        @Override
        public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
                boolean cellHasFocus) {
            Chat chat = (Chat) value;
            String text = chat.getText();
            String name = chat.getName();
            JLabel rendererComponent = (JLabel) super.getListCellRendererComponent(list, text, index, isSelected, cellHasFocus);
            rendererComponent.setBorder(BorderFactory.createTitledBorder(name));
            return rendererComponent;
        }
    }
    
    public static void main(String[] args) {        
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Foo");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            
            FooGui01 gui = new FooGui01();
            frame.add(gui);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

Это так информативно спасибо. Итак, я только что передал строки для целей тестирования, сделал много кода, который идентичен нашему, у меня есть сомнения относительно ChatRenderer. текст представляет собой одну длинную строку... есть предложения? Я попытался добавить его на панель и вернуть панель, но это не сработало :(. Это просто перенос текста, у меня проблема с rn

Jaison Thomas 19.12.2020 20:25

@JaisonThomas: покажите свой минимальный воспроизводимый пример кода в своем вопросе (так же, как я разместил свой). Вы вызывали setLineWrap(true) и setWrapStyleWord(true) в JTextArea в вашем рендерере?

Hovercraft Full Of Eels 19.12.2020 20:29

Да, я установил setLineWrap(true); и setWrapStyleWord(true);, и, учитывая размеры setSize(100,getPreferredSize().height);, он оставляет соответствующее место для высоты, которую он просто не сворачивает.

Jaison Thomas 19.12.2020 20:38

Я слишком беспокоил вас сегодня, я пытался создать пользовательский интерфейс, больше связанный с WhatsApp, но я скомпилировал ваш код, и он выглядит намного лучше, чем все, что я мог бы создать, я собираюсь использовать предоставленный вами пользовательский интерфейс и придерживаться его. еще раз, большое спасибо

Jaison Thomas 19.12.2020 20:48

@JaisonThomas: несколько интересных вещей, которые можно попробовать, из ответов на этот вопрос

Hovercraft Full Of Eels 19.12.2020 20:49

Другие вопросы по теме