user3323950
user3323950

Reputation: 207

How to make an animated circle?

Im still learning GUI, still having some trouble getting my head around threads :/

Im making this GUI in which there are 2 circles, one big (100x100) and one small (50x50). The small one will go to the edge of the big circle and during 0.5seconds, the small circle will go to the center and that it when the user has to click. Whenever the user clicks when the circle is in the middle then the user scores. The only trouble im having is that the circle is not moving about as I suspect its something got to do with my threads, hence the reason why i m using threads, to get to know how to use them.

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();


}

}

I am aware that I haven't used all the mouselistener methods.

Upvotes: 1

Views: 1148

Answers (1)

Braj
Braj

Reputation: 46841

Some points to remember:

  1. Use MouseAdaptor instead of MouseListener if you are not overriding all the methods.

  2. Don't paint directly over top level container such as JFrame, JApplet instead use JPanel

  3. Don't use Thread.sleep() that sometime hangs the whole swing application instead try with Swing Timer that is most suitable for swing application.

    Read more How to Use Swing Timers

  4. Don't forget to call super.paintComponent() in overridden paintComponent() method.

  5. Call frame.setVisible(true) in the end after adding all the components.

  6. Use frame.pack() instead of frame.setSize() that fits the components as per component's preferred size.

  7. Override getPreferredSize() to set the preferred size of the JPanel in case of custom painting.

  8. Use SwingUtilities.invokeLater() or EventQueue.invokeLater() to make sure that EDT is initialized properly.

    Read more

It's worth reading Lesson: Performing Custom Painting


Sample code: (change it as per your 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(..., ...);
    }
}

Upvotes: 1

Related Questions