我一直在寻找一个答案,将键绑定附加到JButton很多个小时,但仍然无法做到。 我有以下简单的程序,包括两个类。我试过用几种方法使用getInputMap()和getActionMap(),但没有成功。我希望它能做到以下几点: 当我按下键盘上的“1”键时,它会按下JButton btn1,当我按下“2”键时,它会按下JButton btn2(因此1或2会出现在JLabel上)。
//的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方法下获取keycode,而不是在keyTyped方法下 - 后者适合使用getKeyChar获取关键字符。使用getKeyCode而不是getKeyChar也更好,因为特定键具有键码,但不是keychar)。
对于按钮,我使用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。 这似乎是正确的答案,虽然我在尝试使用该建议时遇到此错误: 错误:预期的标识符
YEAH,我找到了解决方案!!!: (首先我告诉你代码,然后我将解释我修改过的内容。)
// class 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");}
}
};
}
所以,我做了以下事情: - 在类1中将一个ActionListener添加到btn1和btn2:
btn1.addActionListener(base.act);
我还使用了InputMap:
btn1.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke('1'),“press”);
这里要注意两件事:您必须将“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,因为没有它也可以使用。
对不起,如果我误解了某些内容而没有给出正确的解释。我只是一个爱好程序员,没有计算机科学的教育。但我希望,这个问题和所提供的答案可能会为许多其他人提供帮助。
答案 0 :(得分:4)
这是一种方法:
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");