Java中的密钥侦听器/密钥绑定
我如何对一个事件进行编码,该事件在按下某个键(特别是空格键)时开始,在按住该键时继续运行,并且仅在释放该键时停止?我试图模拟一个在粗糙表面上移动的轮式物体。我尝试过使用原始的KeyListener方法,但问题是,当我按住空格键时,我正在模拟的对象会反复停止和启动。我听说一个可能的解决方案是键绑定,但即使在阅读了Java教程之后,我仍然不理解它们 以下是用于模拟的绘制方法(由每10毫秒休眠一次的线程控制): 下面是用于更改x_pos的方法(未声明的变量假定已在类主体中声明):Java中的密钥侦听器/密钥绑定,java,swing,paint,keylistener,key-bindings,Java,Swing,Paint,Keylistener,Key Bindings,我如何对一个事件进行编码,该事件在按下某个键(特别是空格键)时开始,在按住该键时继续运行,并且仅在释放该键时停止?我试图模拟一个在粗糙表面上移动的轮式物体。我尝试过使用原始的KeyListener方法,但问题是,当我按住空格键时,我正在模拟的对象会反复停止和启动。我听说一个可能的解决方案是键绑定,但即使在阅读了Java教程之后,我仍然不理解它们 以下是用于模拟的绘制方法(由每10毫秒休眠一次的线程控制): 下面是用于更改x_pos的方法(未声明的变量假定已在类主体中声明): }最好也是最常见的方
}最好也是最常见的方法之一是为每个映射键设置一个标志。按下(由KeyEvent检测)时,该标志设置为true。释放时(也被KeyEvent检测到),该标志设置为false 应用程序状态(由另一个线程定期检查)不是由键状态或事件决定的,而是由标志状态决定的
这种简单的方法避免了键重复设置所造成的影响。最好也是最常见的方法之一是为每个映射键设置一个标志。按下(由KeyEvent检测)时,该标志设置为true。释放时(也被KeyEvent检测到),该标志设置为false 应用程序状态(由另一个线程定期检查)不是由键状态或事件决定的,而是由标志状态决定的
这种简单的方法避免了按键重复设置所带来的影响。我会首先提出,有时候一个
按键监听器是件好事,但我不认为这是其中之一
基本上,这演示了如何使用键绑定来监视键的状态更改(在空格键中)
我会第一个提出这样的观点:有时候,keylister
是件好事,但我不认为这是其中之一
基本上,这演示了如何使用键绑定来监视键的状态更改(在空格键中)
要做到这一点,可以有多种方法。我过去处理这个问题的方式是一个监控系统,所以我会检查钥匙是否在任何给定的时间关闭。当动画/效果是时间的函数时效果非常好。可以有多种方法来实现这一点。我过去处理这个问题的方式是一个监控系统,所以我会检查钥匙是否在任何给定的时间关闭。当动画/效果是时间的函数时,效果非常好。
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Shape roadsurface = new Rectangle2D.Float(0, 85, 1000, 200);
g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(10));
g2.draw(roadsurface);
g2.setColor(new Color(102, 102, 153));
g2.fill(roadsurface);
Image carimage = Toolkit.getDefaultToolkit().getImage("cargrey.png");
g2.drawImage(carimage, x_pos, y_pos, 60, 30, this);
g2.finalize();
}
public void accelerate()
{
do
{ acc = 15.0 - t;
vel = ( t * 15.0) - ( 0.5 * Math.pow(t, 2.0) );
disp = ( 0.5 * 15.0 * Math.pow(t, 2.0) ) - ( (1.0/6.0) * Math.pow(t, 3.0) );
x_pos = (int)disp;
t += 0.01; break;} while (acc > 0);
while (acc <= 0)
{ acc = 0;
disp = t * vel;
x_pos = (int)disp;
t += 0.01;
}
}
public void brake(double vel, double disp)
{
double u = 0;
double disp2;
while (vel > 0)
{
disp2 = (vel * u) + (0.5 * -100 * Math.pow(u, 2.0) );
vel = vel + (-100 * u);
x_pos = (int)(disp + disp2);
u += 0.01;
t += 0.01; break;}
while (vel <= 0)
{
u += 0.01;
t += 0.01;
}
}
class Key1 extends Thread implements KeyListener
{
Track g;
boolean keyIsPressed;
Key1(Track g)
{
this.g = g;
}
public void keyTyped(KeyEvent ke) {}
public void keyPressed(KeyEvent ke)
{
if (ke.getKeyCode() == KeyEvent.VK_SPACE)
keyIsPressed = true;
}
public void keyReleased(KeyEvent ke)
{
if (ke.getKeyCode() == KeyEvent.VK_SPACE)
keyIsPressed = false;
}
public void run()
{
while (keyIsPressed)
{
g.repaint();
g.accelerate();
try
{
Thread.sleep(10);
}
catch (InterruptedException ex)
{
// swallowed
}
while (!keyIsPressed)
{
g.repaint();
g.brake(g.vel, g.disp);
try
{
Thread.sleep(10);
}
catch (InterruptedException ex)
{
// swallowed
}
}
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
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.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class KeyBindingTest {
public static void main(String[] args) {
new KeyBindingTest();
}
public KeyBindingTest() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private boolean spaceIsDown = false;
public TestPane() {
// Avoid all the issues with focusable and single
// focused components
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, false), "space.pressed");
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true), "space.released");
am.put("space.pressed", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
spaceIsDown = true;
repaint();
}
});
am.put("space.released", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
spaceIsDown = false;
repaint();
}
});
}
public boolean isSpaceIsDown() {
return spaceIsDown;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
String text = isSpaceIsDown() ? "Space is DOWN" : "Space is UP";
FontMetrics fm = g2d.getFontMetrics();
g2d.drawString(text, (getWidth() - fm.stringWidth(text)) / 2, (((getHeight() - fm.getHeight())) / 2) + fm.getAscent());
g2d.dispose();
}
}
}