我提前为创建这个问题道歉,我做.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,不是吗?这里的问题在哪里?
此外,我想再添加一个名为"再次运行"的按钮,您点击它,它关闭当前窗口并打开新窗口(基本上我想再次运行程序),是否可能这样或如何存档它?
您的本地变量正在隐藏实例变量
更改
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);