简体   繁体   English

ActionListener上的java.lang.NullPointerException | Java秋千

[英]java.lang.NullPointerException on ActionListener | Java swing

I do apologize in advance for creating this question, I do .NET so I know "how it feel" to ask this question, but I did search and tried to debug my program in Eclipse and still could not figure-out how to fix it, since I am totally new to Java GUI and first time using Eclipse, so ... 我确实为创建这个问题而道歉,我也做了.NET,所以我知道问这个问题的感觉,但是我确实进行了搜索并尝试在Eclipse中调试我的程序,但仍然找不到解决方法。 ,因为我是Java GUI的新手,并且是第一次使用Eclipse,所以...

I have small program Java swing GUI program, where you have 2 buttons, one of them is hidden (visible set to false) when click on a button, it will shows the hidden button (set Visible to true): 我有一个小程序Java swing GUI程序,其中有2个按钮,其中一个按钮是隐藏的(可见设置为false),当单击一个按钮时,它将显示隐藏的按钮(将Visible设置为true):

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

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

public class TestButton extends JPanel {

    private JFrame mainFrame;
    private JButton btnShow ;
    private JButton btnNew;

    public TestButton() {
        mainFrame = new JFrame("Test Button");

        JButton btnShow = new JButton("Show New Button");
        JButton btnNew = new JButton("This is New Button");

        Container c = mainFrame.getContentPane();
        c.setLayout(new FlowLayout());

        c.add(btnShow);
        c.add(btnNew);
        btnNew.setVisible(false);

        btnShow.setMnemonic('G');
        btnNew.setMnemonic('N');

        mainFrame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        ShowButtonHandler ghandler = new ShowButtonHandler();
        btnShow.addActionListener(ghandler);

        mainFrame.setSize(250, 150);
        mainFrame.setLocationRelativeTo(null);
        mainFrame.setResizable(false);
        mainFrame.setVisible(true);
    }

    class ShowButtonHandler implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            btnNew.setVisible(true);
        }
    }

    public static void main(String args[]) {
        TestButton app = new TestButton();
    }
}

But when I click that button, it shows Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException 但是,当我单击该按钮时,它在线程“ AWT-EventQueue-0” java.lang.NullPointerException中显示异常

The error was at this line: btnNew.setVisible(true); 错误在此行: btnNew.setVisible(true);

Here is the full trace: 这是完整的跟踪:

 Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at TestButton$ShowButtonHandler.actionPerformed(TestButton.java:51)
    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)

So normally Null Exception happens when object was not initialized, but I did initialized the btnNew when declaring it, didn't I? 因此,通常在未初始化对象时发生Null异常,但是我在声明时确实初始化了btnNew,不是吗? Where is the problem here? 问题出在哪里?

Also, I want to add 1 more button called "Run again" where you click on it, it closes current windows and open the new one (Basically I want re run program again) , is it possible that way or how to I archive it? 另外,我想在单击它的位置再添加一个名为“再次运行”的按钮,它会关闭当前窗口并打开新窗口(基本上我想再次运行程序),是否可以通过这种方式或如何对其进行存档?

Your local variable is hiding the instance variable 您的局部变量隐藏了实例变量

Change 更改

JButton btnNew = new JButton("This is New Button");

to

btnNew = new JButton("This is New Button");

EDIT 编辑

According to your question as a comment... but it would be better to ask a new question or post your code at https://codereview.stackexchange.com/ . 根据您的问题作为评论...,但最好提出一个新问题或将代码发布到https://codereview.stackexchange.com/

What I mean is that your inner class ShowButtonHandler depends on the outer class TestButton , because it uses the outer class's field btnNew . 我的意思是您的内部类ShowButtonHandler依赖于外部类TestButton ,因为它使用外部类的字段btnNew

class ShowButtonHandler implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        btnNew.setVisible(true);
    }
}

But this dependency is not necessary. 但是这种依赖性不是必需的。 The ShowButtonHandler only needs a reference to a JButton that it must set visible when an action is performed. ShowButtonHandler仅需要引用一个JButton ,在执行操作时必须将其设置为可见。

So in a first step you can break the dependency to the outer class by simply pass the button as a constructor argument. 因此,第一步,您可以通过简单地将按钮作为构造函数参数传递来打破对外部类的依赖。

class ShowButtonHandler implements ActionListener {

    private JButton btnNew;

    public ShowButtonHandler(JButton btnNew){
        this.btnNew = btnNew;
    }

    public void actionPerformed(ActionEvent e) {
        btnNew.setVisible(true);
    }
}

Now you realize that the ShowButtonHandler could be more flexible to allow reuse. 现在您意识到ShowButtonHandler可以更灵活地允许重用。 You take a look at the class hierarchy and you see that setVisible can be done for any JComponent . 您查看了类层次结构,并看到可以对任何JComponent完成setVisible So you can make the class more general. 因此,您可以使该类更加通用。

class ShowComponentHandler implements ActionListener {

    private JComponent component;

    public ShowComponentHandler(JComponent component){
        this.component = component;
    }

    public void actionPerformed(ActionEvent e) {
        component.setVisible(true);
    }
}

Since the ShowButtonHandler is now independent and has a more general API it can be placed in an own compilation unit (java file) and be re-used. 由于ShowButtonHandler现在是独立的,并且具有更通用的API,因此可以将其放在自己的编译单元(java文件)中并重新使用。

In your TestButton class you can still use it 在您的TestButton类中,您仍然可以使用它

ActionListener showComponentAction = new ShowComponentHandler(btnNew);
btnShow.addActionListener(showComponentAction);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM