Как выбрать строку в JList, где каждая ячейка содержит JPanel, которая содержит JTextArea - PullRequest
0 голосов
/ 07 октября 2019

Мой код в настоящее время написан следующим образом, так как я собирался заключить текст в каждую ячейку JList. Теперь эта часть выполнена успешно с JTextArea в Panel, созданной JList, но у меня другая проблема. Кажется, я не могу сделать так, чтобы каждая строка выбиралась как простая реализация JList.

Как я могу сделать так, чтобы каждая строка была выбираемой? или вы предлагаете использовать другой компонент для переноса текста внутри JList?

import java.awt.BorderLayout;
import java.awt.Component;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class JListPractice3 {

public static void main(final String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            new JListPractice3();
        }
    });
}

public JListPractice3() {
    JFrame f = new JFrame("JList Practice");
    f.setResizable(true);
    f.setVisible(true);
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.getContentPane().setLayout(new BorderLayout());

    JPanel listPanel = this.buildJListPanel();

    f.add(listPanel);

    f.pack();
}

/**
 * Build JList panel
 * @return JPanel
 */
private JPanel buildJListPanel() {
    JPanel listPanel = new JPanel();
    listPanel.setLayout(new BorderLayout());

    JList jList = new JList(getData());
    jList.setVisibleRowCount(1);
    jList.setFixedCellHeight(50);
    jList.setFixedCellWidth(250);
    jList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    jList.setCellRenderer(new MyCellRenderer());

    JScrollPane scrollPane = new JScrollPane();
    scrollPane.getViewport().setView(jList);
    listPanel.add(scrollPane, BorderLayout.CENTER);
    return listPanel;
}

/**
 * Get Alias data
 * @return String[]
 */
private String[] getData() {
    //TODO: remove hard code
    String[] data = {"123456789012345678901234567890123456789012345678901234567890123456789"
            + "012345678901234567890123456789012345678901234567890123456789012",
            "two two two two two two two two two two two twotwo two two two two two two two two two two twotwo two two end",
            "two two two two two two two two two two two twotwo two two two two two two two end",
            "five", "six"};
    return data;
}

private class MyCellRenderer implements ListCellRenderer {
    private JPanel p;
    private JPanel linePanel;
    private JLabel lineLabel;
    private JTextArea textArea;

    public MyCellRenderer() {
        p = new JPanel();
        p.setLayout(new BorderLayout());

        linePanel = new JPanel(new BorderLayout());
        linePanel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 3));
        lineLabel = new JLabel("Test");
        linePanel.add(lineLabel, BorderLayout.NORTH);
        p.add(linePanel, BorderLayout.WEST);

        textArea = new JTextArea();
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        p.add(textArea, BorderLayout.CENTER);
    }

    @Override
    public Component getListCellRendererComponent(final JList list,
            final Object value, final int index, final boolean isSelected,
            final boolean hasFocus) {

        textArea.setText((String) value);
        int width = list.getWidth();
        // this is just to lure the ta's internal sizing mechanism into action
        if (width > 0) {
            textArea.setSize(width, Short.MAX_VALUE);
        }
        return p;
    }
  }
}

1 Ответ

0 голосов
/ 08 октября 2019

Если вы решили использовать интерфейс ListCellRender, вы должны реализовать весь эффект, поэтому для пояснения ListCellRender является компонентом (пример JLabel) для установки значения и всего прослушивателя (в этом случае вы добавляете прослушиватель внутри компонента)

Таким образом, в вашем решении компонент выбирается, но ваш код не рисует его, а моя реализация вас CellRender

private class MyCellRenderer extends JTextArea implements ListCellRenderer{
    private JPanel p;
    private JPanel linePanel;
    private JLabel lineLabel;

    public MyCellRenderer() {
        p = new JPanel();
        p.setLayout(new BorderLayout());

        linePanel = new JPanel(new BorderLayout());
        linePanel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 3));
        lineLabel = new JLabel("Test");
        linePanel.add(lineLabel, BorderLayout.NORTH);
        p.add(linePanel, BorderLayout.WEST);

        this.setLineWrap(true);
        this.setWrapStyleWord(true);
        p.add(this, BorderLayout.CENTER);
    }

    public Component getListCellRendererComponent(final JList list,
            final Object value, final int index, final boolean isSelected,
            final boolean hasFocus) {
        if(isSelected){
            this.setBackground(Color.BLUE);
        }else{
            this.setBackground(Color.GRAY);
        }
        this.setText((String) value);
        int width = list.getWidth();
        // this is just to lure the ta's internal sizing mechanism into action
        if (width > 0) {
            this.setSize(width, Short.MAX_VALUE);
        }
        return this;
    }
  }

Результат -

enter image description here

Как я могу получить возможность выбора каждой строки? или Вы предлагаете использовать другой компонент для переноса текстов внутри JList?

для ответа на наш запрос, мой ответ будет зависит

Если вам нужнотолько визуальный эффект, я думаю, что это хорошее решение, DefaultListCellRenderer не удалось несколько строк.

...