当前位置: 首页 > 面试题库 >

是否可以在不将事件引发给侦听器的情况下为JList设置所选项目?

璩涵衍
2023-03-14
问题内容

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

当使用后一种替代方法时,我希望JList也选择页面。我使用setSelectedIndex()进行此操作,但是这触发了一个事件,该事件导致再次加载页面,就像用户单击并选择了JList中的页面一样,这给我带来了一些问题。

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

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


问题答案:
  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);
}

}


 类似资料:
  • 问题内容: 在以下示例代码中,我将事件处理程序附加到包含文本“foo”的范围。该处理程序是一个匿名函数,会弹出一个。 但是,如果我将其分配给父节点的,则此事件处理程序将被销毁-单击“ foo”将无法弹出警报框。 这个可以解决吗? 问题答案: 不幸的是,即使您尝试附加,分配给也会导致所有子元素的破坏。如果要保留子节点(及其事件处理程序),则需要使用DOM函数: 编辑: 鲍勃的解决方案,从评论。发表您

  • 问题内容: 在以下示例代码中,我将事件处理程序附加到包含文本“ foo”的范围。该处理程序是一个匿名函数,会弹出一个。 但是,如果我将其分配给父节点的,则此事件处理程序将被销毁-单击“ foo”将无法弹出警报框。 这个可以解决吗? 问题答案: 不幸的是,即使您尝试附加,分配给也会导致所有子元素的破坏。如果要保留子节点(及其事件处理程序),则需要使用DOM函数:

  • 问题内容: 我有以下情况。 我有一个从另一个基类继承并重写一个方法的Java类。基本方法不会引发异常,因此没有声明。 现在我自己的方法应该能够引发异常,但是我要么有选择 吞下异常 添加抛出声明 两者都不令人满意,因为第一个会默默地忽略异常(好的,我可以执行一些日志记录),第二个会因为方法头不同而产生编译器错误。 问题答案: 如果确实需要,可以抛出未经检查的异常而不必声明它们。未检查的异常扩展。扩展

  • 问题内容: 有一个Java文件,其中包含一些依赖项jar。但是现在,我没有那些jars,必须将其编译为.class文件。 是否有可能做到这一点? 更新 感谢您的回答。 起初,我认为我们可以为缺少的依赖项创建一些存根,这很简单但是很无聊。既然我们可以创建存根而不会丢失存根以使编译器满意,那么为什么我们不能使工具自动完成呢?该工具不需要创建存根,而是读取java文件,收集信息,然后构建.class文件

  • 我正在编写一个手势/动作库,它还管理事件侦听器和触发。我已经实现了我的库,通过一个API支持手势对象设置被动侦听器,该API如下:。My lib支持多种手势,设置多个听众,包括被动和非被动。lib将确保最多只有一个真正的侦听器连接到DOM。因此,我们最多可以有2个touchstart监听器,其中一个是被动监听器,另一个不是。 我的问题和问题是,我无法检测接收到的事件是否附加了选项。我认为我可以在本

  • Project Reactor是否可以在一个mono中等待一个事件/条件,而不需要使用每个mono的阻塞线程?使用,我可以完成这样的事情,但我不知道如何使用Project Reactor。 我的问题是我需要将请求与响应相关联。响应时间变化很大,有些甚至永远不会得到回复和超时。在客户端,每个请求阻塞线程不是问题,但由于这是一个服务器应用程序,我不想最终导致每个请求产生一个线程阻塞等待响应。 API如