正如大多数人现在用密钥监听器实现的那样,在keyPressed方法中,java注册一次按键,然后暂停大约半秒钟,然后按下密钥记录稳定的流。 我的问题是,我希望java在按下一个键后立即注册一个稳定的流keyDown事件。 我已经阅读过很多关于这个问题的文章,其中很多都谈到了摇摆计时器,其中我也处于黑暗中。 为了使下面的代码更好更容易看,我只是修剪掉了胖子并把关键的监听器放到了一个单独的类中! 对此的任何意见将不胜感激!
public class Keyer implements KeyListener
{
Keyer(){}
@Override
public void keyPressed(KeyEvent ovent)
{
int keyCode = ovent.getKeyCode();
System.out.println("You pressed: "+keyCode);
}
@Override
public void keyReleased(KeyEvent ovent)
{
}
@Override
public void keyTyped(KeyEvent ovent)
{
}
}
答案 0 :(得分:6)
我认为这不是Java问题,而是操作系统问题 - 操作系统在发送一键击键之前在一段时间内发送键击延迟。解决方案是在按键时启动Swing Timer。我还建议您使用Key Bindings而不是KeyListener。
另外你说你在摇摆计时器“黑暗中”,如果是这样,我敦促你做我们其他人在这种情况下所做的事情:查看相关教程。 Google会帮助您快速找到它。此外,搜索此站点将帮助您查找使用Swing Timer进行键绑定的示例,例如,看看here。
修改强>
KeyListener是一个低级构造,通常您更喜欢使用更高级别的构造,因为它们更安全,更容易使用而不会产生副作用或出现问题。例如,如果使用KeyListener,则很容易遇到焦点问题,因为只有在侦听的组件具有焦点时它才有效。如果您使用键绑定,则很容易避免这种情况。
答案 1 :(得分:6)
如果按下的按键是更新GUI的触发器,那就是当你需要使用SwingTimers时。如果它没有触发对GUI的更新,则可以使用普通线程。
我认为文章所指的是
KeyListener
以下是您如何将其纳入KeyListener
:
public class Keyer implements KeyListener{
/** Stores currently pressed keys */
HashSet<Integer> pressedKeys = new HashSet<Integer>();
public Keyer(){
//Check every 100ms if there's keys pressed
//(This is the Swing Timer they talk about)
new Timer(100, new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
String keysString = "";
if(!pressedKeys.isEmpty()){
Iterator<Integer> i = pressedKeys.iterator();
while(i.hasNext()){
keysString += i.next() + ",";
}
}
System.out.println(keysString);
}
}).start();
}
@Override
public void keyPressed(KeyEvent ovent){
//Add key to hashSet when pressed
int keyCode = ovent.getKeyCode();
pressedKeys.add(keyCode);
}
@Override
public void keyReleased(KeyEvent ovent){
//Remove key from hashset when released
int keyCode = ovent.getKeyCode();
pressedKeys.remove(keyCode);
}
@Override
public void keyTyped(KeyEvent ovent){}
}
这是一个将所有内容放在一起的示例 - 更新标签,告诉您确切按下了哪些键(按键码)。
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
public class TempProject extends JPanel{
/** Label to update with currently pressed keys */
JLabel output = new JLabel();
public TempProject(){
super();
setFocusable(true);
add(output, BorderLayout.CENTER);
requestFocus();
addKeyListener(new Keyer());
}
public static void main(String args[])
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setContentPane(new TempProject());
frame.pack();
frame.setVisible(true);
new TempProject();
}
});
}
public class Keyer implements KeyListener{
/** Stores currently pressed keys */
HashSet<Integer> pressedKeys = new HashSet<Integer>();
public Keyer(){
//Check every 100ms if there's keys pressed
//(This is the Swing Timer they talk about)
new Timer(100, new ActionListener(){
@Override
public void actionPerformed(ActionEvent arg0) {
String keysString = "";
if(!pressedKeys.isEmpty()){
Iterator<Integer> i = pressedKeys.iterator();
while(i.hasNext()){
keysString += i.next() + ",";
}
}
output.setText(keysString);
}
}).start();
}
@Override
public void keyPressed(KeyEvent ovent){
//Add key to hashSet when pressed
int keyCode = ovent.getKeyCode();
pressedKeys.add(keyCode);
}
@Override
public void keyReleased(KeyEvent ovent){
//Remove key from hashset when released
int keyCode = ovent.getKeyCode();
pressedKeys.remove(keyCode);
}
@Override
public void keyTyped(KeyEvent ovent){}
}
}
修改强>
另外,请参阅@HovercraftFullOfEels发布的关于KeyListener
的警告。根据您要完成的任务,您可能需要考虑使用Key Bindings(与此帖适用的原理相同)。如果你想看一下,这里有一个关于键绑定的有用的tutorial。