Java 即使选择了JTextField,箭头键键绑定仍然有效
我正在使用键绑定,并在聚焦窗口中使用条件WHEN,以便键始终工作。然而,如果选择了JTextField,则箭头键(左、右、上、下)键绑定似乎会停止工作 简单地说,我希望无论JComponent的焦点是什么,键绑定都能始终工作Java 即使选择了JTextField,箭头键键绑定仍然有效,java,swing,focus,jtextfield,key-bindings,Java,Swing,Focus,Jtextfield,Key Bindings,我正在使用键绑定,并在聚焦窗口中使用条件WHEN,以便键始终工作。然而,如果选择了JTextField,则箭头键(左、右、上、下)键绑定似乎会停止工作 简单地说,我希望无论JComponent的焦点是什么,键绑定都能始终工作 import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.WindowConstants;
public class Test extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
private static JTextField field;
private static JFrame frame;
private static boolean up = false, down = false, left = false, right = false;
private static int x = 275, y = 275;
public static void main(String[] args) {
Test t = new Test();
t.setBounds(0, 0, 1200, 600);
t.setVisible(true);
field = new JTextField();
field.setBounds(20, 20, 100, 20);
Timer repaintTimer = new Timer(2, t);
frame = new JFrame();
frame.setSize(600, 600);
setUpKeyActions(t);
frame.add(field);
frame.add(t);
Dimension dim = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLocation((dim.width - frame.getWidth()) / 2, (dim.height - frame.getHeight()) / 2);
frame.getContentPane().setLayout(null);
frame.setAlwaysOnTop(true);
frame.setResizable(false);
repaintTimer.start();
frame.setVisible(true);
frame.requestFocus();
}
private static void setUpKeyActions(Test t) {
int condition = WHEN_IN_FOCUSED_WINDOW;
new KeyAction(t, condition, KeyEvent.VK_UP, 0, false) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
up = true;
}
};
new KeyAction(t, condition, KeyEvent.VK_UP, 0, true) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
up = false;
}
};
new KeyAction(t, condition, KeyEvent.VK_LEFT, 0, false) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
left = true;
}
};
new KeyAction(t, condition, KeyEvent.VK_LEFT, 0, true) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
left = false;
}
};
new KeyAction(t, condition, KeyEvent.VK_RIGHT, 0, false) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
right = true;
}
};
new KeyAction(t, condition, KeyEvent.VK_RIGHT, 0, true) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
right = false;
}
};
new KeyAction(t, condition, KeyEvent.VK_DOWN, 0, false) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
down = true;
}
};
new KeyAction(t, condition, KeyEvent.VK_DOWN, 0, true) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
down = false;
}
};
}
private static abstract class KeyAction extends AbstractAction {
private static final long serialVersionUID = 1L;
KeyAction(JComponent component, int condition, int keyCode, int modifiers, boolean onKeyRelease) {
InputMap inputMap = component.getInputMap(condition);
ActionMap actionMap = component.getActionMap();
KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode, modifiers, onKeyRelease);
inputMap.put(keyStroke, keyStroke.toString());
actionMap.put(keyStroke.toString(), this);
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(up)
y -= 1;
if(down)
y += 1;
if(right)
x += 1;
if(left)
x -= 1;
if(x < 0)
x = 0;
else if(x > frame.getWidth() - 30)
x = frame.getWidth() - 30;
if(y < 0)
y = 0;
else if(y > frame.getHeight() - 50)
y = frame.getHeight() - 50;
g.drawRect(x, y, 30, 30);
}
@Override
public void actionPerformed(ActionEvent e) {
frame.repaint();
}
}
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.KeyEvent;
导入javax.swing.AbstractAction;
导入javax.swing.ActionMap;
导入javax.swing.InputMap;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JTextField;
导入javax.swing.KeyStroke;
导入javax.swing.Timer;
导入javax.swing.WindowConstants;
公共类测试扩展JPanel实现ActionListener{
私有静态最终长serialVersionUID=1L;
私有静态JTextField字段;
私有静态JFrame;
私有静态布尔值up=false,down=false,left=false,right=false;
私有静态int x=275,y=275;
公共静态void main(字符串[]args){
测试t=新测试();
t、 立根(0,0,1200,600);
t、 setVisible(真);
field=新的JTextField();
场地.立根(20,20,100,20);
定时器重新绘制定时器=新定时器(2,t);
frame=新的JFrame();
框架。设置尺寸(600600);
关键动作(t);
帧。添加(字段);
帧。添加(t);
维度dim=java.awt.Toolkit.getDefaultToolkit().getScreenSize();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLocation((dim.width-frame.getWidth())/2,(dim.height-frame.getHeight())/2);
frame.getContentPane().setLayout(null);
frame.setAlwaysOnTop(真);
frame.setresizeable(false);
repaittimer.start();
frame.setVisible(true);
frame.requestFocus();
}
专用静态无效设置键动作(测试t){
int condition=当在聚焦窗口中时;
新的KeyAction(t,条件,KeyEvent.VK_UP,0,false){
私有静态最终长serialVersionUID=1L;
@凌驾
已执行的公共无效操作(操作事件e){
向上=真;
}
};
新的KeyAction(t,条件,KeyEvent.VK_UP,0,真){
私有静态最终长serialVersionUID=1L;
@凌驾
已执行的公共无效操作(操作事件e){
向上=错误;
}
};
新的KeyAction(t,条件,KeyEvent.VK_左,0,假){
私有静态最终长serialVersionUID=1L;
@凌驾
已执行的公共无效操作(操作事件e){
左=真;
}
};
新的KeyAction(t,条件,KeyEvent.VK_左,0,真){
私有静态最终长serialVersionUID=1L;
@凌驾
已执行的公共无效操作(操作事件e){
左=假;
}
};
新的KeyAction(t,条件,KeyEvent.VK_RIGHT,0,false){
私有静态最终长serialVersionUID=1L;
@凌驾
已执行的公共无效操作(操作事件e){
右=真;
}
};
新的KeyAction(t,条件,KeyEvent.VK_RIGHT,0,true){
私有静态最终长serialVersionUID=1L;
@凌驾
已执行的公共无效操作(操作事件e){
右=假;
}
};
新的按键动作(t,条件,KeyEvent.VK_向下,0,错误){
私有静态最终长serialVersionUID=1L;
@凌驾
已执行的公共无效操作(操作事件e){
向下=真;
}
};
新键动作(t,条件,KeyEvent.VK_向下,0,真){
私有静态最终长serialVersionUID=1L;
@凌驾
已执行的公共无效操作(操作事件e){
向下=假;
}
};
}
私有静态抽象类KeyAction扩展了AbstractAction{
私有静态最终长serialVersionUID=1L;
KeyAction(JComponent组件、int条件、int键代码、int修饰符、布尔onKeyRelease){
InputMap InputMap=component.getInputMap(条件);
ActionMap ActionMap=component.getActionMap();
击键击键=击键。getKeyStroke(键代码、修改器、onKeyRelease);
inputMap.put(击键,击键.toString());
actionMap.put(keyStroke.toString(),this);
}
}
@凌驾
公共组件(图形g){
超级组件(g);
如果(向上)
y-=1;
如果(向下)
y+=1;
如果(右)
x+=1;
如果(左)
x-=1;
if(x<0)
x=0;
else if(x>frame.getWidth()-30)
x=frame.getWidth()-30;
if(y<0)
y=0;
否则,如果(y>frame.getHeight()-50)
y=frame.getHeight()-50;
g、 drawRect(x,y,30,30);
}
@凌驾
已执行的公共无效操作(操作事件e){
frame.repaint();
}
}
在上面的代码中,框随箭头键移动。但是,如果选择左上角的文本框,该框将不再移动
更新:
我试图将键绑定添加到JTextFields中,正如@camickr给出的答案所示,但它似乎不起作用。也许我做错了什么
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.WindowConstants;
public class Test extends JPanel implements ActionListener {
private static final long serialVersionUID = 1L;
private static JFrame frame;
private static boolean up = false, down = false, left = false, right = false;
private static int x = 275, y = 275;
public static void main(String[] args) {
Test t = new Test();
t.setBounds(0, 0, 1200, 600);
t.setVisible(true);
JTextField field = new JTextField();
field.setBounds(20, 20, 100, 20);
Timer repaintTimer = new Timer(2, t);
frame = new JFrame();
frame.setSize(600, 600);
setUpKeyActions(t, field);
frame.add(field);
frame.add(t);
Dimension dim = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setLocation((dim.width - frame.getWidth()) / 2, (dim.height - frame.getHeight()) / 2);
frame.getContentPane().setLayout(null);
frame.setAlwaysOnTop(true);
frame.setResizable(false);
repaintTimer.start();
frame.setVisible(true);
frame.requestFocus();
}
private static void setUpKeyActions(Test t, JTextField field) {
int condition = WHEN_IN_FOCUSED_WINDOW;
new KeyAction(condition, KeyEvent.VK_UP, 0, false, t, field) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
up = true;
}
};
new KeyAction(condition, KeyEvent.VK_UP, 0, true, t, field) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
up = false;
}
};
new KeyAction(condition, KeyEvent.VK_LEFT, 0, false, t, field) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
left = true;
}
};
new KeyAction(condition, KeyEvent.VK_LEFT, 0, true, t, field) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
left = false;
}
};
new KeyAction(condition, KeyEvent.VK_RIGHT, 0, false, t, field) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
right = true;
}
};
new KeyAction(condition, KeyEvent.VK_RIGHT, 0, true, t, field) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
right = false;
}
};
new KeyAction(condition, KeyEvent.VK_DOWN, 0, false, t, field) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
down = true;
}
};
new KeyAction(condition, KeyEvent.VK_DOWN, 0, true, t, field) {
private static final long serialVersionUID = 1L;
@Override
public void actionPerformed(ActionEvent e) {
down = false;
}
};
}
private static abstract class KeyAction extends AbstractAction {
private static final long serialVersionUID = 1L;
KeyAction(int condition, int keyCode, int modifiers, boolean onKeyRelease, JComponent component, JComponent... components) {
InputMap inputMap = component.getInputMap(condition);
ActionMap actionMap = component.getActionMap();
KeyStroke keyStroke = KeyStroke.getKeyStroke(keyCode, modifiers, onKeyRelease);
inputMap.put(keyStroke, keyStroke.toString());
actionMap.put(keyStroke.toString(), this);
for(JComponent jc : components) {
inputMap = jc.getInputMap(condition);
actionMap = jc.getActionMap();
keyStroke = KeyStroke.getKeyStroke(keyCode, modifiers, onKeyRelease);
inputMap.put(keyStroke, keyStroke.toString());
actionMap.put(keyStroke.toString(), this);
}
}
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if(up)
y -= 1;
if(down)
y += 1;
if(right)
x += 1;
if(left)
x -= 1;
if(x < 0)
x = 0;
else if(x > frame.getWidth() - 30)
x = frame.getWidth() - 30;
if(y < 0)
y = 0;
else if(y > frame.getHeight() - 50)
y = frame.getHeight() - 50;
g.drawRect(x, y, 30, 30);
}
@Override
public void actionPerformed(ActionEvent e) {
frame.repaint();
}
}
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.awt.event.KeyEvent;
导入javax.swing.AbstractAction;
导入javax.swing.Act
InputMap im = (InputMap)UIManager.get("TextField.focusInputMap");
KeyStroke keyStroke = KeyStroke.getKeyStroke("RIGHT");
im.put(keyStroke, "none"); //noop
ActionMap am = (ActionMap)UIManager.get("TextField.actionMap");
am.put("caret-forward", yourRightActionHere);