Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用空格键触发JButton,或输入key,或单击鼠标_Java_Swing_Jbutton_Key Events - Fatal编程技术网

Java 使用空格键触发JButton,或输入key,或单击鼠标

Java 使用空格键触发JButton,或输入key,或单击鼠标,java,swing,jbutton,key-events,Java,Swing,Jbutton,Key Events,我试图获得一个简单的JFrame,其中有一个按钮可以在这些事件发生时触发事件: 按下Enter键,JButton具有焦点 按下空格键,JButton具有焦点 单击JButton 似乎Enter和空格键是“免费”的,同时在JButton上使用addActionListener进行默认的鼠标单击;问题是,我读到密钥绑定依赖于使用的外观 我试图通过向JButton的动作图中添加Enter和Spacebar来获得LaF中的通用行为,甚至还添加了一个随机键(“m”),以确保动作图正在执行(它是),但现

我试图获得一个简单的JFrame,其中有一个按钮可以在这些事件发生时触发事件:

  • 按下Enter键,JButton具有焦点
  • 按下空格键,JButton具有焦点
  • 单击JButton
似乎Enter和空格键是“免费”的,同时在JButton上使用addActionListener进行默认的鼠标单击;问题是,我读到密钥绑定依赖于使用的外观

我试图通过向JButton的动作图中添加Enter和Spacebar来获得LaF中的通用行为,甚至还添加了一个随机键(“m”),以确保动作图正在执行(它是),但现在鼠标点击丢失了。我似乎能够获得所有按键和鼠标单击的唯一方法是同时使用action map和addActionListener

有没有一种方法可以让这些键和鼠标绑定在所有LaF上一致地工作,而不必检测可能出现的所有LaF?我是否可以注册一个操作侦听器,该侦听器将在按键和鼠标事件上同时启动

我最喜欢的解决方案是将鼠标单击添加到JButton动作图中,并检测动作中发生的键或鼠标单击

我还在这里学习诀窍,所以这可能不是做事情的最好或最有效的方法;我肯定这是设计过度了。这是一种训练练习,我正在尝试我能得到的一切。欢迎任何和所有编码风格的评论

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;

public class Example extends JFrame {

// ============================
private class BtnListener extends AbstractAction {
    private static final long serialVersionUID = 1L;

    public void actionPerformed(ActionEvent ae) {
        System.out.println("\nclick button listener triggered");
        System.out.println(ae.getSource().getClass().toString());
    }
} // class BtnListener

private static final int NO_MODIFIER = 0;
private static final boolean ON_KEY_PRESS = false;
private static final KeyStroke ENTER_PRESSED = KeyStroke.getKeyStroke(
        KeyEvent.VK_ENTER, NO_MODIFIER, ON_KEY_PRESS);
private static final KeyStroke M_PRESSED = KeyStroke.getKeyStroke(
        KeyEvent.VK_M, NO_MODIFIER, ON_KEY_PRESS);
private static final KeyStroke SPACEBAR_PRESSED = KeyStroke.getKeyStroke(
        KeyEvent.VK_SPACE, NO_MODIFIER, ON_KEY_PRESS);
private JButton btnButton;
private final AbstractAction btnListener = new BtnListener();
private JPanel buttonPanel;
private JFrame frmMain;

public static void main(String[] args) {
    Example ex = new Example();
    ex.displayFrame();
}

Action btnActionListener = new AbstractAction() {
    private static final long serialVersionUID = 1L;

    public void actionPerformed(ActionEvent e) {
        System.out.println("\nkey button action triggerred");
        System.out.println(e.getSource().getClass().toString());
        if (e.getSource() instanceof JButton) {
            System.out.println("button");
        } else {
            System.out.println("Something else");
        }
    }
};

public Example() {
    initialize();
}

public void displayFrame() {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Throwable e) {
        e.printStackTrace();
    }
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                frmMain.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

private void initialize() {

    frmMain = new JFrame();
    btnButton = new JButton("Abutton");

    // Comment this out, you lose the mouse click
    btnButton.addActionListener(btnListener);

    // Comment out ActionMaps, but keep addActionListner (above), and
            // only lose M_PRESSED
    InputMap buttonFocusedMap = btnButton
            .getInputMap(JComponent.WHEN_FOCUSED);

    buttonFocusedMap.put(ENTER_PRESSED, "blah");
    btnButton.getActionMap().put("blah", btnActionListener);

    buttonFocusedMap.put(SPACEBAR_PRESSED, "blort");
    btnButton.getActionMap().put("blort", btnActionListener);

    buttonFocusedMap.put(M_PRESSED, "gaaak");
    btnButton.getActionMap().put("gaaak", btnActionListener);

    // Is there a way to add a mouse click to the ActionMap?

    buttonPanel = new JPanel();
    buttonPanel.add(btnButton);

    frmMain.getContentPane().add(buttonPanel);
    frmMain.setBounds(100, 100, 500, 432);
    frmMain.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

}

您可以(也可能应该)做的是创建一个抽象动作。您可以将AbstractAction用于ActionMap和单击(do JButton.setAction(…)

BasicButtonListener
,由
BasicButtonUI
使用,确保所有按钮(选中、单选、切换)在聚焦时都绑定到空格。这可以跨平台工作,即使单个外观可能会唯一地呈现各种按钮模型状态。按空格键可调用按下的
ui动作
,释放空格键可调用已释放的
ui动作
。当鼠标在按钮的边界内按下和释放时,也会发生同样的情况;按住按钮的同时将其拖到按钮外部,以查看启用状态的更改

在任何一种情况下,按下和释放的组合都会调用按钮的
actionPerformed()
方法


将Enter绑定到
操作
的一种方便方法是通过根窗格的方法,而不考虑焦点。这说明了单击按钮的所有三种方式。

非常好!谢谢你的深刻解释。