按下其他键后,JButton键侦听器不会触发

时间:2016-05-01 02:18:48

标签: java swing user-interface keylistener

我正在用Java创建一个虚拟钢琴。到目前为止,我有两个按键的动作监听器,它们大部分都在工作,而不是一个接一个。例如,我点击键盘上的q并按下c键并播放c,这就是它应该做的事情。但是我想通过敲击键盘上的w来点击钢琴上的d键,如果我已经按下q键,它就不会这样做。

// c key
        JButton btnC3 = new JButton("");
        btnC3.addKeyListener(new KeyAdapter() 
        {
            @Override
            public void keyPressed(KeyEvent e) 
            {
                if (e.getKeyCode() == KeyEvent.VK_Q)
                {
                    btnC3.doClick();
                }
            }
        });
        btnC3.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent e) 
            {
                // play c
                try 
                {
                    keys.playNote(Notes.c3.getValue());
                } 
                catch (InterruptedException e1) 
                {
                    e1.printStackTrace();
                }
                catch (InvalidMidiDataException e2)
                {
                    e2.printStackTrace();
                }
            }
        });
// d key
JButton btnD3 = new JButton("");
        btnD3.addKeyListener(new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) 
            {
                if (e.getKeyCode() == KeyEvent.VK_W)
                {
                    btnD3.doClick();
                }
            }
        });
        btnD3.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent e) 
            {
                // play d
                try 
                {
                    keys.playNote(Notes.d3.getValue());
                } 
                catch (InterruptedException e1) 
                {
                    e1.printStackTrace();
                }
                catch (InvalidMidiDataException e2)
                {
                    e2.printStackTrace();
                }
            }
        });
        btnD3.setBackground(Color.WHITE);
        btnD3.setBounds(wKeyWidth*1, 0, wKeyWidth, wKeyHeight);
        frame.getContentPane().add(btnD3);

2 个答案:

答案 0 :(得分:3)

专注是问题。按下q时它会起作用,因为该按钮具有焦点。如果按下w,无论你是否先按q,因为" q"按钮始终关注。您应该使用KeyBindings。尽管任何组件都有重点,它们仍可正

另一个解决方案是将q和w按钮添加到添加到JFrame上的keylistener并使用requestFocus()和grabFocus()。

但是你需要为JFrame中的keylistener添加实现,并为按钮按下和释放按钮。

这是一个完美的链接,可以看到焦点如何影响按键在摇摆中的工作方式

http://www.javaworld.com/article/2076720/core-java/focus-on-swing.html

答案 1 :(得分:1)

问题与键盘焦点有关,'use strict'; var mongoose = require('mongoose'); require('../../../public_ui/models/Users'); var User = mongoose.model('User'); 只会在侦听器注册到IS可聚焦和HAS焦点时生成事件。

显然,当点击按钮时,"它获得了焦点,这意味着其他任何组件都无法响应。

基本答案是,使用Use Key Bindings API

您可以做出许多选择,您可以使用当前容器来注册密钥绑定,例如......

KeyListener

或者您可以在各个组件中注册它们。选择主要取决于您希望解决方案的可重用性。

例如,您可以创建一个InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW); ActionMap am = getActionMap(); JButton btnC3 = new JButton(""); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_Q, 0), "c3"); am.put("c3", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { btnC3.doClick(); } }); btnC3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { // play c try { keys.playNote(Notes.c3.getValue()); } catch (InterruptedException e1) { e1.printStackTrace(); } catch (InvalidMidiDataException e2) { e2.printStackTrace(); } } }); JButton btnD3 = new JButton(""); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "d3"); am.put("d3", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { btnD3.doClick(); } }); ,它可以同时应用于Action和键绑定,这意味着您无需以编程方式点击该按钮。

例如......

JButton

(我没有你的代码,所以我只是制作了一些课程名称)

然后你可以简单地使用......

public class NoteAction extends AbstractAction {
    private Note note;
    private Keys keys;

    public NoteAction(Note note, Keys keys) {
        this.note = note;
        this.keys = keys;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        keys.playNote(note.getValue());
    }

}

进行设置。

有关详细信息,请参阅How to Use Actions