代码之家  ›  专栏  ›  技术社区  ›  Andrei Vajna II

我可以为jlist设置所选项目而不向侦听器引发事件吗?

  •  4
  • Andrei Vajna II  · 技术社区  · 14 年前

    我正在开发一个查看器,它使用jlist显示文档页面的缩略图。用户可以通过在jlist中选择它来打开页面,或者通过其他机制(如在文本框中输入数字)来打开页面。

    当使用后一个选项时,我希望jlist也选择页面。我使用setSelectedIndex()执行此操作,但这会触发一个事件,导致再次加载页面,就像用户在jList中单击并选择了页面一样,这会导致一些问题。

    在我看来,索引应该以某种方式设置(可能在模型中),以便只有jlist的UI更新,而不会触发索引已更改的事件。

    这有可能吗?还是有更好的方法来解决我的问题?

    2 回复  |  直到 14 年前
        1
  •  6
  •   Taisin    14 年前
    1. 你可以全部删除 ListSelectionListener 从列表中进行选择,然后再次添加。

    2. 你可以自己创造 ListSelectionModel 使用不引发事件并将其设置为选择模型的方法 JList 然后使用 getSelectionModel().yourSelectIndexMethod(index) .

    3. 您还可以将所有其他选择方法转移到列表中,如果通过其他方式选择页面,只需找到相应的条目并选择列表中的项目即可。这样可以选择项目并加载一次页面。

    选项2代码:

    public class ListTest extends JPanel{
    
    private static final String[] items = new String[]{"1", "2", "3"};
    private JList mylist;
    private JComboBox myCombo;
    private JTextArea myTA;
    
    public ListTest() {
        setLayout(new BorderLayout());
        myCombo = new JComboBox(items);
        myCombo.addActionListener(new ActionListener(){
    
            @Override
            public void actionPerformed(ActionEvent e){
                valueSelectedCombo(myCombo.getSelectedIndex());
            }
        });
        JPanel pn = new JPanel();
        pn.setLayout(new BoxLayout(pn, BoxLayout.X_AXIS));
        pn.add(myCombo);
        pn.add(Box.createHorizontalGlue());
        pn.add(new JButton(new AbstractAction("Clear"){
    
            @Override
            public void actionPerformed(ActionEvent e){
                myTA.setText("");
            }
        }));
        add(pn, BorderLayout.NORTH);
        add(new JScrollPane(getJList()), BorderLayout.WEST);
        add(new JScrollPane(myTA = new JTextArea()), BorderLayout.CENTER);
    }
    
    private void valueSelectedList(int index){
        myTA.setText(myTA.getText() + "\n" + items[index]);
    }
    
    private void valueSelectedCombo(int index){
        myTA.setText(myTA.getText() + "\n" + items[index]);
        ((CustomSelectionModel)mylist.getSelectionModel()).setSelectionSilent(index);
    }
    
    private JList getJList(){
        if (mylist == null){
            mylist = new JList(items);
            mylist.setSelectionModel(new CustomSelectionModel());
            mylist.addListSelectionListener(new ListSelectionListener(){
    
                @Override
                public void valueChanged(ListSelectionEvent e){
                    if (!e.getValueIsAdjusting()){
                        valueSelectedList(mylist.getSelectedIndex());
                    }
                }
            });
    
            mylist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            mylist.setPreferredSize(new Dimension(100, 106));
    
        }
        return mylist;
    }
    
    private static class CustomSelectionModel extends DefaultListSelectionModel{
    
        private boolean isSilent = false;
    
        public void setSelectionSilent(int firstIndex){
            isSilent = true;
            setSelectionInterval(firstIndex, firstIndex);
            isSilent = false;
        }
        protected void fireValueChanged(int firstIndex, int lastIndex, boolean isAdjusting){
            if (isSilent){
                return;
            }
            super.fireValueChanged(firstIndex, lastIndex, isAdjusting);
        }
    }
    
    public static void main(String[] args){
        JFrame frame = new JFrame("test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
        // Add content to the window.
        frame.add(new ListTest());
    
        // Display the window.
        frame.pack();
        frame.setSize(300, 200);
        frame.setVisible(true);
    }
    
    }
    
        2
  •  1
  •   Catalina Island    14 年前

    看起来像 setSelectedIndex() 只是在 ListSelectionModel . 也许你的 ListModel 可以标记或缓存结果,以便它不会再次加载。