【问题标题】:having problems with keyListenerkeyListener 有问题
【发布时间】:2013-08-26 11:04:04
【问题描述】:

我正在尝试用 java 做一个简单的反应测试。 当屏幕变绿时,我按空格女巫应该改变布尔值“点击为假并停止测量时间的循环。 实际上,关键侦听器什么都不做。 我是否将关键侦听器添加到正确的组件(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");
            }    
        }    
    }
}

【问题讨论】:

    标签: java swing keylistener thread-sleep focusable


    【解决方案1】:
    • 不要使用 Thread.sleep(5000); 阻止 Event Dispatch Thread 并且在睡眠期间您可能会将所有事件丢失到已经可见的 Swing GUI 中

    • 改用Swing Timer

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

    • AWT/Swing 中的JLabel x = new JLabel("" +time2+""); 和panel.add(x); 不是任何通知器,即JComponents 的某些、任何部分被删除或添加,必须通知使用的LayoutManager(JPanel 有@ API 中的 987654333@t)通过使用方法 revalidate 和 repaint,例如

    .

    JLabel x = new JLabel("" +time2+"");
    panel.add(x);
    panel.revalidate();
    panel.repaint();
    

    【讨论】:

      【解决方案2】:
      • 问题是你的“e.getKeyCode()”总是“0”所以 更改为“e.getKeyChar()”和“(char)32”
      • 另一个问题是你把 clicked = false 并且必须是 “真”
      • 您遇到的最后一个问题是在“timeKeeper()”中,您必须删除“boolean”,因为它已经被声明了

        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");
              }    
          }  
      }
      }
      

      【讨论】:

        【解决方案3】:

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

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

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

        【讨论】:

        • -1 使用计时器的建议是在 30 分钟前给出的。无需用重复的建议使论坛混乱。
        猜你喜欢
        • 2016-07-05
        • 1970-01-01
        • 1970-01-01
        • 2012-11-29
        • 2014-06-04
        • 1970-01-01
        • 2011-09-24
        • 1970-01-01
        相关资源
        最近更新 更多