# Java: Example - Rolling Dice

| The applet / application to the left rolls two dice. It is divided into three source files. `RollDice.java` is both an application (it defines `main()`) and an applet (it subclasses `JApplet`). `RollDicePanel.java` is a subclass of JPanel that creates the GUI interface. `Die.java` defines a component as a subclass of JComponent, and provides a graphical view of the die face. It implements logic with a `roll()` method that randomly "rolls" the die.

### `RollDice.java` - the main program / applet

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
    // File:   rolldice/RollDice.java
    // Description: Main program and applet display two dice and roll them.
    // Tag: <applet code="rolldice.RollDice.class" archive="rolldice.jar"
    //            width="140" height="117"></applet>
    // Author: Fred Swartz - 2006-11-30 - Placed in public domain.

    package rolldice;

    import java.awt.*;
    import javax.swing.*;

    ///////////////////////////////////////////////////////// class RollDice
    public class RollDice extends JApplet {

        //=============================================== applet constructor
        /** Applet constructor requires putting the panel in applet.*/
        public RollDice() {
            this.setContentPane(new RollDicePanel());
        }

        //====================================================== method main
        /** Create JFrame and set content pane to a RollDicePanel. */
        public static void main(String[] args) {
            JFrame window = new JFrame("Dice Demo");
            window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            window.setContentPane(new RollDicePanel());
            window.pack();
            //System.out.println(window.getContentPane().getSize());
            window.setLocationRelativeTo(null);
            window.setVisible(true);
        }
    }

### `RollDicePanel.java` provides the GUI to this demo program

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
    // File:   rolldice/RollDicePanel.java
    // Description: Panel of GUI, shows button and two dice.
    // Author: Fred Swartz - 2006-11-30 - Placed in public domain.

    package rolldice;

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.event.*;

    //////////////////////////////////////////////////////////// class RollDicePanel
    public class RollDicePanel extends JPanel {
        //======================================================= instance variables
        private Die _leftDie;     // component for one die
        private Die _rightDie;

        //============================================================== constructor
        /** Create border layout panel with one button and two dice. */
        RollDicePanel() {
            //... Create the dice
            _leftDie  = new Die();
            _rightDie = new Die();

            //...Create the button to roll the dice
            JButton rollButton = new JButton("New Roll");
            rollButton.setFont(new Font("Sansserif", Font.PLAIN, 24));

            //... Add listener.
            rollButton.addActionListener(new RollListener());

            //... Layout components
            this.setLayout(new BorderLayout(5, 5));
            this.add(rollButton, BorderLayout.NORTH);
            this.add(_leftDie , BorderLayout.WEST);
            this.add(_rightDie, BorderLayout.EAST);

            this.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
        }

        ////////////////////////////////////////// inner listener class RollListener
        private class RollListener implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                _leftDie.roll();
                _rightDie.roll();
            }
        }
    }

### `Die.java` implements the graphics and logic of a die

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    // File:   rolldice/Die.java
    // Description: Models / displays one die.
    // Author: Fred Swartz - 2006-11-30 - Placed in public domain.

    package rolldice;

    import java.awt.*;
    import javax.swing.*;

    ////////////////////////////////////////////////////////////////////// class Die
    public class Die extends JComponent {
        //================================================================ constants
        private static final int SPOT_DIAM = 9;  // Diameter of spots

        //======================================================= instance variables
        private int _faceValue;     // value that shows on face of die

        //============================================================== constructor
        /** Initialize to white background and 60x60 pixels. Initial roll.*/
        public Die() {
            //-- Preferred size is set, but layout may change it.
            setPreferredSize(new Dimension(60,60));
            roll();  // Set to random initial value
        }

        //============================================================== method roll
        /** Produce random roll in range 1-6.  Causes repaint().
         * @return Result of roll (1-6).
         */
        public int roll() {
            int val = (int)(6*Math.random() + 1);   // Range 1-6
            setValue(val);
            return val;
        }

        //========================================================== method getValue
        /** Returns result of last roll.*/
        public int getValue() {
            return _faceValue;
        }

        //========================================================== method setValue
        /** Sets the value of the Die.  Causes repaint().
         * @param spots Number from 1-6.
         */
        public void setValue(int spots) {
            _faceValue = spots;
            repaint();    // Value has changed, must repaint
        }

        //==================================================== method paintComponent
        /** Draws spots of die face. */
        @Override public void paintComponent(Graphics g) {
            int w = getWidth();  // Get height and width
            int h = getHeight();

            //... Change to Graphic2D for smoother spots.
            Graphics2D g2 = (Graphics2D)g;  // See note below
            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                    RenderingHints.VALUE_ANTIALIAS_ON);

            //... Paint background
            g2.setColor(Color.WHITE);
            g2.fillRect(0, 0, w, h);
            g2.setColor(Color.BLACK);

            g2.drawRect(0, 0, w-1, h-1);  // Draw border

            switch (_faceValue) {
                case 1:
                    drawSpot(g2, w/2, h/2);
                    break;
                case 3:
                    drawSpot(g2, w/2, h/2);
                    // Fall thru to next case
                case 2:
                    drawSpot(g2, w/4, h/4);
                    drawSpot(g2, 3*w/4, 3*h/4);
                    break;
                case 5:
                    drawSpot(g2, w/2, h/2);
                    // Fall thru to next case
                case 4:
                    drawSpot(g2, w/4, h/4);
                    drawSpot(g2, 3*w/4, 3*h/4);
                    drawSpot(g2, 3*w/4, h/4);
                    drawSpot(g2, w/4, 3*h/4);
                    break;
                case 6:
                    drawSpot(g2, w/4, h/4);
                    drawSpot(g2, 3*w/4, 3*h/4);
                    drawSpot(g2, 3*w/4, h/4);
                    drawSpot(g2, w/4, 3*h/4);
                    drawSpot(g2, w/4, h/2);
                    drawSpot(g2, 3*w/4, h/2);
                    break;
            }
        }

        //========================================================== method drawSpot
        /** Utility method used by paintComponent(). */
        private void drawSpot(Graphics2D g2, int x, int y) {
            g2.fillOval(x-SPOT_DIAM/2, y-SPOT_DIAM/2, SPOT_DIAM, SPOT_DIAM);
        }
    }