使图形在关键事件上移动

lvl*_*lvl 0 java graphics swing timer keylistener

当按下"i,j,k,l"键(如箭头键)时,我试图制作一个能够移动的圆,并在释放时停止.尝试创建一个Timer,以便在再次移动之前等待一秒,这样动画就可以了,但是因为我创建了'while(!quit)'循环,所以没有图形移动或显示.你能指出我的错误吗?

码:

import java.awt.*;
import java.awt.Color.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.Timer;
import java.util.TimerTask;


public class Event_test{
    public static void main(String args[])
    {
        boolean quit = false;

        JFrame Window = new JFrame("Event_test");
        MyCanvas WCanvas = new MyCanvas();
        KeyCatcher k = new KeyCatcher();

        WCanvas.addKeyListener(k);


        Window.getContentPane().add(WCanvas);
        Window.setSize(640, 360);
        Window.setVisible(true);
        Window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        new Notification(1);

        while(!quit)
        {
            WCanvas.update(WCanvas.getGraphics());

            if(!Notification.flag)
            {
                continue;
            }
            else
            {
                Notification.flag = false;
                System.out.println("tic");
                /*
                CONTROLS:
                */

                if(KeyCatcher.KEYS[0])
                {
                    MyCanvas.x--;
                }
                if(KeyCatcher.KEYS[1])
                {
                    MyCanvas.y++;
                }
                if(KeyCatcher.KEYS[2])
                {
                    MyCanvas.x++;
                }
                if(KeyCatcher.KEYS[3])
                {
                    MyCanvas.y--;
                }
                if(KeyCatcher.KEYS[4])
                {
                    quit = true;
                }

                new Notification(1);
            }


        }
    }
}

class MyCanvas extends Canvas
{
    static int x, y;

    public void paint(Graphics g)
    {
        g = this.getGraphics();
        MyClass.drawSomething(g, x, y);
    }
}

class MyClass
{

    public static void drawSomething(Graphics g, int x, int y)
    {
        g.setColor(Color.RED);
        g.drawOval(x, y, 10, 10);
    }
}

class KeyCatcher implements KeyListener
{

    static boolean KEYS[] = new boolean[5];


    public void keyPressed(KeyEvent e)
    {
        if(e.getKeyChar() == 'j'/*IZQ*/)
        {
            KEYS[0] = true;
        }

        if(e.getKeyChar() == 'i'/*ARR*/)
        {
            KEYS[1] = true;
        }

        if(e.getKeyChar() == 'l'/*DER*/)
        {
            KEYS[2] = true;
        }

        if(e.getKeyChar() == 'k'/*ABA*/)
        {
            KEYS[3] = true;
        }

        if(e.getKeyChar() == 'q'/*QUIT*/)
        {
            KEYS[4] = true;
        }
    }

    public void keyReleased(KeyEvent e)
    {
        if(e.getKeyChar() == 'j'/*IZQ*/)
        {
            KEYS[0] = false;
        }

        if(e.getKeyChar() == 'i'/*ARR*/)
        {
            KEYS[1] = false;
        }

        if(e.getKeyChar() == 'l'/*DER*/)
        {
            KEYS[2] = false;
        }

        if(e.getKeyChar() == 'k'/*ABA*/)
        {
            KEYS[3] = false;
        }

        if(e.getKeyChar() == 'q'/*QUIT*/)
        {
            KEYS[4] = false;
        }
    }

    public void keyTyped(KeyEvent e){

    }
}

class Notification{
    static boolean flag = false;
    Timer timer;

    Notification(int seconds)
    {
        timer = new Timer();
        timer.schedule(new Task(), seconds*1000);
    }

    class Task extends TimerTask
    {
        public void run()
        {
            //What task does:
            flag = true;
            timer.cancel();
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

cam*_*ckr 5

你的问题是关于Swing(不是AWT)所以:

  1. 不要扩展Canvas.而是通过扩展JPanel来完成自定义绘制
  2. 不要覆盖油漆(...).自定义绘画是通过覆盖paintComponent(...)来完成的
  3. 不要使用TimerTask.而是使用Swing Timer.
  4. 不要使用getGraphics()方法.见第2点.
  5. 不要调用update(...).您只需在组件上调用repaint(),它就会绘制为iself.
  6. 不要使用while循环.这就是使用Swing Timer的原因.
  7. 不要使用大写字符启动变量名称.遵循Java命名约定.
  8. 不要使用KeyListener.Swing旨在与Key Bindings一起使用.

查看自定义绘画的Swing教程,了解基本的绘画示例,以帮助您入门.

使用键盘查看动作.该Keyboard Animation示例解决了许多这些问题.