java - 如何在 JList 中选择行,其中每个单元格包含包含 JTextArea 的 JPanel
问题描述
我的代码目前是这样编写的,因为我的目的是将文本包装在 JList 的每个单元格中。现在,这部分在 JList 呈现的面板中的 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;
}
}
}
解决方案
如果您决定使用 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;
}
}
结果是
我怎样才能让每一行都可以选择?或者您会建议使用不同的组件在 JList 中包装文本吗?
为了回应我们的要求,我的回应取决于
如果您只需要视觉效果,我认为这是一个很好的解决方案,而DefaultListCellRenderer
不是管理多条线路。
推荐阅读
- r - 如何计算连续出现低于R中的阈值
- windows - Go exec.Cmd() 导致 Python 脚本不导入模块?
- c# - 将数组存储为逗号分隔,如何使用 LINQ 进行查询?
- mysql - 外键错误 - 错误 1005 (HY000) ... 无法创建表 ... `stored_on` (errno: 150)
- nginx - 关于Nginx的使用
- mysql - 创建 MySQL 过程
- php - 从 PHP5 迁移到 PHP7 后,PHP Pear HTML-IT 不呈现
- java - 如何修复变量不等于用户输入
- javascript - MUIdatatables 如何使用箭头/tab 键导航?
- javascript - 懒加载:如何用pdf.js将多个pdf文档显示为一个?