- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试从 Java KeyListeners 转移到 KeyBindings 来进行动画处理,但它们会工作几秒钟,然后完全停止。当 Action 触发时,我将消息打印到控制台,并且这些消息停止,因此不仅仅是绘画不起作用,而是按下按键时触发了 Action 。
我的类扩展了 JFrame,我只是向它添加了一个 JPanel,并向 JPanel 添加了一个 JLabel。我使用由操作切换的标志来指示 JLabel 应如何移动,并使用 JFrame 的 actionPerformed
方法来检查标志的状态并调整 JLabel 的位置。
我尝试在 getInputMap
方法中添加 JComponent.WHEN_IN_FOCUSED_WINDOW
,但没有什么区别。
代码如下:
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
public class KeyBindingTest extends JFrame implements ActionListener {
long counter = 0;
int speed = 5;
boolean isUp = false, isDown = false, isLeft = false, isRight = false;
JLabel j = new JLabel();
JPanel p = new JPanel();
Timer t;
Action upPressed = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("up on");
isUp = true;
}
};
Action upReleased = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
isUp = false;
System.out.println("up off");
}
};
Action downPressed = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("down on");
isDown = true;
}
};
Action downReleased = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("down off");
isDown = false;
}
};
Action leftPressed = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("left on");
isLeft = true;
}
};
Action leftReleased = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("left off");
isLeft = false;
}
};
Action rightPressed = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("right on");
isRight = true;
}
};
Action rightReleased = new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("right off");
isRight = false;
}
};
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
// The try/catch block prevents errors from crashing the program
try {
KeyBindingTest window = new KeyBindingTest(); // Create and setup the main game window
window.run(); // show the new window
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private void run() {
this.setBounds(640, 400, 640, 400);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p.setBounds(0, 0, this.getWidth(), this.getHeight());
p.setVisible(true);
p.setBackground(Color.blue);
p.setOpaque(true);
p.setFocusable(true);
p.setLayout(null);
j.setBounds(320, 200, 10, 10);
j.setVisible(true);
j.setBackground(Color.red);
j.setOpaque(true);
this.add(p);
p.add(j);
p.requestFocusInWindow();
setupKeyBindings();
t = new Timer(1000 / 40, this);
t.start();
}
private void setupKeyBindings() {
p.getInputMap().put(KeyStroke.getKeyStroke("W"), "moveUp");
p.getActionMap().put("moveUp", upPressed);
p.getInputMap().put(KeyStroke.getKeyStroke("released W"), "stopUp");
p.getActionMap().put("stopUp", upReleased);
p.getInputMap().put(KeyStroke.getKeyStroke("S"), "moveDown");
p.getActionMap().put("moveDown", downPressed);
p.getInputMap().put(KeyStroke.getKeyStroke("released S"), "stopDown");
p.getActionMap().put("stopDown", downReleased);
p.getInputMap().put(KeyStroke.getKeyStroke("A"), "moveLeft");
p.getActionMap().put("moveLeft", leftPressed);
p.getInputMap().put(KeyStroke.getKeyStroke("released A"), "stopLeft");
p.getActionMap().put("stopLeft", leftReleased);
p.getInputMap().put(KeyStroke.getKeyStroke("D"), "moveRight");
p.getActionMap().put("moveRight", rightPressed);
p.getInputMap().put(KeyStroke.getKeyStroke("released D"), "stopRight");
p.getActionMap().put("stopRight", rightReleased);
}
@Override
public void actionPerformed(ActionEvent e) {
counter++;
System.out.println(counter);
if (isUp) {
j.setLocation(j.getX(), j.getY() - speed);
}
if (isDown) {
j.setLocation(j.getX(), j.getY() + speed);
}
if (isLeft) {
j.setLocation(j.getX() - speed, j.getY());
}
if (isRight) {
j.setLocation(j.getX() + speed, j.getY());
}
repaint();
}
}
最佳答案
这是个人的事情,但是,如果您使用类似 KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false)
的方法,通常会遇到更少的问题KeyStroke.getKeyStroke("W")
KeyStroke.getKeyStroke("released W")
的等效项是 KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, true)
我已经反复浏览了您的示例,我尝试将 KeyStroke.getKeyStroke("W")
替换为 KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false)
及其等效项;我尝试用 Set
替换 boolean
标志,但仍然遇到同样的问题
然后我扔掉了你的代码并开始了一个新项目。首先我尝试了自定义绘画路线,效果很好。然后我尝试了基于组件的路线并且有效......😓
所以,虽然我仍然没有一个“答案”来解释为什么它不起作用,但我确实有一个例子......
因为我实际上已经测试了我的建议......
import com.sun.glass.events.KeyEvent;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public enum Input {
UP, DOWN, LEFT, RIGHT
}
public class TestPane extends JPanel {
private Set<Input> inputs = new HashSet<>();
private int delta = 4;
private JLabel label;
public TestPane() {
InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = getActionMap();
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, false), "Up.pressed");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0, true), "Up.relesed");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, false), "Down.pressed");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0, true), "Down.relesed");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, false), "Left.pressed");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0, true), "Left.relesed");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, false), "Right.pressed");
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0, true), "Right.relesed");
actionMap.put("Up.pressed", new InputAction(Input.UP, true));
actionMap.put("Up.relesed", new InputAction(Input.UP, false));
actionMap.put("Down.pressed", new InputAction(Input.DOWN, true));
actionMap.put("Down.relesed", new InputAction(Input.DOWN, false));
actionMap.put("Left.pressed", new InputAction(Input.LEFT, true));
actionMap.put("Left.relesed", new InputAction(Input.LEFT, false));
actionMap.put("Right.pressed", new InputAction(Input.RIGHT, true));
actionMap.put("Right.relesed", new InputAction(Input.RIGHT, false));
setLayout(null);
label = new JLabel();
label.setBackground(Color.RED);
label.setOpaque(true);
label.setBounds(0, 0, 10, 10);
add(label);
Timer timer = new Timer(5, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int xPos = label.getX();
int yPos = label.getY();
if (inputs.contains(Input.UP)) {
yPos -= delta;
}
if (inputs.contains(Input.DOWN)) {
yPos += delta;
}
if (inputs.contains(Input.LEFT)) {
xPos -= delta;
}
if (inputs.contains(Input.RIGHT)) {
xPos += delta;
}
if (xPos < 0) {
xPos = 0;
} else if (xPos + 10 > getWidth()) {
xPos = getWidth() - 10;
}
if (yPos < 0) {
yPos = 0;
} else if (yPos + 10 > getHeight()) {
yPos = getHeight() - 10;
}
label.setLocation(xPos, yPos);
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
// protected void paintComponent(Graphics g) {
// super.paintComponent(g);
// Graphics2D g2d = (Graphics2D) g.create();
// g2d.setColor(Color.RED);
// g2d.drawRect(xPos, yPos, 10, 10);
// g2d.dispose();
// }
public class InputAction extends AbstractAction {
private Input input;
private boolean pressed;
public InputAction(Input input, boolean pressed) {
this.input = input;
this.pressed = pressed;
}
@Override
public void actionPerformed(ActionEvent e) {
if (pressed) {
inputs.add(input);
} else {
inputs.remove(input);
}
}
}
}
}
这种“类型”的问题最近被问到很多,我认为这是某种类作业,因为我们已经看到了这种代码风格的许多变体。正如我们一再建议的那样,以这种方式使用组件是不明智的,它们并不是真正为这种事情而设计的。使用自定义绘画路线,您将获得更好(且更容易)的结果,如 Make an JLabel move with Key Bidings 中所示。
关于Java KeyBindings 在几秒钟后停止工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50598222/
用户特定的 keyBindings .dict 文件位于:~/Library/KeyBindings/ 您(作为开发人员)如何告诉 AppKit 在另一个目录(特定于应用程序)中查找特定应用程序的另一
我想创建一个 StaticResource KeyBinding,但我不知道如何取消引用它。因此,在我的 Window.Resources 中,我可能会添加以下内容:
好的,这是代码 Gui.java package mainProgram; import javax.swing.*; import java.awt.*;
我需要 issgin CTRL+F12 和 CTRL+G 此代码不起作用 但是这段代码有效 为什么不工作? 如何分配 CTRL+F12 和 CTRL+G? 最佳答案 使用代码设置绑
这段代码适合多次按下箭头键吗?现在正在工作。向右走,向左走。但是,如果我同时按下向左和向右箭头键,我希望该桨停止。我怎样才能做到这一点 ? import java.awt.*; import java
在我的表单中,当我按下键盘上的 ENTER 按钮时,应该调用 okAction() 方法(并且调用完美)。 我的问题是处于焦点状态,当我填写文本字段然后按下 ENTER 按钮时,okAction()
简短版本:如何通过与 KeyListener keyReleased() 事件类似的功能来确定 KeyBind 键何时被释放? 长版:我正在尝试制作一个非常简单的游戏,并且我使用了几个 KeyList
我不太确定如何用这个问题的标题来表达。基本上,我正在使用 JFrames 制作太空入侵者,并使用 KeyBindings 进行键盘输入。键绑定(bind)工作正常,我可以毫无问题地移动飞船。但是,如果
Python-keybinder 用于在我的程序中设置全局热键。 GtkToggleButton 小部件用于从用户检索键绑定(bind)(按键事件/按键释放事件)。 用户按下切换按钮并按下一些键(左
我正在尝试从 Java KeyListeners 转移到 KeyBindings 来进行动画处理,但它们会工作几秒钟,然后完全停止。当 Action 触发时,我将消息打印到控制台,并且这些消息停止,因
我正在努力创建一种识别组合键的方法。在我设置任何 boolean 值之前,我注意到某些组合键会导致忽略其他键。 package question; import java.awt.BorderLayo
无论出于何种原因,一旦我的 WPF 应用程序加载,我的 UserControl 的 KeyBindings 就无法工作。在我按下表单上的按钮后,它们会起作用,但当我通过单击或 alt 选项卡或移动或类
我想将键绑定(bind)添加到我的 JFileChooser以便在按下 SPACE 键时打开文件预览窗口。 由于源代码太大,我只是做了一个简单的脏代码: MainWindow.java package
我有一个 Jpanel (p)、一个 Jframe (f) 和这个标签 (cursorlbl),我想通过箭头键四处移动。我已经在 goLeft() 方法中做了我认为合理的事情......但它不起作用。
在我的程序中,由使用 KeyBindings 的监听器操作的 JPanel 组件(在阅读有关聚焦问题后已经从 KeyListeners 更改)被添加到 JFrame 中。这个应用程序的任务是简单地使用
我正在尝试制作一个简单的游戏,我需要我的宇宙飞船在其中心旋转(使用 A 和 D 键),并相对于它所面对的方向移动(W 和 S 键)。 我已经基本弄清楚了移动和旋转的数学原理,但我对关键听众有疑问。 当
因此,如果我在 Tmux 中并且有一堆输出到达终端,我可以按以下键滚动浏览它: ctrl-b [ 现在,我必须举起双手并使用箭头键向上滚动。 如何在滚动模式下映射 vim 键? 最佳答案 2020年更
我读到使用 KeyBindings 比使用 KeyListeners 更好。我看到了 KeyBindings 如何对特定键的特定 react 有用;但我也在尝试检测键盘上任何键的按下/释放:有没有办法
我对 Swing 的使用并不陌生,但我用它做了很多工作,并且我正在设计一个新的应用程序。这是一个绘图应用程序。它将允许用户单击空白的白色“查看器”窗口中的某些位置,使用键盘键入字母和符号,从而编辑查看
我有一个程序,我想使用键绑定(bind): // Imports.. public class Test{ JButton button = new JButton(); Test(){ //...
我是一名优秀的程序员,十分优秀!