我正在尝试构建一个jlist,它包含具有独立侦听器和行为的元素(自定义)。我的意思是,当电池加载时,它应该:
如果customclass的值“installed”=true,则显示选中的复选框
显示customclass中的文本
如果我在复选框中单击,它会将该对象的已安装状态更改为与其值相反的状态
如果单击文本,它将在另一个面板中显示customclass的信息
现在我设法构建的是jlist,带有customclass( SimpleTemplate
),即用 SimpleTemplate
的名称,当您单击它时,将显示 SimpleTemplate
在另一个面板中。然而,我不知道如何将听众和事件分开,并在之前提出建议。
我的代码如下:
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import javax.swing.DefaultListModel;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
public class CustomJListExample extends JFrame {
private static final Dimension SIDE_PANEL_DIMENSION = new Dimension(190, 190);
private static final Dimension CONTAINER_PANEL_DIMENSION = new Dimension(400, 200);
private static final Dimension TEMPLATES_LIST_DIMENSION = new Dimension(180, 180);
private static final Border SIMPLE_BORDER = new JTextField().getBorder();
private JList<SimpleTemplate> templatesList = new JList<>();
private JLabel templateName = new JLabel();
private JLabel templateDescription = new JLabel();
public CustomJListExample() {
JPanel rightPanel = prepareRightSide();
JPanel leftPanel = prepareLeftSide();
JPanel containerPanel = new JPanel();
containerPanel.setPreferredSize(CONTAINER_PANEL_DIMENSION);
containerPanel.add(leftPanel);
containerPanel.add(rightPanel);
add(containerPanel);
pack();
}
private JPanel prepareRightSide() {
JPanel rightPanel = new JPanel();
rightPanel.setBorder(SIMPLE_BORDER);
rightPanel.setBackground(Color.GRAY);
rightPanel.setPreferredSize(SIDE_PANEL_DIMENSION);
templateName.setText("---");
templateDescription.setText("---");
rightPanel.add(templateName);
rightPanel.add(templateDescription);
return rightPanel;
}
private JPanel prepareLeftSide() {
JPanel leftPanel = new JPanel();
leftPanel.setBorder(SIMPLE_BORDER);
leftPanel.setBackground(Color.GRAY);
leftPanel.setPreferredSize(SIDE_PANEL_DIMENSION);
DefaultListModel<SimpleTemplate> templatesListModel = new DefaultListModel<>();
templatesListModel.addElement(new SimpleTemplate("Template 1", "Description template 1", false));
templatesListModel.addElement(new SimpleTemplate("Template 2", "Description template 2", true));
templatesListModel.addElement(new SimpleTemplate("Template 3", "Description template 3", false));
templatesList.setCellRenderer(new JListRepositoryItem());
templatesList.addListSelectionListener(e-> displayTemplateInfo());
templatesList.setPreferredSize(TEMPLATES_LIST_DIMENSION);
templatesList.setModel(templatesListModel);
templatesList.repaint();
leftPanel.add(templatesList);
return leftPanel;
}
private void displayTemplateInfo() {
SimpleTemplate selectedValue = templatesList.getSelectedValue();
templateName.setText(selectedValue.getName());
templateDescription.setText(selectedValue.getDescription());
}
class JListRepositoryItem extends JCheckBox implements ListCellRenderer {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
setComponentOrientation(list.getComponentOrientation());
setFont(list.getFont());
setBackground(list.getBackground());
setForeground(list.getForeground());
if (value instanceof SimpleTemplate) {
SimpleTemplate template = (SimpleTemplate) value;
setSelected(isSelected);
setEnabled(list.isEnabled());
setText(template.getName());
}
return this;
}
}
class SimpleTemplate {
private String name;
private String description;
private boolean installed;
public SimpleTemplate(String name, String description, boolean installed) {
this.name = name;
this.description = description;
this.installed = installed;
}
public String getName() {
return name;
}
public String getDescription() {
return description;
}
public boolean isInstalled() {
return installed;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new CustomJListExample().setVisible(true));
}
}
这将生成以下示例。
然而,我无法使文本具有自己的行为,也无法使其具有自己的行为。
1条答案
按热度按时间pu82cl6c1#
如果你想做得好,你就得改变
JList
ui实现,因为选择行为来自于此。如果你从来没有用过它,那是一件很难做到的事。而且,通常很难像你要求的那样做,因为
JList
组件不允许您与中提供的组件交互ListCellRenderer
直接实现-它只是使用它们以不同的设置多次“标记”它们的图形表示。这使JList
在大量数据上执行得非常好,但会将您锁定在与渲染器组件的直接交互之外。但是有一个解决方法可以用于像您这样的简单案例-您可以添加一个自定义
MouseListener
你的列表和“猜测”用户点击的位置。幸运的是JList
api将为您提供所有必要的方法:为了演示,我添加了文本大小计算,但是如果不需要,可以简化整个过程。
以下是标签、按钮或复选框等基本组件的明细:
这将使它更容易可视化,并应帮助您了解哪些领域,你想使“点击”,因为这并不总是一个简单的事情来决定。例如,我的例子非常精确-你只能准确地点击复选图标或文本,但在实践中,这将是一个可怕的经验,你可能会想扩大到插入/剩余的地区。
您还需要删除您的
ListSelectionListener
因为它将与MouseListener
. 以下是完整代码:虽然我想再次强调,这是一个“黑客”的工作范围以外的
JList
内部逻辑,所以你不能依赖JList
选择,因为它将由内部lsitener从JList
用户界面。但你似乎并不真的需要JList
首先是选择,所以这对你来说可能很好。如果你愿意调整的话
JList
用户界面-您将需要执行类似的计算,但也提供了一个自定义的ListUI
如果您使用的是本机操作系统的外观和感觉,实现可能会很困难。