ActionListener上的java.lang.NullPointerException | Java摇摆

时间:2014-10-02 17:55:39

标签: java swing actionlistener

我提前为创建这个问题道歉,我做.NET所以我知道"感觉如何"问这个问题,但是我确实搜索过并尝试在Eclipse中调试我的程序,但仍然无法弄清楚如何修复它,因为我是Java GUI的新手,第一次使用Eclipse,所以......

我有一个小程序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();
    }
}

但是当我点击该按钮时,它会显示线程中的异常" AWT-EventQueue-0"显示java.lang.NullPointerException

错误发生在这一行: btnNew.setVisible(true);

以下是完整的跟踪:

 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)

所以通常在对象未初始化时发生Null Exception,但是在声明它时我确实初始化了btnNew,不是吗?这里的问题在哪里?

另外,我想再添加一个名为&#34的按钮;再次运行"你点击它,它关闭当前窗口并打开新窗口(基本上我想再次运行程序),是否可能这样或如何存档?

1 个答案:

答案 0 :(得分:5)

您的本地变量正在隐藏实例变量

更改

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

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

编辑

根据您的问题作为评论...但最好在https://codereview.stackexchange.com/提出新问题或发布您的代码。

我的意思是你的内部课程ShowButtonHandler取决于外部课程TestButton,因为它使用外部课程的btnNew字段。

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

但这种依赖性并不是必需的。 ShowButtonHandler只需要对JButton的引用,它必须在执行操作时设置为可见。

因此,在第一步中,您可以通过简单地将按钮作为构造函数参数传递来打破对外部类的依赖。

class ShowButtonHandler implements ActionListener {

    private JButton btnNew;

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

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

现在您意识到ShowButtonHandler可以更灵活地允许重用。您可以查看类层次结构,并看到可以为任何setVisible执行JComponent。所以你可以让课程更通用。

class ShowComponentHandler implements ActionListener {

    private JComponent component;

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

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

由于ShowButtonHandler现在是独立的并且具有更通用的API,因此可以将其放置在自己的编译单元(java文件)中并重新使用。

TestButton课程中,您仍然可以使用

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