How to get ImageIcon from Enum?

2019-08-30 04:54发布

问题:

My Gui class pulls up an ExceptioninInitializerError due to NullPointerException.

My question is, how can I get information from my enum (such as the ImageIcon of Rock) and use it to setIcon of my JPanel without getting this error.

EDIT: When I click the Rock Button on the GUI, this is the error that is brought up

Exception in thread "AWT-EventQueue-0" java.lang.ExceptionInInitializerError
at rockPaperScissors.RockPaperScissorsGui$2.actionPerformed(RockPaperScissorsGui.java:156)
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$400(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)
Caused by: java.lang.NullPointerException
at javax.swing.ImageIcon.<init>(Unknown Source)
at rockPaperScissors.RockPaperScissors.<clinit>(RockPaperScissors.java:7)
... 37 more

Enum

package rockPaperScissors;

import javax.swing.Icon;
import javax.swing.ImageIcon;


public enum RockPaperScissors {
    ROCK(new ImageIcon(RockPaperScissors.class.getResource("Rock.jpg"))),
    PAPER(new ImageIcon(RockPaperScissors.class.getResource("Paper.gif"))),
    SCISSORS(new ImageIcon(RockPaperScissors.class.getResource("Scissors.jpg")));

    private ImageIcon icon;
    private int humanScore;
    private int computerScore;


    private RockPaperScissors(ImageIcon icon) {
        setIcon(icon);
    }

    public String evaluate(int humanChoice, int computerChoice ) {
        if ((humanChoice == 1 && computerChoice == 2)
                ||(humanChoice == 2 && computerChoice == 3)
                ||(humanChoice == 3 && computerChoice == 1)) {
            computerScore += 1;
            return "You Lose";
        } else if ((humanChoice == 2 && computerChoice == 1)
                ||(humanChoice == 3 && computerChoice == 2)
                ||(humanChoice == 1 && computerChoice == 3)) {
            humanScore += 1;
            return "You Win";
        } else {
            return "You Tie";
        }
    }

    public int getHumanScore() {
        return humanScore;
    }

    public int getComputerScore() {
            return computerScore;
    }

    public void setIcon(ImageIcon icon) {
        this.icon = icon;
    }

    public ImageIcon getIcon() {
        return icon;
    }
}

Gui

package rockPaperScissors;


import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;

import java.awt.GridLayout;

import javax.swing.BoxLayout;

import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;

import javax.swing.ImageIcon;

import java.awt.Dimension;
import java.awt.Component;

import javax.swing.Box;
import javax.swing.JLabel;

import java.awt.Font;

import javax.swing.SwingConstants;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Random;
import java.awt.FlowLayout;
import javax.swing.JTextPane;


public class RockPaperScissorsGui extends JFrame {

private JPanel contentPane;

/**
 * Launch the application.
 */
private int humanChoice;
private int computerChoice;
private Random rand = new Random();
private ArrayList choices = new ArrayList<>();

public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                RockPaperScissorsGui frame = new RockPaperScissorsGui();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public RockPaperScissorsGui() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 801, 525);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);

    ImageIcon background = new ImageIcon(RockPaperScissorsGui.class.getResource("Background.jpg"));


    choices.add(1);
    choices.add(2);
    choices.add(3);

    JLabel lblRockPaperScissors = new JLabel("Rock, Paper, Scissors");
    lblRockPaperScissors.setPreferredSize(new Dimension(103, 50));
    lblRockPaperScissors.setHorizontalAlignment(SwingConstants.CENTER);
    lblRockPaperScissors.setAlignmentX(Component.CENTER_ALIGNMENT);
    lblRockPaperScissors.setFont(new Font("Comic Sans MS", Font.PLAIN, 22));
    contentPane.add(lblRockPaperScissors, BorderLayout.NORTH);

    JPanel panel = new JPanel();
    contentPane.add(panel, BorderLayout.SOUTH);



    JPanel panel_1 = new JPanel();
    contentPane.add(panel_1, BorderLayout.CENTER);
    panel_1.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));

    Component horizontalStrut_2 = Box.createHorizontalStrut(20);
    horizontalStrut_2.setPreferredSize(new Dimension(110, 0));
    panel_1.add(horizontalStrut_2);

    JLabel userChoiceLabel = new JLabel("");
    userChoiceLabel.setPreferredSize(new Dimension(200, 200));
    panel_1.add(userChoiceLabel);

    Component horizontalStrut = Box.createHorizontalStrut(20);
    horizontalStrut.setPreferredSize(new Dimension(100, 0));
    panel_1.add(horizontalStrut);

    JLabel computerChoiceLabel = new JLabel("");
    computerChoiceLabel.setPreferredSize(new Dimension(200, 200));
    panel_1.add(computerChoiceLabel);

    Component horizontalStrut_1 = Box.createHorizontalStrut(20);
    horizontalStrut_1.setPreferredSize(new Dimension(110, 0));
    panel_1.add(horizontalStrut_1);

    Component horizontalStrut_4 = Box.createHorizontalStrut(20);
    horizontalStrut_4.setPreferredSize(new Dimension(740, 60));
    panel_1.add(horizontalStrut_4);

    JLabel lblUserScore = new JLabel("User Score");
    panel_1.add(lblUserScore);

    JTextPane txtpnUserScore = new JTextPane();
    txtpnUserScore.setText("User Score");
    panel_1.add(txtpnUserScore);

    Component horizontalStrut_3 = Box.createHorizontalStrut(20);
    horizontalStrut_3.setPreferredSize(new Dimension(100, 0));
    panel_1.add(horizontalStrut_3);

    JTextPane textPane = new JTextPane();
    panel_1.add(textPane);

    Component horizontalStrut_5 = Box.createHorizontalStrut(20);
    horizontalStrut_5.setPreferredSize(new Dimension(100, 0));
    panel_1.add(horizontalStrut_5);

    JLabel lblComputerScore = new JLabel("Computer Score");
    panel_1.add(lblComputerScore);

    JTextPane txtpnComputerScore = new JTextPane();
    txtpnComputerScore.setText("Computer Score");
    panel_1.add(txtpnComputerScore);

    JPanel panel_2 = new JPanel();
    contentPane.add(panel_2, BorderLayout.WEST);

    JPanel panel_3 = new JPanel();
    contentPane.add(panel_3, BorderLayout.EAST);

    JButton btnRock = new JButton("Rock");
    btnRock.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {

            userChoiceLabel.setIcon(RockPaperScissors.ROCK.getIcon());
        }
    });
    btnRock.setFont(new Font("Georgia", Font.PLAIN, 20));
    panel.add(btnRock);

    JButton btnPaper = new JButton("Paper");
    btnPaper.setFont(new Font("Georgia", Font.PLAIN, 20));
    panel.add(btnPaper);

    JButton btnScissors = new JButton("Scissors");
    btnScissors.setFont(new Font("Georgia", Font.PLAIN, 20));
    panel.add(btnScissors);
}

public int getHumanChoice() {
    return humanChoice;
}

public int getComputerChoice() {
    return computerChoice;
}

public void setComputerChoice() {
    computerChoice = rand.nextInt(choices.size());
    System.out.println(computerChoice);
}

回答1:

Your program crashes because RockPaperScissors.class.getResource("Rock.jpg") fails to find the file specified. This also counts for the other images you're attempting to load. Java tries to look for them in the root folder of the project or the same directory as the JAR file when you turn your program into a runnable JAR. As you pointed out, they are in the same folder as the enum.

I'd recommend creating a new folder in the root of your project, called "res", and moving all your image files into that folder. Next, replace:

new ImageIcon(RockPaperScissors.class.getResource("Rock.jpg"))

by:

new ImageIcon("res/Rock.jpg")

And do that for every place where you're loading images.

On an unrelated note, since the icons of the RockPaperScissors enum are not supposed to change, it's better (and easier) to make them public final. Final variables can only be assigned once, and have to be assigned when the object is constructed. They thus act as constants. In code:

public final ImageIcon icon;

private RockPaperScissors(ImageIcon icon) {
    this.icon = icon;
}

And just get rid of the getter and setter, you can now get to the icon field directly.