除非先点击 JButton,否则 keyPressed 不起作用
keyPressed doesn't work unless JButton clicked first
我创建了一个使用 JButtons 来递增数字的小应用程序。这些按钮不应该是可点击的,而是由键盘激活的(即 textField 中的数字随着键盘的按下而增加,而不是通过使用鼠标单击按钮来增加)。我的问题是,当应用程序首次启动时,键盘不会执行任何操作,直到我第一次单击其中一个按钮 - 即使单击按钮没有任何进展。我曾尝试制作其中一个按钮 requestFocusInWindow()
,认为如果它已经被聚焦,则按键会起作用,但无论我将它放在我的主要方法还是控制器中,这似乎都不起作用 class.我试图弄清楚我是否需要执行 KeyboardFocusManager
或 addFocusListener()
(但我不希望按钮 gains/loses 焦点时总是发生某些事情)。我已经尝试了很多让我头晕目眩的事情,试图添加到我的带有框架的主要方法或我的控制器 class。以下是我当前的代码:
Class 与 Main
import javax.swing.JFrame;
public class Count {
public static void main(String[] args) {
CountController frame = new CountController();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(560, 150);
frame.setVisible(true);
//I've tried to add the button and requestFocusInWindow here
//as well as tried a frame.addWindowFocusListener
}
} // end class
控制器Class
imports ...
public class CountController extends JFrame implements KeyListener {
private JLabel ...
private JTextField ...
private JButton ....
int ...
// no-argument constructor
public CountController() {
super("Title");
setLayout(null); // position GUI components explicitly
//set up JLabels in following manner
label = new JLabel("some label");
label.setBounds(47, 5, 45, 25);
label.setHorizontalAlignment(JLabel.CENTER);
add(label);
//set up JTextFields in following manner
textField = new JTextField("0");
textField.setBounds(47, 30, 45, 25);
textField.setHorizontalAlignment(JTextField.CENTER);
textField.setBackground(Color.WHITE);
textField.setEditable(false);
add(textField);
//set up JButtons in the following manner
button = new JButton("some text");
button.setBounds(15, 70, 110, 25);
button.setBackground(Color.WHITE);
add(button);
button.addKeyListener(this);
//I've tried adding requestFocusInWindow() here as well
} // end constructor
//begin KeyListener stuff
@Override
public void keyPressed(KeyEvent event){
int keyCode = event.getKeyCode();
switch(keyCode){
case #: //# is ASCII #
do some things;
call a method();
break;
}
}
@Override
public void keyReleased(KeyEvent event){
button.setBackground(Color.WHITE);
}
@Override
public void keyTyped(KeyEvent event){
// nothing but this is needed for implementing KeyListener
}
//List of methods that are called from switch
...
//I've tried to add a public void initialize(){}
}//end CountController class
我将不胜感激任何关于让它工作的意见,这样我就不必在我的键工作之前先点击一个按钮。
谢谢!
虽然我不太清楚你的代码应该完成什么,但你的问题是你 addKeyListener(this)
到 button
但你的按钮没有焦点,键也没有按下时做任何事情。尝试将 KeyListener()
添加到其他一些 GUI 组件,例如 textfield
,因为它是第一个组件并且专注于开始(从您提供的代码),并查看它是否有效.
为了让侦听器触发事件,它注册到的组件必须首先获得焦点并且具有焦点。请改用 key bindings API。
下面使用JComponent.WHEN_IN_FOCUSED_WINDOW
来定义按键事件产生的上下文。在此配置中,焦点是什么并不重要,只要 window 当前得到焦点
,事件仍会生成
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class Count {
public static void main(String[] args) {
CountController frame = new CountController();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(560, 150);
frame.setVisible(true);
//I've tried to add the button and requestFocusInWindow here
//as well as tried a frame.addWindowFocusListener
}
public static class CountController extends JFrame {
// no-argument constructor
public CountController() {
super("Title");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
//set up JLabels in following manner
JLabel label = new JLabel("some label");
label.setHorizontalAlignment(JLabel.CENTER);
add(label, gbc);
//set up JTextFields in following manner
JTextField textField = new JTextField("0", 20);
textField.setHorizontalAlignment(JTextField.CENTER);
textField.setBackground(Color.WHITE);
textField.setEditable(false);
add(textField, gbc);
//set up JButtons in the following manner
JButton button = new JButton("some text");
add(button, gbc);
InputMap im = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap am = button.getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_3, KeyEvent.SHIFT_DOWN_MASK), "Pressed.#");
am.put("Pressed.#", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText() + "#");
}
});
} // end constructor
}//end CountController class
} // end class
虽然我会针对父容器而不是按钮注册绑定,但那只是我。
而且,不使用 null
布局的原因...这就是您的原始代码在我的电脑上的样子
我创建了一个使用 JButtons 来递增数字的小应用程序。这些按钮不应该是可点击的,而是由键盘激活的(即 textField 中的数字随着键盘的按下而增加,而不是通过使用鼠标单击按钮来增加)。我的问题是,当应用程序首次启动时,键盘不会执行任何操作,直到我第一次单击其中一个按钮 - 即使单击按钮没有任何进展。我曾尝试制作其中一个按钮 requestFocusInWindow()
,认为如果它已经被聚焦,则按键会起作用,但无论我将它放在我的主要方法还是控制器中,这似乎都不起作用 class.我试图弄清楚我是否需要执行 KeyboardFocusManager
或 addFocusListener()
(但我不希望按钮 gains/loses 焦点时总是发生某些事情)。我已经尝试了很多让我头晕目眩的事情,试图添加到我的带有框架的主要方法或我的控制器 class。以下是我当前的代码:
Class 与 Main
import javax.swing.JFrame;
public class Count {
public static void main(String[] args) {
CountController frame = new CountController();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(560, 150);
frame.setVisible(true);
//I've tried to add the button and requestFocusInWindow here
//as well as tried a frame.addWindowFocusListener
}
} // end class
控制器Class
imports ...
public class CountController extends JFrame implements KeyListener {
private JLabel ...
private JTextField ...
private JButton ....
int ...
// no-argument constructor
public CountController() {
super("Title");
setLayout(null); // position GUI components explicitly
//set up JLabels in following manner
label = new JLabel("some label");
label.setBounds(47, 5, 45, 25);
label.setHorizontalAlignment(JLabel.CENTER);
add(label);
//set up JTextFields in following manner
textField = new JTextField("0");
textField.setBounds(47, 30, 45, 25);
textField.setHorizontalAlignment(JTextField.CENTER);
textField.setBackground(Color.WHITE);
textField.setEditable(false);
add(textField);
//set up JButtons in the following manner
button = new JButton("some text");
button.setBounds(15, 70, 110, 25);
button.setBackground(Color.WHITE);
add(button);
button.addKeyListener(this);
//I've tried adding requestFocusInWindow() here as well
} // end constructor
//begin KeyListener stuff
@Override
public void keyPressed(KeyEvent event){
int keyCode = event.getKeyCode();
switch(keyCode){
case #: //# is ASCII #
do some things;
call a method();
break;
}
}
@Override
public void keyReleased(KeyEvent event){
button.setBackground(Color.WHITE);
}
@Override
public void keyTyped(KeyEvent event){
// nothing but this is needed for implementing KeyListener
}
//List of methods that are called from switch
...
//I've tried to add a public void initialize(){}
}//end CountController class
我将不胜感激任何关于让它工作的意见,这样我就不必在我的键工作之前先点击一个按钮。 谢谢!
虽然我不太清楚你的代码应该完成什么,但你的问题是你 addKeyListener(this)
到 button
但你的按钮没有焦点,键也没有按下时做任何事情。尝试将 KeyListener()
添加到其他一些 GUI 组件,例如 textfield
,因为它是第一个组件并且专注于开始(从您提供的代码),并查看它是否有效.
为了让侦听器触发事件,它注册到的组件必须首先获得焦点并且具有焦点。请改用 key bindings API。
下面使用JComponent.WHEN_IN_FOCUSED_WINDOW
来定义按键事件产生的上下文。在此配置中,焦点是什么并不重要,只要 window 当前得到焦点
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
public class Count {
public static void main(String[] args) {
CountController frame = new CountController();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(560, 150);
frame.setVisible(true);
//I've tried to add the button and requestFocusInWindow here
//as well as tried a frame.addWindowFocusListener
}
public static class CountController extends JFrame {
// no-argument constructor
public CountController() {
super("Title");
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
//set up JLabels in following manner
JLabel label = new JLabel("some label");
label.setHorizontalAlignment(JLabel.CENTER);
add(label, gbc);
//set up JTextFields in following manner
JTextField textField = new JTextField("0", 20);
textField.setHorizontalAlignment(JTextField.CENTER);
textField.setBackground(Color.WHITE);
textField.setEditable(false);
add(textField, gbc);
//set up JButtons in the following manner
JButton button = new JButton("some text");
add(button, gbc);
InputMap im = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap am = button.getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_3, KeyEvent.SHIFT_DOWN_MASK), "Pressed.#");
am.put("Pressed.#", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
textField.setText(textField.getText() + "#");
}
});
} // end constructor
}//end CountController class
} // end class
虽然我会针对父容器而不是按钮注册绑定,但那只是我。
而且,不使用 null
布局的原因...这就是您的原始代码在我的电脑上的样子