gpt4 book ai didi

java - 将键绑定(bind)到 JButton

转载 作者:行者123 更新时间:2023-11-29 03:00:34 27 4
gpt4 key购买 nike

这个问题在这里已经有了答案:





Add key bindings to JButtons that get their actions from action commands?

(1 个回答)


6年前关闭。




我一直在寻找将键绑定(bind)附加到 JButton 的答案很多小时,但仍然没有成功。
我有以下由两个类组成的简单程序。我尝试使用 getInputMap() 和 getActionMap() 几种方法,但没有成功。我希望它执行以下操作:
当我按下键盘上的键“1”时,它会按下 JButton btn1,当我按下键“2”时,它会按下 JButton btn2(因此 JLabel 上会出现 1 或 2)。

//class1://

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;

public class event06 extends JFrame {

event06b base = new event06b(this);

JButton btn1 = new JButton("1");
JButton btn2 = new JButton("2");
JLabel label = new JLabel("");

public event06() {
super();
setBounds(300,300, 200,150);
setResizable(true);
setTitle("Button with keybinding");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

btn1.addActionListener(base);
btn2.addActionListener(base);

FlowLayout flo = new FlowLayout(FlowLayout.CENTER);
setLayout(flo);
add(btn1);
add(btn2);
add(label);

setVisible(true);
}

public static void main(String[] args) {
event06 window = new event06();
}
}


//class 2://
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;

public class event06b implements ActionListener {
event06 gui;

public event06b (event06 in) {
gui = in;
}
public void actionPerformed(ActionEvent pressed) {
Object source = pressed.getSource();
if (source == gui.btn1) {gui.label.setText("1");}
else if (source == gui.btn2) {gui.label.setText("2");}
}
}

更新:
(我还没有 15 的声誉,所以我不能回答我自己的问题,据我所知,我不能在评论中发布代码或长答案,所以我正在修改我的问题)。

我设法发现的是,如果没有按钮具有焦点,则仅使用 KeyListeners 才有效。
请参见以下示例:
 //in class 1:// 
FlowLayout flo = new FlowLayout(FlowLayout.CENTER);
setLayout(flo);
add(btn1);
btn1.setEnabled(false);
btn2.setEnabled(false);
add(btn2);
add(label);

btn1.addActionListener(base);
btn2.addActionListener(base);
addKeyListener(base);

在这里,两个按钮 btn1 和 btn2 被禁用,因此它们没有焦点,而是窗口处于焦点上。这就是 KeyListener 可以工作的原因:
public void keyPressed (KeyEvent evt) {
int keycode = evt.getKeyCode();
gui.label.setText(Integer.toString(keycode));
}

public void keyReleased(KeyEvent txt) {}
public void keyTyped(KeyEvent txt) {}

在这种情况下,class1 中的 JLabel 显示已按下的键的键码。 (注意,您可以在 keyPressed 方法下获取键码,而不是在 keyTyped 方法下 - 后者适用于使用 getKeyChar 获取键字符。使用 getKeyCode 而不是 getKeyChar 也更好,因为特定键具有键码,但不是 key 字符)。

对于按钮,我使用 actionPerformed 方法:
public void actionPerformed(ActionEvent pressed) {
Object source = pressed.getSource();
if (source == gui.btn1) {gui.label.setText("1");}
else if (source == gui.btn2) {gui.label.setText("2");}
}

由于此处禁用了按钮,因此这不起作用。到目前为止,我无法将 keyCode 连接到这个 actionPerformed 方法。
在 Veluria 提供的示例中,这个 actionPerformed 方法是 AbstractAction 的一部分,并且在那里使用了 InputMaps 和 ActionMaps。
这似乎是正确的答案,尽管当我尝试使用该建议时出现此错误:
错误:需要标识符

是的,我找到了解决方案!!!:
(首先我给你看代码,然后我会解释我修改了什么)。

//类1://
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class event06 extends JFrame {

event06b base = new event06b(this);

JButton btn1 = new JButton("1");
JButton btn2 = new JButton("2");
JLabel label = new JLabel("");


public event06() {
super();
setBounds(300,300,250,75);
setResizable(false);
setTitle("Buttons with key");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

FlowLayout flo = new FlowLayout(FlowLayout.CENTER);
setLayout(flo);
add(btn1);
btn1.setEnabled(true);
btn2.setEnabled(true);
add(btn2);
add(label);

btn1.addActionListener(base.act);
btn1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('1'), "pressed");
btn1.getActionMap().put("pressed", base.act);

btn2.addActionListener(base.act);
btn2.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('2'), "pressed");
btn2.getActionMap().put("pressed", base.act);


setVisible(true);
}

public static void main(String[] args) {
event06 window = new event06();
}
}

类2:
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;

public class event06b {
event06 gui;

public event06b (event06 in) {
gui = in;
}

Action act = new AbstractAction() {

@Override
public void actionPerformed(ActionEvent pressed) {
Object source = pressed.getSource();
if (source == gui.btn1) {gui.label.setText("1");}
else if (source == gui.btn2) {gui.label.setText("2");}
}
};
}

所以,我做了以下事情:
- 在 btn1 和 btn2 中添加了第 1 类的 ActionListener:
btn1.addActionListener(base.act);
  • 我还使用了 InputMap:

    btn1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('1'), "pressed");
  • 这里需要注意两点:您必须将“JComponent.WHEN_IN_FOCUSED_WINDOW”文本放在圆括号中,这样即使按钮没有焦点,您也可以从键中获取输入。另一件事是,当你使用 getKeyStroke('1') 时,你必须给一个字符,所以使用 ' ' 而不是 ""。 (我看到许多例子中都使用了“”)。

  • 然后我使用了 ActionMap,如下所示:
    btn1.getActionMap().put("pressed", base.act);

    请注意,在这里以及在 ActionListener 中,我使用 base.act 来引用另一个类(base 指的是 class2,act 指的是里面的 Action)

    在class2中,我将actionPerformed方法放在了AbstractAction中,并使用了@Override。我不知道为什么必须使用@Override,因为没有它它也可以工作。

    对不起,如果我误解了某些内容并且没有给出正确的解释。我只是一个爱好程序员,没有受过计算机科学教育。但我希望,这个问题和所提供的答案可能会给许多处于同一条船上的人带来帮助。

    最佳答案

    这是一种方法:

    Action action = new AbstractAction("1") {
    @Override
    public void actionPerformed(ActionEvent e) {
    label.setText("1");
    }
    };
    action.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("1"));
    btn1.setAction(action);
    btn1.getActionMap().put("setOneAction", action);
    btn1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
    (KeyStroke) action.getValue(Action.ACCELERATOR_KEY), "setOneAction");

    关于java - 将键绑定(bind)到 JButton,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35259244/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com