【发布时间】:2020-10-02 13:54:23
【问题描述】:
这里的第一个问题,希望我做对了。
下面是我的问题的一个最小示例,我很快就为我的项目挑选了代表。我为包含一些对象的 JList 创建了一个自定义渲染器(在示例中,我使用字符串进行说明)。我的问题是,据我所知,如果我将 ListSelectionListener 添加到列表中,setSelected...() 方法系列不会触发触发条件 if(e.getValueIsAdjusting()) 的事件。
在下面的示例中,问题在启动程序时立即显而易见:即使在将 JLabel 的选定文本指定为“无”之后调用 list.setSelectedIndex(2);,它也不会改变,直到您(用户)单击列表项.事实上,它必须与当前选择的项目不同。
我想要这个功能,这样我的程序流程将是,在用户从列表中添加/删除项目后,一旦所选列表项目发生更改,“视图”就会立即更新。
是我做错了什么,还是我的处理方法不正确?
谢谢。 :)
import java.awt.BorderLayout;
import java.beans.*;
import javax.swing.*;
public class Example implements PropertyChangeListener {
String ITEM_SELECTED = "Item Selected";
String DELETE_SELECTED = "Delete Selected";
PropertyChangeSupport pcs = new PropertyChangeSupport(this);
JLabel selected;
JList<String> list;
DefaultListModel<String> model;
public static void main(String[] args) {
new Example();
}
public Example() {
JFrame frame = new JFrame();
JPanel mainPanel = new JPanel(new BorderLayout());
model = new DefaultListModel<>();
model.addElement("Entry 1");
model.addElement("Entry 2");
model.addElement("Entry 3");
model.addElement("Entry 4");
model.addElement("Entry 5");
list = new JList<>(model);
selected = new JLabel("Currently selected: none");
list.setSelectedIndex(2);
list.addListSelectionListener(e -> {
if(e.getValueIsAdjusting()) {
pcs.firePropertyChange(ITEM_SELECTED, null, null);
}
}
);
JButton removeItem = new JButton("Remove item");
removeItem.addActionListener(e -> {
pcs.firePropertyChange(DELETE_SELECTED, null, null);
}
);
mainPanel.add(new JScrollPane(list), BorderLayout.WEST);
mainPanel.add(removeItem, BorderLayout.NORTH);
mainPanel.add(selected, BorderLayout.CENTER);
pcs.addPropertyChangeListener(this);
frame.add(mainPanel);
frame.setSize(300, 400);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
String event = (String) evt.getPropertyName();
if (event.equals(ITEM_SELECTED)) {
selected.setText("Currently selected: " + list.getSelectedValue());
}
if (event.equals(DELETE_SELECTED)) {
int selectedIndex = list.getSelectedIndex();
model.removeElement(list.getSelectedValue());
if (selectedIndex > 0)
list.setSelectedIndex(selectedIndex-1);
else if (selectedIndex == 0)
list.setSelectedIndex(selectedIndex);
}
}
}
【问题讨论】:
-
我的处理方法有误吗? - 不确定您真正想要做什么。我不明白对 PropertyChangeListener 的需求。您已经在 ListSelectionListener 中处理了选择更改事件,为什么还要添加另一个间接级别。只需将当前在 PropertyChangeListener 中的处理逻辑添加到 ListSelectionListener 中即可。 “删除”逻辑也是如此。你已经有一个 ActionListener,为什么还要涉及 PropertyChangeListener?
-
阅读 How to Use Lists 上的 Swing 教程,了解为 JList 动态添加/删除项目的工作示例。
-
包含属性更改侦听器是为了让给定的示例模仿我的项目。在那里,所有东西都被设计成模块化并遵循 MVC,所以这个例子实际上是用至少 2 个独立的类编写的。我在这里写的所有东西都在一个类中,以便于复制粘贴和测试。我理解冗余。 :)
标签: java swing model-view-controller listener propertychangelistener