按下箭头时键绑定没有响应

时间:2015-09-04 11:39:40

标签: java swing key-bindings

您好我在Java(在Mac中)开发应用程序。当用户按下箭头时我想要它做某事。

我的代码如下:

public class Main {

static JScrollPane scrollPane;

public static void main(String[] args) {


    JFrame f = new JFrame();
    Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
    f.setBounds(0, 0, dim.width, dim.height);

    StandartPanel p = new StandartPanel();

    f.add(p);

    JToolBar tb = new JToolBar();

    tb.add(new JButton("button"));

    f.add(tb);
    f.setVisible(true);
}

}

它只是一个程序,它创建一个JFrame并在其中放入一个StandartPanel和一个带有按钮的JToolBar。

StandartPanel的代码如下:

public class StandartPanel extends JPanel {


public StandartPanel () {

    for( int i = 0; i < 10; i++)
        this.add(new JLabel("Jlabel number: " + i));

    this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "forward");
    this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "forward");
    this.getActionMap().put("forward", new AbstractAction() {

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("pressed");
        }
    });
}

}

for循环并不重要,重要的是它打印&#34;按下&#34;当按下D或Down时。

当我实际按下D时,它会打印&#34;按下&#34;但当我点击它时什么也没做。

在尝试了一些事情后,我发现如果不是将JButton添加到JToolBar中,而是添加一个JLabel它可以工作(如果我不添加任何东西,它也可以工作)。

因此,将JButton添加到JToolBar会以某种方式停止使用向下按钮进行键绑定。

关于它为什么会发生以及如何解决的任何想法?

谢谢!

2 个答案:

答案 0 :(得分:1)

最简单的方法是设置你的( JToolBar和)JButton不可聚焦。 (参见this,JToolBar通常会注册UP / DOWN / LEFT / RIGHT来切换工具栏内按钮的焦点。)但要小心!这将阻止JToolbar从一个项目“跳跃”到另一个项目。 (如果你想保留这个功能,请看看MadProgrammer的答案) - 在你的代码中实现它看起来像这样:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;

public class Main {

    static JScrollPane scrollPane;

    public static void main(String[] args) {

        JFrame f = new JFrame();
        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
        f.setBounds(0, 0, dim.width, dim.height);

        StandartPanel p = new StandartPanel();

        f.add(p);

        JToolBar tb = new JToolBar();

        JButton button = new JButton("Button");
        button.setFocusable(false);

        tb.add(button);
        //tb.setFocusable(false);

        f.add(tb, BorderLayout.NORTH);
        f.setVisible(true);
    }

    static class StandartPanel extends JPanel {

        public StandartPanel() {

            for (int i = 0; i < 10; i++) {
                this.add(new JLabel("Jlabel number: " + i));
            }

            this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                    KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "forward");
            this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                    KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "forward");
            this.getActionMap().put("forward", new AbstractAction() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    System.out.println("pressed");
                }
            });
        }

    }

}

答案 1 :(得分:1)

在我的Mac上测试它:

this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "forward");

没有用,但由于某些原因我无法解释,使用......

this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), "forward");

确实

哦,而不是使用......

Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
f.setBounds(0, 0, dim.width, dim.height);

考虑使用......

f.setExtendedState(JFrame.MAXIMIZED_BOTH);

它不仅会给出一个类似的结果,它会考虑像隐藏/显示的停靠点这样的东西,并以对其状态更正确的方式表示窗口状态(即最大化而不仅仅是“填充”该区域)