I am currently working on a simple GUI application that rolls two dice. I am currently using two classes, one called “Game” and the other “DiceRoll”. For meeting the assignment criteria, we have to use multiple classes in order for the program to work. It would be much easier just using one class…Anyways, I am successfully calling my “roll()” method in my “DiceRoll” class, which uses a switch statement and implements the “Graphics.drawImage()” method in order to draw the specified “.png” images. Everything looks fine, and I have no errors before I run it. When I run the program, the GUI frame pops up and all of the buttons/menus that I have created are working. However, once I press the “Roll Dice” button, I keep receiving multiple run-time errors.
This is what I have so far:
Game Class
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class Game extends JFrame implements ActionListener
{
JPanel mainPanel;
JPanel optionPanel;
JPanel dicePanel;
JButton rollDice;
JMenu options;
JMenuItem quit;
JMenuItem explanation;
JMenuBar menuBar;
JLabel diceLabel;
JLabel diceLabel2;
DiceRoll dr;
Graphics die1;
Graphics die2;
public Game()
{
setTitle("Rollin' Dice");
this.setPreferredSize(new Dimension(600,600));
mainPanel = new JPanel();
optionPanel = new JPanel();
dicePanel = new JPanel();
rollDice = new JButton("Roll Dice");
options = new JMenu("Options");
quit = new JMenuItem("Quit");
explanation = new JMenuItem("Explanation");
menuBar = new JMenuBar();
dr = new DiceRoll();
diceLabel = new JLabel();
diceLabel2 = new JLabel();
options.add(quit);
options.add(explanation);
menuBar.add(options);
optionPanel.add(menuBar);
optionPanel.setPreferredSize(new Dimension(600,100));
dicePanel.add(rollDice);
dicePanel.add(diceLabel);
dicePanel.add(diceLabel2);
mainPanel.setPreferredSize(new Dimension(600,600));
mainPanel.add(optionPanel);
mainPanel.add(dicePanel);
quit.addActionListener(this);
explanation.addActionListener(this);
rollDice.addActionListener(this);
this.getContentPane().add(mainPanel);
this.pack();
this.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource()== quit)
System.exit(0);
if (e.getSource() == explanation)
{
JOptionPane.showMessageDialog(mainPanel,
"Win: Roll a sum that is an even number \nLose: Roll a sum that is an odd number" + dicePanel, "Rules", JOptionPane.INFORMATION_MESSAGE);
}
if (e.getSource() == rollDice)
{
dr.roll(die1);
dr.roll(die2);
diceLabel.updateUI();
dicePanel.updateUI();
}
}
public static void main (String []args)
{
Game dg = new Game();
}
}
DiceRoll Class
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.imageio.*;
import java.io.File;
import java.io.IOException;
import javax.swing.JComponent;
public class DiceRoll extends JComponent {
private BufferedImage die1;
private BufferedImage die2;
private BufferedImage die3;
private BufferedImage die4;
private BufferedImage die5;
private BufferedImage die6;
public DiceRoll()
{
try {
die1 = (ImageIO.read(new File("die1.png")));
die2 = ImageIO.read(new File("die2.png"));
die3 = ImageIO.read(new File("die3.png"));
die4 = ImageIO.read(new File("die4.png"));
die5 = ImageIO.read(new File("die5.png"));
die6 = ImageIO.read(new File("die6.png"));
} catch (IOException ex){
System.err.println("That is invalid");
}
}
public Graphics roll(Graphics g)
{
int dieResult = (int)(6 * Math.random());
switch(dieResult){
case 1:
g.drawImage(die1, 0, 0, null);
break;
case 2:
g.drawImage(die2, 0, 0, null);
break;
case 3:
g.drawImage(die3, 0, 0, null);
break;
case 4:
g.drawImage(die4, 0, 0, null);
break;
case 5:
g.drawImage(die5, 0, 0, null);
break;
case 6:
g.drawImage(die6, 0, 0, null);
break;
}
return g;
}
}
Errors that I am receiving
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at DiceRoll.roll(DiceRoll.java:51)
at Game.actionPerformed(Game.java:89)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
I think you’re making this much more complicated than is necessary. Why don’t you change your
public Graphics roll(Graphics g)method to calculate the roll and update theJLabel, something like this…Then all you need to do is change your code here …
to send the label you want to change, like this…
You pass the
JLabelthrough to theroll()method, which calculates the roll and sets the image on that label. Much simpler.This also means that you don’t need the 2
Graphicsobjects either (die1anddie2), so you can get rid of these. You also wouldn’t need theBufferedImages, because the loading of the image file is done by theImageIconclassLet me know if you need any further information about my suggestion, for learning purposes.
EDIT…
This is my re-writing of your
Game()constructor, that shows how to add items toJPanelsusingGridLayoutandBorderLayoutas the layout managers…