schlachsahne
schlachsahne

Reputation: 85

Java Swing GUI distort animation

I want to build a simple animation of three balls going in one direction. Therefore I created a timer which edits the coordinates of the ball at every tick, but when I try to run it the balls just distort. They are moving in the right speed and direction but I want to remove the old balls when they change coordinates. I tried to add super.paint() in the paint method. It's deleting the old balls but most of the time the frame is just white.

public class Animation extends JFrame{
    private JPanel panel2;
    int maus1x = 110;
    int maus1y = 350;
    int maus2x = 55;
    int maus2y = 350;
    int maus3x = 0;
    int maus3y = 350;
    ActionListener timeListener = new TimeListener();
    Timer timer = new Timer(100,timeListener);

    public Animation() {
        this.setContentPane(this.panel2);
        this.setTitle("MausKampf");
        this.setSize(500, 500);
        this.setResizable(false);
        this.setVisible(true);
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        timer.start();
    }

    public void paint(Graphics g) {
        Graphics2D g2D = (Graphics2D) g;
        g2D.setColor(Color.black);
        g2D.drawLine(0,400,500,400);
        g2D.drawLine(0,350,225,350);
        g2D.drawLine(275,350,500,350);
        g2D.drawLine(225,350,225,0);
        g2D.drawLine(275,350,275,0);
        g2D.setPaint(Color.CYAN);
        g2D.fillOval(maus1x,maus1y,50,50);
        g2D.setPaint(Color.GREEN);
        g2D.fillOval(maus2x,maus2y,50,50);
        g2D.setPaint(Color.RED);
        g2D.fillOval(maus3x,maus3y,50,50);
    }

    public void move() {
        maus1x = maus1x + 4;
        maus2x = maus2x + 4;
        maus3x = maus3x + 4;
        if (maus1x > 325) {
            timer.stop();
        }
        repaint();
    }

    public class TimeListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
            move();
        }
    }
}

Upvotes: 0

Views: 48

Answers (1)

Abra
Abra

Reputation: 20914

A Swing application does not have to extend JFrame. However, if you want to perform custom painting, then you should write a class that extends JPanel and override its paintComponent method and the first line in the overridden method should be: super.paintComponent(g);

I made some minor changes to the code in your question.

  • First, class Animation extends JPanel and not JFrame.
  • Second, I renamed method paint to paintComponent and added the line as described above.
  • Last, I added method main so as to make it runnable.
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.WindowConstants;

public class Animation extends JPanel {
    int maus1x = 110;
    int maus1y = 350;
    int maus2x = 55;
    int maus2y = 350;
    int maus3x = 0;
    int maus3y = 350;
    ActionListener timeListener = new TimeListener();
    Timer timer = new Timer(100,timeListener);

    public Animation() {
        JFrame frame = new JFrame("MausKampf");
        frame.setContentPane(this);
        frame.setSize(500, 500);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);
        timer.start();
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2D = (Graphics2D) g;
        g2D.setColor(Color.black);
        g2D.drawLine(0,400,500,400);
        g2D.drawLine(0,350,225,350);
        g2D.drawLine(275,350,500,350);
        g2D.drawLine(225,350,225,0);
        g2D.drawLine(275,350,275,0);
        g2D.setPaint(Color.CYAN);
        g2D.fillOval(maus1x,maus1y,50,50);
        g2D.setPaint(Color.GREEN);
        g2D.fillOval(maus2x,maus2y,50,50);
        g2D.setPaint(Color.RED);
        g2D.fillOval(maus3x,maus3y,50,50);
    }

    public void move() {
        maus1x = maus1x + 4;
        maus2x = maus2x + 4;
        maus3x = maus3x + 4;
        if (maus1x > 325) {
            timer.stop();
        }
        repaint();
    }

    public class TimeListener implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
            move();
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new Animation());
    }
}

Upvotes: 1

Related Questions