jordan shedletzky
jordan shedletzky

Reputation: 103

How do I do a simple graphics animation within a JPanel

What I am trying to do is simply roll a die and have a rolling dice animation (simply have random dice values displayed while rolling)

My code so far for the die:

import java.awt.*;

import javax.swing.*;

public class diePanel extends JPanel{

private int dieValue;
private boolean onHold=false;
private int pNum;

public diePanel(){
    super();
}

public void setPlayerNumber(int pNum){
    this.pNum=pNum;
}

public void setDieValue(int dieValue){
    this.dieValue=dieValue;
}

public int checkDieValue(){
    return dieValue;
}

public void roll(){
    dieValue=(int) ((Math.random()*6)+1);
    repaint();
}

public void changeOnHold(){
    onHold=!onHold;
}

public void unHold(){
    onHold=false;
}

public boolean checkOnHold(){
    return onHold;
}

public void paintComponent(Graphics g){
    super.paintComponent(g);
    this.setSize(50,50);
    this.setVisible(true);
    if(pNum==1){
        if(dieValue==1){
            if(onHold==false){
                g.setColor(Color.black);
            }
            else{
                g.setColor(Color.white);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.black);
            }
            else{
                g.setColor(Color.white);
            }
            g.fillOval(23,23,5,5);
        }
        else if(dieValue==2){
            if(onHold==false){
                g.setColor(Color.black);
            }
            else{
                g.setColor(Color.white);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.black);
            }
            else{
                g.setColor(Color.white);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
        }
        else if(dieValue==3){
            if(onHold==false){
                g.setColor(Color.black);
            }
            else{
                g.setColor(Color.white);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.black);
            }
            else{
                g.setColor(Color.white);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(23,23,5,5);

        }
        else if(dieValue==4){
            if(onHold==false){
                g.setColor(Color.black);
            }
            else{
                g.setColor(Color.white);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.black);
            }
            else{
                g.setColor(Color.white);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(7,38,5,5);
            g.fillOval(38,7,5,5);
        }
        else if(dieValue==5){
            if(onHold==false){
                g.setColor(Color.black);
            }
            else{
                g.setColor(Color.white);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.black);
            }
            else{
                g.setColor(Color.white);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(7,38,5,5);
            g.fillOval(38,7,5,5);
            g.fillOval(23,23,5,5);
        }
        else if(dieValue==6){
            if(onHold==false){
                g.setColor(Color.black);
            }
            else{
                g.setColor(Color.white);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.black);
            }
            else{
                g.setColor(Color.white);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(7,38,5,5);
            g.fillOval(38,7,5,5);
            g.fillOval(7,23,5,5);
            g.fillOval(38,23,5,5);
        }
    }
    if(pNum==2){
        if(dieValue==1){
            if(onHold==false){
                g.setColor(Color.blue);
            }
            else{
                g.setColor(Color.green);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.blue);
            }
            else{
                g.setColor(Color.green);
            }
            g.fillOval(23,23,5,5);
        }
        else if(dieValue==2){
            if(onHold==false){
                g.setColor(Color.blue);
            }
            else{
                g.setColor(Color.green);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.blue);
            }
            else{
                g.setColor(Color.green);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
        }
        else if(dieValue==3){
            if(onHold==false){
                g.setColor(Color.blue);
            }
            else{
                g.setColor(Color.green);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.blue);
            }
            else{
                g.setColor(Color.green);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(23,23,5,5);

        }
        else if(dieValue==4){
            if(onHold==false){
                g.setColor(Color.blue);
            }
            else{
                g.setColor(Color.green);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.blue);
            }
            else{
                g.setColor(Color.green);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(7,38,5,5);
            g.fillOval(38,7,5,5);
        }
        else if(dieValue==5){
            if(onHold==false){
                g.setColor(Color.blue);
            }
            else{
                g.setColor(Color.green);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.blue);
            }
            else{
                g.setColor(Color.green);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(7,38,5,5);
            g.fillOval(38,7,5,5);
            g.fillOval(23,23,5,5);
        }
        else if(dieValue==6){
            if(onHold==false){
                g.setColor(Color.blue);
            }
            else{
                g.setColor(Color.green);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.blue);
            }
            else{
                g.setColor(Color.green);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(7,38,5,5);
            g.fillOval(38,7,5,5);
            g.fillOval(7,23,5,5);
            g.fillOval(38,23,5,5);
        }
    }
    if(pNum==3){
        if(dieValue==1){
            if(onHold==false){
                g.setColor(Color.pink);
            }
            else{
                g.setColor(Color.orange);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.pink);
            }
            else{
                g.setColor(Color.orange);
            }
            g.fillOval(23,23,5,5);
        }
        else if(dieValue==2){
            if(onHold==false){
                g.setColor(Color.pink);
            }
            else{
                g.setColor(Color.orange);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.pink);
            }
            else{
                g.setColor(Color.orange);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
        }
        else if(dieValue==3){
            if(onHold==false){
                g.setColor(Color.pink);
            }
            else{
                g.setColor(Color.orange);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.pink);
            }
            else{
                g.setColor(Color.orange);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(23,23,5,5);

        }
        else if(dieValue==4){
            if(onHold==false){
                g.setColor(Color.pink);
            }
            else{
                g.setColor(Color.orange);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.pink);
            }
            else{
                g.setColor(Color.orange);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(7,38,5,5);
            g.fillOval(38,7,5,5);
        }
        else if(dieValue==5){
            if(onHold==false){
                g.setColor(Color.pink);
            }
            else{
                g.setColor(Color.orange);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.pink);
            }
            else{
                g.setColor(Color.orange);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(7,38,5,5);
            g.fillOval(38,7,5,5);
            g.fillOval(23,23,5,5);
        }
        else if(dieValue==6){
            if(onHold==false){
                g.setColor(Color.pink);
            }
            else{
                g.setColor(Color.orange);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.pink);
            }
            else{
                g.setColor(Color.orange);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(7,38,5,5);
            g.fillOval(38,7,5,5);
            g.fillOval(7,23,5,5);
            g.fillOval(38,23,5,5);
        }
    }
    if(pNum==4){
        if(dieValue==1){
            if(onHold==false){
                g.setColor(Color.red);
            }
            else{
                g.setColor(Color.gray);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.red);
            }
            else{
                g.setColor(Color.gray);
            }
            g.fillOval(23,23,5,5);
        }
        else if(dieValue==2){
            if(onHold==false){
                g.setColor(Color.red);
            }
            else{
                g.setColor(Color.gray);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.red);
            }
            else{
                g.setColor(Color.gray);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
        }
        else if(dieValue==3){
            if(onHold==false){
                g.setColor(Color.red);
            }
            else{
                g.setColor(Color.gray);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.red);
            }
            else{
                g.setColor(Color.gray);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(23,23,5,5);

        }
        else if(dieValue==4){
            if(onHold==false){
                g.setColor(Color.red);
            }
            else{
                g.setColor(Color.gray);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.red);
            }
            else{
                g.setColor(Color.gray);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(7,38,5,5);
            g.fillOval(38,7,5,5);
        }
        else if(dieValue==5){
            if(onHold==false){
                g.setColor(Color.red);
            }
            else{
                g.setColor(Color.gray);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.red);
            }
            else{
                g.setColor(Color.gray);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(7,38,5,5);
            g.fillOval(38,7,5,5);
            g.fillOval(23,23,5,5);
        }
        else if(dieValue==6){
            if(onHold==false){
                g.setColor(Color.red);
            }
            else{
                g.setColor(Color.gray);
            }
            g.fillRoundRect(0, 0, 50, 50, 10, 10);
            if(onHold==true){
                g.setColor(Color.red);
            }
            else{
                g.setColor(Color.gray);
            }
            g.fillOval(7,7,5,5);
            g.fillOval(38,38,5,5);
            g.fillOval(7,38,5,5);
            g.fillOval(38,7,5,5);
            g.fillOval(7,23,5,5);
            g.fillOval(38,23,5,5);
        }
    }
   }
}

Where I call upon roll in my frame:

 for(int i=0;i<numDice;i++){
     die[i].setPlayerNumber(cPlayer+1);
    if(die[i].checkOnHold()==false){
        for(int i2=0;i2<100;i2++){
            die[i].roll();
            try {
                    Thread.sleep(5);
            } catch (InterruptedException e) {
                // TODO Auto-generated      catch block
                e.printStackTrace();
            }
            repaint();
        }
    }
 }

Using repaint() is just causing the button pressed to be delayed

Any help would be much appreciated

Thank you

Upvotes: 0

Views: 2119

Answers (2)

MadProgrammer
MadProgrammer

Reputation: 347184

You're basically violating the single thread rules of Swing. In particular, you are performing a long running and blocking operation within the Event Dispatching Thread, preventing it from processing repaint requests, hence the reason nothing is working.

You could use a Swing Timer to solve the problem, but it's more likely that a SwingWorker will result in a more desirable result.

Take a look at Concurrency in swing for more details

Updated with example

I've gone through your code and there a number of things that scare me.

  • You should NEVER modify the UI in anyway from within a paint method, this will cause the repaint manager to schedule a new repaint, which will call your paint method and so on and so forth...

This...

this.setSize(50,50);
this.setVisible(true);

Is a very bad idea. First, you should never rely on setSize, but instead, override getPreferredSize. This will allow you to use appropriate layout managers to layout your component.

  • The use of a "player" flag in the DiePanel to determine where each die should be painted.

This is a bad idea of a number of reasons. Firstly, you are not actually keeping track of each players roll any way, so only the player's die will be painted, but every player will share the same die roll.

You are also repeating the same code for each player, which is an utter waste.

A DiePanel should represent a single unit of work, it should be representative of a single players results, or a multiple number of the panels could use to produce a cumulative result as required.

  • You should not rely on "magic" numbers.

Your paint code relies on the fact that the component is a given size, this is not always possible, instead, you should be using the components width and height values to better generate your results OR maintain the die at a static size, but position it better, such as in the middle of the component.

The following example corrects for the more serious of these issues, but is designed to demonstrate the use of a SwingWorker to simulate the die roll.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class DiceRoll {

    public static void main(String[] args) {
        new DiceRoll();
    }

    public DiceRoll() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private DiePanel diePane;

        public TestPane() {
            setLayout(new BorderLayout());
            diePane = new DiePanel();
            diePane.roll();
            add(diePane);
            JButton roll = new JButton("Roll");
            add(roll, BorderLayout.SOUTH);
            roll.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    new DieRoller(diePane).execute();
                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }
    }

    public class DieRoller extends SwingWorker<Void, Integer> {

        private DiePanel diePane;

        public DieRoller(DiePanel diePane) {
            this.diePane = diePane;
        }

        @Override
        protected void process(List<Integer> chunks) {
            diePane.roll();
        }

        @Override
        protected Void doInBackground() throws Exception {
            int rolls = ((int) Math.round(Math.random() * 100)) + 1;
            System.out.println("Rolls = " + rolls);
            for (int roll = 0; roll < rolls; roll++) {
                publish(roll);
                Thread.sleep(125);
            }
            return null;
        }
    }

    public class DiePanel extends JPanel {

        private int dieValue;
        private boolean onHold = false;

        public DiePanel() {
            super();
        }

        public void setDieValue(int dieValue) {
            this.dieValue = dieValue;
        }

        public int checkDieValue() {
            return dieValue;
        }

        public void roll() {
            dieValue = (int) ((Math.random() * 6) + 1);
            repaint();
        }

        public void changeOnHold() {
            onHold = !onHold;
        }

        public void unHold() {
            onHold = false;
        }

        public boolean checkOnHold() {
            return onHold;
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (dieValue == 1) {
                if (onHold == false) {
                    g.setColor(Color.black);
                } else {
                    g.setColor(Color.white);
                }
                g.fillRoundRect(0, 0, 50, 50, 10, 10);
                if (onHold == true) {
                    g.setColor(Color.black);
                } else {
                    g.setColor(Color.white);
                }
                g.fillOval(23, 23, 5, 5);
            } else if (dieValue == 2) {
                if (onHold == false) {
                    g.setColor(Color.black);
                } else {
                    g.setColor(Color.white);
                }
                g.fillRoundRect(0, 0, 50, 50, 10, 10);
                if (onHold == true) {
                    g.setColor(Color.black);
                } else {
                    g.setColor(Color.white);
                }
                g.fillOval(7, 7, 5, 5);
                g.fillOval(38, 38, 5, 5);
            } else if (dieValue == 3) {
                if (onHold == false) {
                    g.setColor(Color.black);
                } else {
                    g.setColor(Color.white);
                }
                g.fillRoundRect(0, 0, 50, 50, 10, 10);
                if (onHold == true) {
                    g.setColor(Color.black);
                } else {
                    g.setColor(Color.white);
                }
                g.fillOval(7, 7, 5, 5);
                g.fillOval(38, 38, 5, 5);
                g.fillOval(23, 23, 5, 5);

            } else if (dieValue == 4) {
                if (onHold == false) {
                    g.setColor(Color.black);
                } else {
                    g.setColor(Color.white);
                }
                g.fillRoundRect(0, 0, 50, 50, 10, 10);
                if (onHold == true) {
                    g.setColor(Color.black);
                } else {
                    g.setColor(Color.white);
                }
                g.fillOval(7, 7, 5, 5);
                g.fillOval(38, 38, 5, 5);
                g.fillOval(7, 38, 5, 5);
                g.fillOval(38, 7, 5, 5);
            } else if (dieValue == 5) {
                if (onHold == false) {
                    g.setColor(Color.black);
                } else {
                    g.setColor(Color.white);
                }
                g.fillRoundRect(0, 0, 50, 50, 10, 10);
                if (onHold == true) {
                    g.setColor(Color.black);
                } else {
                    g.setColor(Color.white);
                }
                g.fillOval(7, 7, 5, 5);
                g.fillOval(38, 38, 5, 5);
                g.fillOval(7, 38, 5, 5);
                g.fillOval(38, 7, 5, 5);
                g.fillOval(23, 23, 5, 5);
            } else if (dieValue == 6) {
                if (onHold == false) {
                    g.setColor(Color.black);
                } else {
                    g.setColor(Color.white);
                }
                g.fillRoundRect(0, 0, 50, 50, 10, 10);
                if (onHold == true) {
                    g.setColor(Color.black);
                } else {
                    g.setColor(Color.white);
                }
                g.fillOval(7, 7, 5, 5);
                g.fillOval(38, 38, 5, 5);
                g.fillOval(7, 38, 5, 5);
                g.fillOval(38, 7, 5, 5);
                g.fillOval(7, 23, 5, 5);
                g.fillOval(38, 23, 5, 5);
            }
        }
    }
}

Upvotes: 2

John3136
John3136

Reputation: 29266

Google "java animation".

You have got everything on the Event Dispatch Thread (EDT), and so it never gets a chance to actually handle any events.

Upvotes: -1

Related Questions