如何在JList中选择行,其中每个单元格都包含包含JTextArea的JPanel

问题描述 投票:0回答:1

目前,我的代码在下面以这种方式编写,因为我的意图是将文本包装在JList的每个单元格内。现在,该部分在由JList呈现的Panel中使用JTextArea成功了,但是我遇到了另一个问题。我似乎无法像简单的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;
    }
  }
}
java swing jlist
1个回答
0
投票

如果决定使用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

© www.soinside.com 2019 - 2024. All rights reserved.