1

Here is the spec for my task:

Write a class called Die which extends JPanel. Objects of this class, representing a standard six faced die, should draw a representation of themselves on the panel, It is sufficient to draw a top-down view of a single face of the die showing the 'current' number rolled. The class should also provide a method updateVal(int i). which accepts an int between 1 and 6 and then updates the display to show the new value.

I have completed everything up until the last updateVal(int i) method and am having trouble with this and making it override the random value assigned to roll in my paintComponent(Graphics g). Basically this method should be able to specify which face the program should show upon booting.

package weekThree;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.*;

@SuppressWarnings("serial")
public class Die extends JPanel {

    static Random rand = new Random();

    private Color circleColor = Color.BLACK;
    private int circX  = 75;
    private int circY = circX;
    private int circW = 75;
    private int circH = circW;

    public Die() {
        addMouseListener(new MyMouse());
    }

    protected void paintComponent(Graphics g) {

        super.paintComponent(g);

        int roll = (rand.nextInt(6) + 1); //rolls the dice

        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //smoothes edges
        g2.setColor(circleColor);

        if (roll == 1) {  //each body updates the associated dots
            g2.fillOval(325, 325, circW, circH);
            g2.drawOval(325, 325, circW, circH);
        }

        if (roll == 2) {
            g2.fillOval(circX, circY, circW, circH);
            g2.drawOval(circX, circY, circW, circH);

            g2.fillOval(600, 600, circW, circH);
            g2.drawOval(600, 600, circW, circH);
        }

        if (roll == 3) {
            g2.fillOval(circX, 600, circW, circH);
            g2.drawOval(circX, 600, circW, circH);

            g2.fillOval(325, 325, circW, circH);
            g2.drawOval(325, 325, circW, circH);

            g2.fillOval(600, circY, circW, circH);
            g2.drawOval(600, circY, circW, circH);
        }

        if (roll == 4) {
            g2.fillOval(circX, circY, circW, circH);
            g2.drawOval(circX, circY, circW, circH);

            g2.fillOval(600, circY, circW, circH);
            g2.drawOval(600, circY, circW, circH);

            g2.fillOval(circX, 600, circW, circH);
            g2.drawOval(circX, 600, circW, circH);

            g2.fillOval(600, 600, circW, circH);
            g2.drawOval(600, 600, circW, circH);
        }

        if (roll == 5) {
             g2.fillOval(circX, circY, circW, circH);
             g2.drawOval(circX, circY, circW, circH);

             g2.fillOval(600, circY, circW, circH);
             g2.drawOval(600, circY, circW, circH);          

             g2.fillOval(600, 600, circW, circH);
             g2.drawOval(600, 600, circW, circH);             

             g2.fillOval(circX, 600, circW, circH);
             g2.drawOval(circX, 600, circW, circH);

             g2.fillOval(325, 325, circW, circH);
             g2.drawOval(325, 325, circW, circH);
        }

        if (roll == 6) {
            g2.fillOval(circX, circY, circW, circH);
            g2.drawOval(circX, circY, circW, circH);

            g2.fillOval(600, circY, circW, circH);
            g2.drawOval(600, circY, circW, circH);

            g2.fillOval(600, 325, circW, circH);
            g2.drawOval(600, 325, circW, circH);

            g2.fillOval(600, 600, circW, circH);
            g2.drawOval(600, 600, circW, circH);

            g2.fillOval(circX, 325, circW, circH);
            g2.drawOval(circX, 325, circW, circH);

            g2.fillOval(circX, 600, circW, circH);
            g2.drawOval(circX, 600, circW, circH);
        }

    }

    public void updateVal(int i) {  //takes an int i between 1 and 6 and updates the face

        if (i < 1 || i > 6) {
            new IndexOutOfBoundsException("Choose a number between 1 and 6!");
        }

        else {
            //here the face of the die should be updated according to what value of i is passed through

            repaint();
        }
    }

    private class MyMouse extends MouseAdapter {

        Random rand = new Random();

        public void mousePressed(MouseEvent e) {
            int roll = rand.nextInt(6);  //re-roll dice on click
            repaint();  //repaint components accordingly
        }
    }

    private static void createAndShowGui() { //creation of GUI visuals
        JFrame frame = new JFrame("Die Roller");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new Die());

        frame.setSize(800, 800);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

Thanks for any help

DaveRamseyFan
  • 45
  • 2
  • 9
  • 1
    Why would you change `roll` in the `paintComponent` method anyway? It doesn't make much sense the dice result would change every time the window repaints. Just declare `roll` in your class and get rid of the `int roll = rand.nextInt(...)` in the `paintComponent` method. Call `updateVal(rand.nextInt(6) + 1)` in your constructor and also change `int roll = rand.nextInt(6);` in your `mousePressed` method to `roll = rand.nextInt(6) + 1` – Lukas Rotter Feb 12 '16 at 23:25
  • 1
    You might want to start with [Painting in AWT and Swing](http://www.oracle.com/technetwork/java/painting-140037.html) and [Performing Custom Painting](http://docs.oracle.com/javase/tutorial/uiswing/painting/) – MadProgrammer Feb 12 '16 at 23:34
  • 1
    And the have a look at [this example](http://stackoverflow.com/questions/21033199/how-do-i-stop-my-paint-method-form-repeating-twice/21033258#21033258) – MadProgrammer Feb 12 '16 at 23:35

1 Answers1

2

You need to decouple the randomize logic from the graphic part. then we have 2 options :

  1. randomize and 'make the graphic'
  2. static assinment and 'make the graphic'

see comments inline

package weekThree;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.util.*;

@SuppressWarnings("serial")
public class Die extends JPanel {


    static Random rand = new Random();
    // make roll a field to be seen by all methods
    private int roll;
    private Color circleColor = Color.BLACK;
    private int circX  = 75;
    private int circY = circX;
    private int circW = 75;
    private int circH = circW;

    public Die() {
        addMouseListener(new MyMouse());
    }

    protected void paintComponent(Graphics g) {

        super.paintComponent(g);
        // remove the randomize logic from here
        //int roll = (rand.nextInt(6) + 1); //rolls the dice

        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //smoothes edges
        g2.setColor(circleColor);

        if (roll == 1) {  //each body updates the associated dots
            g2.fillOval(325, 325, circW, circH);
            g2.drawOval(325, 325, circW, circH);
        }

        if (roll == 2) {
            g2.fillOval(circX, circY, circW, circH);
            g2.drawOval(circX, circY, circW, circH);

            g2.fillOval(600, 600, circW, circH);
            g2.drawOval(600, 600, circW, circH);
        }

        if (roll == 3) {
            g2.fillOval(circX, 600, circW, circH);
            g2.drawOval(circX, 600, circW, circH);

            g2.fillOval(325, 325, circW, circH);
            g2.drawOval(325, 325, circW, circH);

            g2.fillOval(600, circY, circW, circH);
            g2.drawOval(600, circY, circW, circH);
        }

        if (roll == 4) {
            g2.fillOval(circX, circY, circW, circH);
            g2.drawOval(circX, circY, circW, circH);

            g2.fillOval(600, circY, circW, circH);
            g2.drawOval(600, circY, circW, circH);

            g2.fillOval(circX, 600, circW, circH);
            g2.drawOval(circX, 600, circW, circH);

            g2.fillOval(600, 600, circW, circH);
            g2.drawOval(600, 600, circW, circH);
        }

        if (roll == 5) {
             g2.fillOval(circX, circY, circW, circH);
             g2.drawOval(circX, circY, circW, circH);

             g2.fillOval(600, circY, circW, circH);
             g2.drawOval(600, circY, circW, circH);

             g2.fillOval(600, 600, circW, circH);
             g2.drawOval(600, 600, circW, circH);

             g2.fillOval(circX, 600, circW, circH);
             g2.drawOval(circX, 600, circW, circH);

             g2.fillOval(325, 325, circW, circH);
             g2.drawOval(325, 325, circW, circH);
        }

        if (roll == 6) {
            g2.fillOval(circX, circY, circW, circH);
            g2.drawOval(circX, circY, circW, circH);

            g2.fillOval(600, circY, circW, circH);
            g2.drawOval(600, circY, circW, circH);

            g2.fillOval(600, 325, circW, circH);
            g2.drawOval(600, 325, circW, circH);

            g2.fillOval(600, 600, circW, circH);
            g2.drawOval(600, 600, circW, circH);

            g2.fillOval(circX, 325, circW, circH);
            g2.drawOval(circX, 325, circW, circH);

            g2.fillOval(circX, 600, circW, circH);
            g2.drawOval(circX, 600, circW, circH);
        }

    }

    public void updateVal(int i) {  //takes an int i between 1 and 6 and updates the face

        if (i < 1 || i > 6) {
            new IndexOutOfBoundsException("Choose a number between 1 and 6!");
        }

        else {
            //here the face of the die should be updated according to what value of i is passed through
            // static assinment and 'make the graphic'
            roll = i;
            repaint();
        }
    }

    private class MyMouse extends MouseAdapter {

        Random rand = new Random();

        public void mousePressed(MouseEvent e) {
            //
            // updateVal(2); // can be used for test
            // randomize and 'make the graphic'
            roll = rand.nextInt(6);  //re-roll dice on click
            repaint();  //repaint components accordingly
        }
    }

    private static void createAndShowGui() { //creation of GUI visuals
        JFrame frame = new JFrame("Die Roller");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(new Die());

        frame.setSize(800, 800);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}
chenchuk
  • 5,324
  • 4
  • 34
  • 41
  • Can I suggest you get rid of `static Random rand = new Random();` as it's not required and is simply adding noise (which some people, like me, might get nit picky over ;)) – MadProgrammer Feb 13 '16 at 01:06