我目前正在开发一个简单的GUI应用程序,可以滚动两个骰子。我目前正在使用两个类,一个叫“Game”,另一个叫“DiceRoll”。为了满足分配标准,我们必须使用多个类才能使程序正常工作。使用一个类会容易得多......无论如何,我在我的“DiceRoll”类中成功调用了我的“roll()”方法,该类使用switch语句并按顺序实现“Graphics.drawImage()”方法绘制指定的“.png”图像。一切都很好,我跑之前没有错误。当我运行程序时,弹出GUI框架,我创建的所有按钮/菜单都正常工作。但是,一旦我按下“掷骰子”按钮,我就会一直收到多个运行时错误。 这就是我到目前为止所做的:
游戏类
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;
}
}
我收到的错误
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)
答案 0 :(得分:2)
您在此处传递null
:
dr.roll(die1);
dr.roll(die2);
由于您从未实例化die1
和die2
,因此您获得 NullPointerException 。
答案 1 :(得分:1)
我认为你做的比这更复杂。为什么不更改public Graphics roll(Graphics g)
方法来计算滚动并更新JLabel
,就像这样......
public void roll(JLabel dieLabel) {
int dieResult = (int)(6 * Math.random());
dieLabel.setIcon(new ImageIcon("die" + dieResult + ".png"))
}
然后您需要做的就是在这里更改代码......
if (e.getSource() == rollDice){
dr.roll(die1);
dr.roll(die2);
diceLabel.updateUI();
dicePanel.updateUI();
}
发送您想要更改的标签,例如......
if (e.getSource() == rollDice){
dr.roll(diceLabel);
dr.roll(diceLabel2);
}
您将JLabel
传递给roll()
方法,该方法计算滚动并在该标签上设置图像。更简单。
这也意味着您不需要2 Graphics
个对象(die1
和die2
),因此您可以摆脱这些。您也不需要BufferedImages
,因为图像文件的加载是由ImageIcon
类
如果您需要有关我的建议的任何进一步信息,请出于学习目的告诉我。
编辑...
这是我对您的Game()
构造函数的重写,其中显示了如何使用JPanels
和GridLayout
作为布局管理器向BorderLayout
添加项目...... < / p>
public Game(){
// Set the JFrame properties
setTitle("Rollin' Dice");
this.setPreferredSize(new Dimension(600,600));
// Create the main JPanel to hold the interface
mainPanel = new JPanel(new BorderLayout());
// Build the Menu
options = new JMenu("Options");
quit = new JMenuItem("Quit");
options.add(quit);
explanation = new JMenuItem("Explanation");
options.add(explanation);
menuBar = new JMenuBar();
menuBar.add(options);
// Add the menu to the top of the main panel
mainPanel.add(menuBar,BorderLayout.NORTH);
// Create the dice
dr = new DiceRoll();
diceLabel = new JLabel();
diceLabel2 = new JLabel();
dicePanel = new JPanel(new GridLayout(2,1));
dicePanel.add(diceLabel);
dicePanel.add(diceLabel2);
// Add the dicePanel to the center of the main panel
mainPanel.add(dicePanel,BorderLayout.CENTER);
// Add the rollDice button to the bottom of the main panel
rollDice = new JButton("Roll Dice");
mainPanel.add(rollDice,BorderLayout.SOUTH);
// Add listeners to the menu items and buttons
quit.addActionListener(this);
explanation.addActionListener(this);
rollDice.addActionListener(this);
// Add the main panel to the JFrame
this.getContentPane().add(mainPanel);
// Show the JFrame
this.pack();
this.setVisible(true);
}