尝试使用自定义JPanel中的方法时发生NullPointerException [英] NullPointerException when trying to use method from custom JPanel

查看:165
本文介绍了尝试使用自定义JPanel中的方法时发生NullPointerException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为我创建的游戏创建GUI,而在运行它时遇到了一个小问题.

I am trying to make a GUI for my game I created a while back, and I am running into a slight issue while running it.

我想将输出打印到扩展JPanel中的JTextField.但是,当我运行它时,它会出现以下错误:

I want to have the output print to a JTextField in an extended JPanel. However, when I run it, it comes up with this error:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at Classic.print(Classic.java:509)
    at Classic.play(Classic.java:43)
    at Karma.actionPerformed(Karma.java:134)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2346)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252)
at java.awt.Component.processMouseEvent(Component.java:6525)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
at java.awt.Component.processEvent(Component.java:6290)
at java.awt.Container.processEvent(Container.java:2234)
at java.awt.Component.dispatchEventImpl(Component.java:4881)
at java.awt.Container.dispatchEventImpl(Container.java:2292)
at java.awt.Component.dispatchEvent(Component.java:4703)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4533)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
at java.awt.Container.dispatchEventImpl(Container.java:2278)
at java.awt.Window.dispatchEventImpl(Window.java:2750)
at java.awt.Component.dispatchEvent(Component.java:4703)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
at java.awt.EventQueue.access$500(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:709)
at java.awt.EventQueue$3.run(EventQueue.java:703)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:731)
at java.awt.EventQueue$4.run(EventQueue.java:729)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

以下是适用的代码:

(我将跳过Karma.java:134,因为这只是播放按钮.)

(I will skip Karma.java:134 since this is just the play button.)

Classic.java

Classic.java

import static javax.swing.SwingUtilities.invokeLater; //This is to show where invokeLater comes from
...
public class Classic extends Game {
    private static JFrame gui;
    private static GUIClassic newContentPane;
    ...
    public void play() {
        invokeLater(Classic::startGUI);
        //The next line is "Classic.java:43
        //length, difficulty, and log are all strings that were initialized when the game was instantiated
        print("Selected Options:\nLength: " + length + "\nDifficulty: " + difficulty + "\nOutput Log? " + log + "\n");
        ...
    }
    private static void startGUI() {
        gui = new JFrame("Karma :: Classic Mode");
        gui.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        newContentPane = new GUIClassic();
        newContentPane.setOpaque(true);
        gui.setContentPane(newContentPane);
        gui.pack();
        gui.setVisible(true);
    }
    private static void print(String text) {
        newContentPane.appendOutput(text);
    }

GUIClassic.java(用于内容窗格的类)

GUIClassic.java (The class used for the content pane)

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class GUIClassic extends JPanel implements ActionListener {
    private JTextArea output;
    private JTextField input;
    private boolean inputReady;
    private String inputText;
    public GUIClassic() {
        super();
        setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
        output = new JTextArea(15, 15);
        output.setEditable(false);
        JScrollPane outputScroll = new JScrollPane(output);
        input = new JTextField("",40);
        add(outputScroll);
        add(Box.createRigidArea(new Dimension(0,5)));
        add(input);
    }
    public void actionPerformed(ActionEvent e) {
        inputText = input.getText();
        inputReady = true;
        input.setText("");
    }
    public boolean isInputReady() {
        return inputReady;
    }
    public String getInput() {
        if (!isInputReady())
            return null;
        inputReady = false;
        return inputText;
    }
    public void appendOutput(String addition) {
        output.append(addition + "\n");
    }
}

有趣的是,在异常发生后,GUI确实会弹出并停留.它只是不将输出打印到JTextArea并卡住.

Interestingly enough, the GUI does pop up and stay up after the exception occurs. It just doesn't print the output to the JTextArea and gets stuck.

如果您需要更多的上下文代码,请告诉我,我将添加它.

If you need more code for context, let me know please and I will add it.

有些人指出某些字段可能未初始化.我相应地解决了这些问题.我试图弄清楚到底是什么引起了异常,但是失败了.不应是"newContentPane"或输出",因为它们在程序启动时都出现在屏幕上.

Some have pointed out that certain fields may not be initialized. I addressed those accordingly. I tried figuring out exactly what was causing the exception, but failed. It shouldn't be 'newContentPane' or 'output' because those both appear on the screen when the program starts.

推荐答案

检查一下,这是您的错误:

Check this out, here's your error:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException at Classic.print(Classic.java:509)

这是您的Classic#print

private static void print(String text) {
    newContentPane.appendOutput(text);
}

在这里,唯一会抛出 NullPointerExceptionnewContentPane等于null的时间.

Here, the only scenario that would throw a NullPointerException is when newContentPane equalsnull.

是的,您可能有一些代码可以初始化newContentPane,但是在调用Classic#print之前不会及时发生.

Yes, you might have some code that initializes newContentPane, but its not happening in time before your call to Classic#print.

那么,为什么不及时发生呢?就像每个人都想告诉您的一样,这与使用invokeLater有关.

So, why isn't it happening in time? Like what everyone's been trying to tell you, it has to do with the use of invokeLater.

这篇关于尝试使用自定义JPanel中的方法时发生NullPointerException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆