当调用setSelected方法时,ListSelectionListener不会触发事件。

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

第一个问题在这里,希望我做的正确。

下面是我的问题的一个最小的例子,我很快就写出了我的项目的代表。我为一个包含一些对象的JList创建了一个自定义的渲染器(在这个例子中,我使用了Strings来说明问题)。我的问题是,据我所知,如果我为一个JList添加一个 ListSelectionListener 在名单上,该家族的 setSelected...() 方法不会触发触发条件的事件。if(e.getValueIsAdjusting()).

在下面的例子中,启动程序后,问题就显而易见了:即使是 list.setSelectedIndex(2); 在将JLabel的选定文本指定为 "none "后被调用,它不会改变,直到您(用户)点击列表项。事实上,它必须是一个与当前选择的项目不同的项目。

我希望有这样的功能,这样我的程序流程就会是,当用户从列表中添加和删除项目后,一旦选定的列表项目被改变,"视图 "就会立即更新。

是我做错了什么,还是我的方法不正确?

谢谢您 :)

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);
        }
    }
}
java swing model-view-controller listener propertychangelistener
1个回答
0
投票

我已经为一个JList创建了一个自定义的渲染器。e.getValueIsAdjusting() 方法检查该值是否仍在调整中。在你的案例中,看起来像是由以下方法触发的事件。list.setSelectedIndex(2) 会有 e.getValueIsAdjusting() 返回 false。

你也许可以通过做相反的检查来解决这个问题。!e.getValueIsAdjusting().

这将检查任何响应的变化是该事件链的最终变化。

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