下面是我用来测试的小程序,很简单,字母'A'通过Timer不断向上移动,当按“↑”的时候,改变Timer中的延时(原为1500ms)
按“↑”时先令Timer停止,然后改变延时(t.setDelay(t.getDelay() / 3);),再启动Timer
问题来了,这时字母'A'应该是停顿t.getDelay() / 3的延时再向上移动,但为什么每次按“↑”时,停顿的时间都是原来的延时1500ms?若要达到我想要的效果,并且不在KeyListener中new一个Timer,应如何改动?class Panel_13 extends JPanel
{
    public Panel_13()
    {
        final Timer t = new Timer(1500, new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                if(y > 10)
                    y -=10;
                repaint();
            }
        });
        t.start();        addKeyListener(new KeyAdapter()
        {
            public void keyPressed(KeyEvent event)
            {
                t.stop();
                if(event.getKeyCode() == KeyEvent.VK_UP && y > 10)
                {
                    t.setDelay(t.getDelay() / 3);
                    y -= 10;
                }
                repaint();
                t.start();
            }
        });
    }    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.setFont(new Font("TimesRoman", Font.PLAIN, 24));
        g.drawString("A", 45, y);
    }    private int y = 360;
}

解决方案 »

  1.   

    楼主,不是setDelay()方法的问题,你的键盘事件根本没触发,也不知道在keyPressed()方法里面先打印一条语句看按上箭头触发事件没有啊,这是基本的排错步骤啊。楼主在main方法最后加上:Panel_13.requestFocus()就行了,一定要加在JFrame.setVisible()之后,JPanel是无法通过鼠标、键盘获取焦点的,除非setFocusable()为true。所以,解决办法两个,要么加requestFocus(),要么setFocusable()为true。
      

  2.   

    键盘事件已经触发,每次按“↑”字母‘A‘都会向上移动
    setFocusable()为true在创建Panel_13这个类时已经有了
    问题是Timer那个延时
      

  3.   

    反正我把楼主的代码拷过去用是没问题的,按上箭头键A会停止移动一下,然后上移的速度会变快,如果我多按几下,A重新上移的时候跑得飞快,明显setDelay()方法起作用了。
      

  4.   

    final成员变量表示常量,只能被赋值一次,赋值后值不再改变
      

  5.   

    我说的是按下“↑”后,字母‘A’停顿再向上移动的那个的延时问题,当字母‘A’停顿再向上,所用的时间是1500ms,不管这时Timer的延时是多少,仍然是1500ms
    如果将KeyListener事件改成这样、addKeyListener(new KeyAdapter()
            {
                public void keyPressed(KeyEvent event)
                {
                    t.stop();
                    if(event.getKeyCode() == KeyEvent.VK_UP && y > 10)
                    {
                        y -= 10;
                        t = new Timer(t.getDelay() / 3, new ActionListener()
                        {
                            public void actionPerformed(ActionEvent e)
                            {
                                if(y > 10)
                                    y -=10;
                                repaint();
                            }
                        });
                    }
                    t.start();
                    repaint();
                }
            });
    private Timer t;
    此时,字母‘A’停顿的时间就是t.getDelay() / 3。
      

  6.   

    调用setInitialDelay()就好了,Timer调用start()之后,会停顿getInitialDelay()的时间,然后再按getDelay()时间触发事件,实例化Timer类的时候已经把initialDelay赋为delay的值,后面虽然setDelay()改变了delay的值,但是initialDelay的值是不会变化的,所以调用start()之后停顿的时间不会发生变化。