遇到keyListener问题

时间:2013-08-26 11:04:05

标签: java swing keylistener thread-sleep focusable

我正在尝试在java中进行简单的反应测试。 当屏幕变为绿色时我按空格键应该改变te boolean“点击进入false并停止测量时间的循环。 实际上,关键列表器什么都不做。 我是否将keay听众添加到正确的组合(jpanel面板)? 还有其他问题吗?

    import java.awt.Color;
    import java.awt.RenderingHints.Key;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;        
    import javax.swing.*;

    public class mainCheck {
    // //////////////////////////////////////
    public static void timeKeeper() {
         boolean clicked=false;
        long time = 10000;
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        panel.setBackground(Color.GREEN);
        while (time > 0 && !clicked) {
            try {
                Thread.sleep(1);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            time--;
        }
        panel.setBackground(Color.gray);
        long time2= 10000-time;
        JLabel x = new JLabel("" +time2+"");
        panel.add(x);    
    }

    // //////////////////////////////////////
    static boolean clicked;
    JFrame frame;
    static JPanel panel;

    public mainCheck() {
        frame = new JFrame();
        panel = new JPanel();
        clicked = false;
        Handler handler = new Handler();
        frame.addKeyListener(handler);
        frame.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500,500);
        frame.setVisible(true);
    }
    // //////////////////////////////////////

    public static void main(String[] args) {
        mainCheck f = new mainCheck();
        panel.getActionMap();           
        f.timeKeeper();
    }

    // //////////////////////////////////////
    public class Handler implements KeyListener {

        @Override
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
        }

        @Override
        public void keyReleased(KeyEvent e) {
            // TODO Auto-generated method stub    
        }

        @Override
        public void keyTyped(KeyEvent e) {
            // TODO Auto-generated method stub
            if (e.getKeyCode() == KeyEvent.VK_SPACE) {
                clicked = false;
                System.out.println("space pressed");
            }    
        }    
    }
}

3 个答案:

答案 0 :(得分:3)

  • 不要使用Thread.sleep(5000);Event Dispatch Thread,在睡眠期间,您可以将所有事件丢失到已经可见的Swing GUI

  • 使用Swing Timer代替

  • Thread.sleep(1);可能适当延迟空间环境,非人类,非常短时间内攻击Native OS中的延迟(8-14毫秒,取决于原生OS)

  • AWT / Swing中的
  • JLabel x = new JLabel("" +time2+"");panel.add(x);并非任何通知JComponents的某些部分被删除或添加,必须通知已使用的{{1}通过使用方法LayoutManagerJPanel,(FlowLayou在API中有revalidate t},例如

repaint
  • 应在Initial Thread

  • 上创建Swing GUI
  • 请勿使用KeyListener使用KeyBindings,否则您(焦点猎手)需要设置JLabel x = new JLabel("" +time2+""); panel.add(x); panel.revalidate(); panel.repaint();

答案 1 :(得分:0)

  • 问题是你“ e.getKeyCode()”总是“ 0 ”所以 更改“ e.getKeyChar()”和“(char)32
  • 另一个问题在于您将 clicked = false 放在必须 “的
  • 你遇到的最后一个问题是“ timeKeeper()”你必须删除“布尔”,因为它已经被声明了

    Bad
    public static void timeKeeper() {
    boolean clicked=false
    ....}
    
    Good
    public static void timeKeeper() {
    clicked=false
    ....}
    

这是正确的代码:

import java.awt.Color;
import java.awt.event.*;        
import javax.swing.*;

public class mainCheck {
// //////////////////////////////////////
public static void timeKeeper() {
    clicked=false;
    long time = 10000;
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }
    panel.setBackground(Color.GREEN);
    while (time > 0 && !clicked) {
        try {
            Thread.sleep(1);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        time--;
    }
    panel.setBackground(Color.gray);
    long time2= 10000-time;
    JLabel x = new JLabel("" +time2+"");
    panel.add(x);    
}

// //////////////////////////////////////
static boolean clicked;
JFrame frame;
static JPanel panel;
Handler handler = new Handler();

public mainCheck() {
    frame = new JFrame();
    panel = new JPanel();
    clicked = false;

    frame.addKeyListener(handler);
    frame.add(panel);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(500,500);
    frame.setVisible(true);
}
// //////////////////////////////////////

public static void main(String[] args) {
    mainCheck f = new mainCheck();
    panel.getActionMap();           
    f.timeKeeper();
}

// //////////////////////////////////////
public class Handler implements KeyListener {

    @Override
    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub
    }

    @Override
    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub    
    }

    @Override
    public void keyTyped(KeyEvent e) {
        if (e.getKeyChar() == (char)32) {
            clicked = true;
            System.out.println("space pressed");
        }    
    }  
}
}

答案 2 :(得分:-1)

使用Thread.sleep()减少时间值是一个非常糟糕的主意。 改为使用Timer对象:

public void myTimer(){
    Timer myTimer = new Timer(delay, new ActionListener(){
        public void actionPerformed(ActionEvent e){
            //Stuff to do
        }
    });
}

其中delay是您延迟计时器的时间。使用myTimer.start();

启动计时器