我为创建这个问题提前道歉,我是 .NET 的所以我知道问这个问题的“感觉”,但我确实搜索并尝试在 Eclipse 中调试我的程序但仍然无法弄清楚如何修复它,因为我是 Java GUI 的新手并且是第一次使用 Eclipse,所以 ...
我有一个小程序 Java swing GUI 程序,其中有 2 个按钮,其中一个是隐藏的(可见设置为 false)当单击一个按钮时,它会显示隐藏按钮(将可见设置为真):
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();
}
}
但是当我点击那个按钮时,它显示 Exception in thread "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)
所以通常在对象未初始化时会发生空异常,但我在声明它时确实初始化了 btnNew,不是吗?问题出在哪里?
此外,我想再添加 1 个名为“再次运行”的按钮,您可以在点击它的地方关闭当前窗口并打开新窗口(基本上我想再次重新运行程序),是否可以这样或如何我存档了吗?
最佳答案
你的局部变量隐藏了实例变量
改变
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
可以更灵活地允许重用。查看类层次结构,您会发现可以为任何 JComponent
完成 setVisible
。因此,您可以使类(class)更通用。
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);
关于ActionListener 上的 java.lang.NullPointerException | Java Swing ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26166639/