如何制作动画圈?

时间:2014-03-12 23:32:34

标签: java swing animation user-interface paintcomponent

我还在学习GUI,但仍然遇到一些麻烦:/

我正在制作这个GUI,其中有2个圆圈,一个大(100x100)和一个小(50x50)。小的一个将进入大圆的边缘,在0.5秒内,小圆圈将转到中心,当用户必须点击时。每当用户点击圆圈位于中间时,用户就会得分。我遇到的唯一麻烦是圆圈没有移动,因为我怀疑它与我的线程有关,因此我使用线程的原因是为了了解如何使用它们。

GUI

public class gui extends JPanel implements MouseListener,
    Runnable {
Thread t = new Thread();


int score = 0;
int rnd;
static final int smallcircleposx = 75;
static final int smallcircleposy = 75;
int circleposx = 75;
int circleposy = 75;
int mousex, mousey;
Random random = new Random();

public gui() {

}

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.setColor(Color.BLUE);
    g.fillOval(50, 50, 100, 100);
    g.setColor(Color.RED);
    g.fillOval(circleposx, circleposy, 50, 50);

}

// THREAD FOR MOVING THE CIRCLE
public void run() {
    rnd = random.nextInt(999);

    if (rnd % 5 == 0) {
        circleposx = circleposx + 25;
    } else if (rnd % 4 == 0) {
        circleposx = circleposx - 25;
    } else if (rnd % 3 == 0) {
        circleposy = circleposy + 25;
    } else {
        circleposy = circleposy - 25;
    }

    try {
        Thread.sleep(500);
        circleposx = smallcircleposx;
        circleposy = smallcircleposy;
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

public void mouseClicked(MouseEvent m) {

    if (circleposx == smallcircleposx && circleposy == smallcircleposy) {
        score++;
    }
}

MAIN

public class main {

public static void main(String[] args) {
    JFrame frame = new JFrame("Circle enlarger");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400,400);
    frame.setVisible(true);

    gui co = new gui();
    frame.add(co);
    frame.addMouseListener(co);
    Thread x = new Thread(new gui());
    x.start();


}

}

我知道我还没有使用所有mouselistener方法。

1 个答案:

答案 0 :(得分:1)

要记住一些要点:

  1. 如果您没有覆盖所有方法,请使用MouseAdaptor代替MouseListener

  2. 请勿直接在顶级容器上绘图,例如JFrameJApplet,而不是使用JPanel

  3. 请勿使用Thread.sleep()来暂停整个swing应用程序,而是尝试使用最适合swing应用程序的Swing Timer

    了解更多How to Use Swing Timers

  4. 不要忘记在重写super.paintComponent()方法中致电paintComponent()

  5. 在添加所有组件后,最后调用frame.setVisible(true)

  6. 根据组件的首选尺寸,使用符合组件的frame.pack()代替frame.setSize()

  7. 在自定义绘画的情况下,覆盖getPreferredSize()以设置JPanel的首选大小。

  8. 使用SwingUtilities.invokeLater()EventQueue.invokeLater()确保EDT已正确初始化。

    了解更多

  9. 值得一读Lesson: Performing Custom Painting


    示例代码:根据自定义绘画更改

    private Timer timer;
    ...
    // 500 Milli-seconds 
    timer = new javax.swing.Timer(500, new ActionListener() {
    
        @Override
        public void actionPerformed(ActionEvent arg0) {
            // change the coordinate
            panel.repaint();
    
            if (condition) {
                timer.stop(); // you can stop the timer anytime
            }
        }
    });
    timer.setRepeats(true); // you can turn-off the repeatation
    timer.start();
    
    public static void main(String args[]) {
        SwingUtilities.invokeLater(new Runnable() {
    
            @Override
            public void run() {
                // Initialize the UI
            }
        });
    }
    
    class MyJPanel extends JPanel {
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            ...
        }
    
        @Override
        public Dimension getPreferredSize() {
            return new Dimension(..., ...);
        }
    }