基本Java Gui错误:为什么JButton会导致错误?
我的代码编译和看似运行良好,直到我打了JButton,然后我得到了很多错误。我不确定我做错了什么。代码应该做的是有一个窗口出现,并随机显示两个骰子图像,当点击按钮时。这些图像与我的程序位于同一个目录中,它们被命名为1-6。基本Java Gui错误:为什么JButton会导致错误?
下面的代码:
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();
}
}
这里通过点击按钮是我得到的错误:
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)
我不认为你正确生成随机数。当我运行类似的代码来生成随机数字时,我会得到随机数字中包含的一堆零,而这些零数字不会用switch语句处理。
为了安全起见,请导入了java.util.Random包,并作出这样
进口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
,你真的想实现的JFrame是要有建立一个JPanel一个构造方法,然后由主方法调用的方式。看看如何在的Java教程中设置示例程序 - 他们已经获得了一些关于如何构建程序的很好的示例代码。
如果您将程序更改为示例中的结构,那么使用静态JLabel声明的原因将是不必要的,但实际上,如果您声明类变量(如JLabel),则该类的每个实例都是构造将具有它们自己的版本的这些变量。所以,当你在构造方法的外部有一个方法时,即使它们有相同的名称,你也不会在同一个JLabel上工作 - 如果你重写了你的程序,所有这些都是不相关的。
当您构建新对象时,可以完成接口的匿名实现。对于一个动作监听它看起来是这样的:
JButton button = new JButton("Click me!");
button.addActionListener(new ActionListener(){
public void (ActionPerformed ap){
//DO SOMETHING ON CLICK
}
});
我怀疑你是让你的错误的原因是因为你的ActionListener没有对已创建时的构造被称为相同的JLabel工作 - 这这就是为什么我会尝试变量的静态声明或者接口的匿名实现
我忘了补偿1.我纠正了代码。 int firstRoll =(int)(Math.random()* 6)+1;等 – Alex 2014-10-30 02:15:13
我的另一个建议是将JLabels声明为静态的,如果这没有解决问题 – 2014-10-30 02:16:19
另外,你可能想考虑匿名实现动作监听器在diceRoller构造函数中 – 2014-10-30 02:17:41
当我跑步时改变图标时,它抛出异常的代码。看起来你正在加载的图像不存在那里。试着找出,你的相对路径是什么,或者测试事物是否使用绝对路径。
如果您需要更多解释,请填写评论。
希望我能帮上忙。
编辑
一些更多的解释:
应用程序“运行”,在您的硬盘驱动器上的特定位置,说这时候很容易:D要加载的图片。由于你给他的路径不是以斜线开始,它将它们解释为相对路径。这意味着,他查找图像的执行目录。当它以“/”开头时,他将解释为绝对路径,该路径从硬盘驱动器开始。
Here解释了如何获得执行目录。刚创建对象时使用
System.out.println(this.getClass().getProtectionDomain().getCodeSource().getLocation().getPath());
,并检查一下控制台输出,当你开始你的程序。在名为的文件夹中,您必须放置照片。这不建议,但要测试它的工作原理。
EDIT 2
没注意到:
你得到了的JLabel dieOne和dieTwo这里:
private JLabel dieOne;
private JLabel dieTwo;
这些都是可以通过当地隐藏的 “全局” 变量方法中具有相同名称的变量。那是你犯了一个错误。你写:
public DiceSimulator() {
setTitle("Dice Simulator");
JLabel dieOne, dieTwo;
[...]
在那里你隐藏了“全局”dieOne和dieTwo,因为你声明本地的同名。但它们不是必需的,因为你想初始化“全局”JLabels。当你现在这样做时,当完成实例化对象时,dieOne和dieTwo在构造函数中被销毁,而“globals”没有值=>当试图更改文本时,它们没有导致NullPointerException的地址。只要删除
JLabel dieOne, dieTwo;
和所有应该可以。
最后希望一切都很清楚,我可以帮忙。
阅读异常 - 它们不只是给你所有的信息,你知道它的乐趣,它实际上是一个关键的诊断工具。在你的情况下,DiceSimulator.java第57行的内容为null – John3136 2014-10-30 01:51:27
我不知道如何阅读它,我是一个初学者,如果它是其他任何方式,我都不会遇到这个问题。 – Alex 2014-10-30 01:53:45
第57行是什么? – DreadHeadedDeveloper 2014-10-30 01:54:25