-1

My code compiles and seemingly runs fine until I hit the JButton and then I get a lot of errors. I'm not sure what I'm doing wrong. What the code is supposed to do is have a window come up and randomly display two image of dice when the button is clicked. The images are in the same directory as my program and they are named 1-6.

Here's the code:

import java.lang.Math;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DiceSimulator extends JFrame
{
  private JLabel dieOne;
  private JLabel dieTwo;
  public DiceSimulator()
  {
    setTitle("Dice Simulator");
    JLabel dieOne, dieTwo;
    dieOne = new JLabel();
    dieTwo = new JLabel();
    JButton button = new JButton("Roll the Dice");
    button.addActionListener(new buttonListener());  
    setLayout(new BorderLayout());
    JPanel panel = new JPanel();
    panel.add(button, BorderLayout.SOUTH);
    panel.add(dieOne);
    panel.add(dieTwo);
    add(panel);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack();
    setVisible(true);
    }
  private class buttonListener implements ActionListener
  {
    public void actionPerformed(ActionEvent e)
    {
      ImageIcon one = new ImageIcon("1.jpg"); 
      ImageIcon two = new ImageIcon("2.jpg"); 
      ImageIcon three = new ImageIcon("3.jpg"); 
      ImageIcon four = new ImageIcon("4.jpg"); 
      ImageIcon five = new ImageIcon("5.jpg"); 
      ImageIcon six = new ImageIcon("6.jpg"); 
      int firstRoll = (int)(Math.random()*6)+1;
      int secondRoll = (int)(Math.random()*6)+1;
      switch(firstRoll)
      {
        case 1: dieOne.setIcon(one);
        dieOne.setText(null);
        break;
        case 2: dieOne.setIcon(two);
        dieOne.setText(null);
        break;
        case 3: dieOne.setIcon(three);
        dieOne.setText(null);
        break;
        case 4: dieOne.setIcon(four);
        dieOne.setText(null);
        break;
        case 5: dieOne.setIcon(five);
        dieOne.setText(null);
        break;
        case 6: dieOne.setIcon(six);
        dieOne.setText(null);
        break;
      }
      switch(secondRoll)
      {
        case 1: dieTwo.setIcon(one);
        dieTwo.setText(null);
        break;
        case 2: dieTwo.setIcon(two);
        dieTwo.setText(null);
        break;
        case 3: dieTwo.setIcon(three);
        dieTwo.setText(null);
        break;
        case 4: dieTwo.setIcon(four);
        dieTwo.setText(null);
        break;
        case 5: dieTwo.setIcon(five);
        dieTwo.setText(null);
        break;
        case 6: dieTwo.setIcon(six);
        dieTwo.setText(null);
        break;
      }
    }
  }
  public static void main(String[] args)
  {
    new DiceSimulator();
  }
}

Here's the errors I get by clicking the button:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at DiceSimulator$buttonListener.actionPerformed(DiceSimulator.java:57)
    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.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(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)
Alex
  • 59
  • 11

2 Answers2

2

I don't think you're generating random numbers correctly. When I run similar code to generate random numbers as you're doing it I get a bunch of zeroes included in the random numbers, which you don't handle with your switch statement.

To be safe, import that java.util.Random package, and make an object like

import java.util.Random;

public class testRandom{

  public static void main (String [] args){
    Random rg = new Random();
   int x;
   for(int i = 0; i < 100; i++){
    x = rg.nextInt(6) + 1;
    System.out.println(x);
   }

  }


}

UPDATE

The way that you really want to implement the JFrame is to have a constructor method that builds a JPanel and then is called by the main method. Take a look at how the sample programs are set up in the Java tutorial for creating JFrame applications -- they've got some nice sample code on there of how you want to structure your program.

The reason I'd use static JLabel declarations will be kind of unnecessary if you change your program to the structure in the sample, but essentially if you declare a class variable, like a JLabel, every instance of the class that is constructed will have its own versions of those variables. So when you have a method OUTSIDE of the constructor, you won't be working on the same JLabels, even though they have the same name -- again all of this will be irrelevant if you rework your program.

An anonymous implementation of an interface can be done when you build a new object. For an action listener it would look something like:

JButton button = new JButton("Click me!");
button.addActionListener(new ActionListener(){
   public void (ActionPerformed ap){
     //DO SOMETHING ON CLICK
  }
});

I suspect that the reason you were getting your error is because your actionListener wasn't working on the same JLabels that had been created when the constructor was called - which would be why I'd try static declarations of the variables, or an anonymous implementation of the interface

chope_chope
  • 450
  • 2
  • 4
  • 14
0

When I'm running the code it throws exception when changing the icon. Looks like the images you are loading don't exist there. Try to find out, whats your relative path, or to test things use absolute pathes.

Write a comment if you need more explanation.

Hope I could help.

EDIT

Some more explanation:

The application "runs" at a specific location on your hard drive, when saying it easy :D You want to load the pictures. As the pathes you give him don't start with a slash it interprets them as relative pathes. That means, he looks in the executing directory for the image. When it starts with a "/" he interprets as an absolute path, which starts at your hard drive.

Here is explained how you get your execution directory. Just use

System.out.println(this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath());

when creating the object and check what the console outputs when you start your program. In the folder named there you have to put your pictures. That's not recommended, but to test things it works.

EDIT 2

Didn't noticed:

You got the JLabels dieOne and dieTwo here:

private JLabel dieOne;
private JLabel dieTwo;

These are the "global" variables which can be hidden by local variables with the same name in a method. Thats where you made a mistake. You write:

public DiceSimulator() {
    setTitle("Dice Simulator");
    JLabel dieOne, dieTwo;
    [...]

There you hide the "global" dieOne and dieTwo because you declare the local ones with the same name. But they aren't necessary, because you want to initialize the "global" JLabels. When you do it as it is right now, The dieOne and dieTwo in the constructor are destroyed when finishing instantiate the object and the "globals" got no value => They have no address which causes a NullPointerException, when trying to change the text. Just remove the

JLabel dieOne, dieTwo;

and all should be could.

Finally hope that everything is clear and I could help.

Community
  • 1
  • 1
Frozn
  • 539
  • 1
  • 8
  • 17
  • Thanks for not being rude first off. I have the images on my computer so they should be loading, if that's what you mean to say. – Alex Oct 30 '14 at 01:56
  • The application runs at a specific location on your hard drive, when saying it easy :D You want to load the pictures. As the pathes you give him don't start with a slash it interprets them as relative pathes. That means, he looks in the executing directory for the image. When it starts with a / he interprets as an absolute path, which starts at your hard drive. Just ask if it's not clear enough :D – Frozn Oct 30 '14 at 02:03
  • The images are in the executing directory if they are in the same folder as the running program, correct? – Alex Oct 30 '14 at 02:06
  • Look in my edited answer and check if you think that the directory you're think is the execution directory really is it. – Frozn Oct 30 '14 at 02:15
  • I directed it to the images, no luck unfortunately. – Alex Oct 30 '14 at 02:19
  • Ohhh, wait found another mistake. Writing it as an edit... Again :) – Frozn Oct 30 '14 at 02:25