JavaSwing-ActionListener比KeyListener慢得多

JavaSwing-ActionListener比KeyListener慢得多,java,swing,Java,Swing,对于一个程序,当按下按钮“1”时,我正在使用KeyListener向ArrayList添加一些内容。此列表中的对象不断被可视化。使用KeyListener,即使按下按钮,也能流畅地工作 后来,我在GUI中添加了一个JMenuBar。向ArrayList添加内容现在有一个自己的JMenuItem,其加速器设置为击键“1”,还有一个ActionListener,它执行与以前的KeyListener相同的操作。然而,现在的表现非常糟糕。保持按下“1”将会非常滞后,与KeyListener相比,它的速度

对于一个程序,当按下按钮“1”时,我正在使用KeyListener向ArrayList添加一些内容。此列表中的对象不断被可视化。使用KeyListener,即使按下按钮,也能流畅地工作

后来,我在GUI中添加了一个JMenuBar。向ArrayList添加内容现在有一个自己的JMenuItem,其加速器设置为击键“1”,还有一个ActionListener,它执行与以前的KeyListener相同的操作。然而,现在的表现非常糟糕。保持按下“1”将会非常滞后,与KeyListener相比,它的速度非常慢

为什么这么慢?我做错什么了吗?有更好的办法吗

    ...
    AL al = new AL();
    menu.add(createMenuItem("Add", KeyEvent.VK_1, al));
}

private JMenuItem createMenuItem(String text, int key, ActionListener al){
    JMenuItem menuItem = new JMenuItem(text);
    menuItem.setAccelerator(KeyStroke.getKeyStroke(key, 0));
    menuItem.addActionListener(al);
    return menuItem;
}

private class AL implements ActionListener{
    public void actionPerformed(ActionEvent e){
        int keycode = ((JMenuItem)e.getSource()).getAccelerator().getKeyCode();
        bla(keycode);
    }
}

其他一些东西正在减慢您的应用程序。这仍然是十几个响应。一种有用的方法是让菜单项和其他组件共享相同的内容,如图和所示


附录:不要实现
ActionListener
,而是通过扩展
AbstractAction
来实现,这将使管理快捷键变得更容易。

看起来,菜单快捷键的处理方式是减速。它可能是L&F,甚至是OS,因为当我分析它时,依赖Java代码(WindowsXP)的系统中没有热点。一种解决方法是将键绑定添加到根窗格,而不是使用菜单加速器

按“1”触发KeyListener on按钮(快速) 按“2”触发菜单加速器(慢速) 按“3”触发按键绑定(快速) 按“4”触发根窗格上的键绑定(fast)


按下的
键是什么(keycode)应该做的代码?它是通过绊倒关键侦听器来实现的吗?提出SSCCE是的,我同意提出SSCCE的建议。我们大多数人在使用ActionListener时都不会遇到“延迟”问题,这使得您使用的ActionListener不太可能是问题的根源,而更可能是代码中存在其他问题。什么?我不知道,我可以帮忙。请在回复之前检查链接,因为有很多关于我们所要求的内容的误解都被链接清除了。我不知道,因为我没有可以运行、测试、修改和检查的代码。我不知道你在这里回答问题有多长时间了,但如果你这么做了多长时间,你会很快改变你对sscce价值的看法。这取决于您自己,取决于您真正需要我们的帮助的程度。嗯,我的问题不是由于几个键绑定而导致的无响应,而是因为用JMenuItem accelerator+ActionListener替换了一个(工作正常的)KeyListener。明天我将发布一个SSCCE,我希望它会有所帮助。谢谢你@莫罗:抱歉搞混了;菜单在内部使用键绑定来实现加速器。当你的答案还存在的时候,请在评论中告诉我。很抱歉,我昨天没有得到你的答案,尽管这可能是我一直在寻找的解决方案。Walter Laan已经提供了一个很好的例子。无论如何谢谢你!哇,这正是我想要的,非常感谢你的回答。你的SSCCE甚至比我想做的要好得多;)因此,我使用菜单加速器和JPanel上的键绑定(尽管两者的操作相同),“2”在Win7上也很慢。显然,它是OS依赖的。@ Morrow:很高兴你有一个解决方案(沃尔特是一个聪明的家伙,1 +),但是考虑一下,他必须创建一个SSCCE来提出并测试一个解决方案,所以你可以看到SSCCE是如何提供一个解决方案,无论是由你还是由他。如果你先这么做的话,你会为他节省很多额外的工作,他真的不需要在这些工作上浪费时间,而且你会更快地找到解决方案。这里的关键是,这是你的问题,因此,努力使我们能够更容易地帮助你的责任应该在你身上,而不是在沃尔特身上。对不起,打了一匹死马,但正如你所说,这是我非常强烈的感受。我是SSCCE宗教的改道者。我再次为你感到高兴,也很高兴从沃尔特那里学到了另一个新东西。我知道这一点,我道歉,我真的不想把工作转移给别人!当我发布这个问题时,我真的认为这个问题是这里的“专业人士”应该知道的,有人可以很容易地告诉我应该做什么。因此,我一开始没有想到SSCCE。
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;

public class TestKeySpeed {
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                final JTextArea area = new JTextArea(20, 40);
                area.setEditable(false);

                JButton button = new JButton("Just something that has focus");
                button.addKeyListener(new KeyAdapter() {
                    @Override
                    public void keyPressed(KeyEvent e) {
                        if (e.getKeyCode() == KeyEvent.VK_1) {
                            area.append("1");
                        }
                    }
                });

                AbstractAction action = new AbstractAction("Add") {
                    {
                        putValue(ACCELERATOR_KEY, KeyStroke.getKeyStroke('2'));
                    }

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        area.append("2");
                    }
                };
                button.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
                        KeyStroke.getKeyStroke('3'), "add3");
                button.getActionMap().put("add3", action);

                JMenu menu = new JMenu("File");
                menu.add(action);
                JMenuBar bar = new JMenuBar();
                bar.add(menu);
                JFrame frame = new JFrame("Test");
                frame.getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(
                        KeyStroke.getKeyStroke('4'), "add4");
                frame.getRootPane().getActionMap().put("add4", action);

                frame.setJMenuBar(bar);
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.getContentPane().add(new JScrollPane(area));
                frame.getContentPane().add(button, BorderLayout.PAGE_END);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                button.requestFocusInWindow();
            }
        });
    }
}