我知道我之前发过关于这个主题的问题,但我在这里发布了一个新问题,因为我创建了我需要的MCVE。这是可以重现问题的类(如果您将此代码复制并粘贴到Java编辑器中(但更改包名称),那么它将能够成功启动而不会出现问题。这是一个完整的测试程序):
package com.blockhead7360.test.ppa;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
public class TotalKeyTest {
static JTextArea area;
static int i = 0;
public TotalKeyTest(){
JFrame frame = new JFrame("Test");
frame.setPreferredSize(new Dimension(600, 600));
frame.setMaximumSize(new Dimension(600, 600));
frame.setMinimumSize(new Dimension(600, 600));
JComponent comp = (JComponent) frame.getContentPane();
frame.getRootPane().getRootPane().setActionMap(bindKeys(comp).getActionMap());
frame.getRootPane().getRootPane().setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, bindKeys(comp).getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static JComponent bindKeys(JComponent comp){
comp.getInputMap().put(KeyStroke.getKeyStroke("pressed SPACE"), "pressSpace");
comp.getActionMap().put("pressSpace", new AbstractAction(){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e){
System.out.println("pressed Space");
}
});
comp.getInputMap().put(KeyStroke.getKeyStroke("pressed A"), "pressLeft");
comp.getActionMap().put("pressLeft", new AbstractAction(){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e){
System.out.println("pressed left");
}
});
comp.getInputMap().put(KeyStroke.getKeyStroke("released A"), "releaseLeft");
comp.getActionMap().put("releaseLeft", new AbstractAction(){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e){
System.out.println("released left");
}
});
comp.getInputMap().put(KeyStroke.getKeyStroke("D"), "pressRight");
comp.getActionMap().put("pressRight", new AbstractAction(){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e){
System.out.println("pressed right");
}
});
comp.getInputMap().put(KeyStroke.getKeyStroke("released D"), "releaseRight");
comp.getActionMap().put("releaseRight", new AbstractAction(){
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e){
System.out.println("released right");
}
});
return comp;
}
public static void main(String args[]){
new TotalKeyTest();
}
}
如果您希望将其作为pastebin,那么它是:http://pastebin.com/EhPJeAPC
基本上,当我在开始时按下SPACE,A和D键几次(短按和长按)时,它会起作用。经过短暂和长时间的压力后,它就停止工作了!
有人可以帮忙吗?
编辑:BTW我知道代码包含了frame.getRootPane(),而不仅仅是使用frame.add(),但这就是因为我正在尝试一些东西。如果你愿意,我可以改回来。编辑:我发现如果我使用箭头键而不是A和D键,它的工作完全正常。我不知道为什么,但我会用它滚动。
答案 0 :(得分:1)
您正在为contentPane获取错误的输入映射。您应该使用默认getInputMap()
使用默认JComponent.WHEN_FOCUSED
地图,当您应该使用更具体的getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
例如,我的MCVE:
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class TotalKeyTest2 extends JPanel {
private static final int PREF_W = 600;
private static final int PREF_H = PREF_W;
private int condition = WHEN_IN_FOCUSED_WINDOW;
private InputMap inputMap = getInputMap(condition);
private ActionMap actionMap = getActionMap();
public TotalKeyTest2() {
setBindings();
}
private void setBindings() {
insertKey(KeyEvent.VK_SPACE, "Space");
insertKey(KeyEvent.VK_A, "Left");
insertKey(KeyEvent.VK_D, "Right");
}
private void insertKey(int keyCode, String text) {
KeyStroke pressed = KeyStroke.getKeyStroke(keyCode, 0, false);
KeyStroke released = KeyStroke.getKeyStroke(keyCode, 0, true);
String pressedActionName = text + " Pressed";
String releasedActionName = text + " Released";
Action pressedAction = new MyAction(pressedActionName);
Action releasedAction = new MyAction(releasedActionName);
inputMap.put(pressed, pressedActionName);
inputMap.put(released, releasedActionName);
actionMap.put(pressedActionName, pressedAction);
actionMap.put(releasedActionName, releasedAction);
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private class MyAction extends AbstractAction {
public MyAction(String name) {
super(name);
}
@Override
public void actionPerformed(ActionEvent e) {
System.out.println(getValue(NAME));
}
}
private static void createAndShowGui() {
TotalKeyTest2 mainPanel = new TotalKeyTest2();
JFrame frame = new JFrame("TotalKeyTest2");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}