单击JFrame上的退出按钮需要关闭JFrame

Posted

技术标签:

【中文标题】单击JFrame上的退出按钮需要关闭JFrame【英文标题】:Need to close JFrame on clicking Exit button on JFrame 【发布时间】:2022-01-18 18:28:28 【问题描述】:

我正在创建一个简单的 Java 应用程序,而且我是 Java 新手。请帮我解决这个问题

我正在使用 java 8,我试图从一个帧移动到另一个帧,我可以这样做,但为此,我在代码中出现了一些异常,我无法弄清楚为什么以及那是什么

下面是我的代码,错误发生在下面。

package oops;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
public class HumanBenchmarkApp implements ActionListener
    JFrame AppWindow, ReflexFrame, VisualFrame, CreditsFrame;
    JLabel Title;
    JButton Game1, Game2, Credits, Exit;
    public HumanBenchmarkApp()
        AppWindow = new JFrame("Human Benchmark");
        AppWindow.setSize(400, 400);
        JPanel Content = new JPanel();
        Content.setBorder(new EmptyBorder(10, 10, 10, 10));
        Content.setLayout(new GridBagLayout());
        try
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        
        catch(Exception e)
            System.err.println(e.getMessage());
        
        AppWindow.setLayout(new BoxLayout(AppWindow.getContentPane(),BoxLayout.Y_AXIS));
        Title = new JLabel("<html><h1><strong>Human Benchmark App</strong></h1><br></html>");
        Game1 = new JButton("<html><h4>Reflex Action Test</h4></html>");
        Game2 = new JButton("<html><h4>Visual Memory Test</h4></html>");
        Credits = new JButton("<html><h4>Credits</h4></html>");
        Exit = new JButton("<html><h4>Exit</h4></html>");
        Game1.addActionListener(this);
        Game2.addActionListener(this);
        Credits.addActionListener(this);
        Exit.addActionListener(this);
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.anchor = GridBagConstraints.NORTH;
        Content.add(Title, gbc);
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        JPanel Buttons = new JPanel(new GridBagLayout());
        Buttons.add(Game1, gbc);
        Buttons.add(Game2, gbc);
        Buttons.add(Credits, gbc);
        Buttons.add(Exit, gbc);
        gbc.weighty = 1;
        Content.add(Buttons);
        AppWindow.add(Content);
        AppWindow.setVisible(true);
        AppWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    public static void main(String[] args)
        new HumanBenchmarkApp();
    
    @Override
    public void actionPerformed(ActionEvent e) 
        JButton clicked = (JButton)e.getSource();
        if (clicked.getName().equals("Game1"))
            
        
        else if(clicked.getName().equals("Game2"))
            
        
        else if(clicked.getName().equals("Credits"))
            
        
        else if(clicked.getName().equals("Exit"))
            System.exit(0);
        
    

这是我的代码,当我执行它时,NetBeans 输出区域出现以下错误。

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at oops.HumanBenchmarkApp.actionPerformed(HumanBenchmarkApp.java:56)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
    at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
    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:6539)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
    at java.awt.Component.processEvent(Component.java:6304)
    at java.awt.Container.processEvent(Container.java:2239)
    at java.awt.Component.dispatchEventImpl(Component.java:4889)
    at java.awt.Container.dispatchEventImpl(Container.java:2297)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4904)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4535)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4476)
    at java.awt.Container.dispatchEventImpl(Container.java:2283)
    at java.awt.Window.dispatchEventImpl(Window.java:2746)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:760)
    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$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:84)
    at java.awt.EventQueue$4.run(EventQueue.java:733)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:74)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:730)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:205)
    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)

控制台出现错误,JFrame 甚至没有关闭。

【问题讨论】:

我很确定你应该使用 getText() 而不是 getName()。 getName() 返回从不显示在窗口中的 internal 文本,默认为 null。也就是说,Agzam 的建议比使用一种大型 actionPerformed 方法要好。 不,兄弟,我只需要在帧之间切换的内部文本 请不要通过破坏您的帖子为他人增加工作量。通过在 Stack Exchange 网络上发帖,您已在 CC BY-SA 4.0 license 下授予 Stack Exchange 分发该内容的不可撤销的权利(即无论您未来的选择如何)。根据 Stack Exchange 政策,帖子的非破坏版本是分发的版本。因此,任何破坏行为都将被撤销。如果您想了解更多关于删除帖子的信息,请参阅:How does deleting work? 【参考方案1】:

如果你可以使用 lambda 表达式,我真的不明白为什么 ActionListener 的实现如此令人困惑:

        ...

        Game1.addActionListener(this);
        Game2.addActionListener(this);
        Credits.addActionListener(this);
        Exit.addActionListener(e ->    // <---- NEW HERE
            System.exit(0);             // <---- NEW HERE
        );                             // <---- NEW HERE
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.anchor = GridBagConstraints.NORTH;
        Content.add(Title, gbc);
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        JPanel Buttons = new JPanel(new GridBagLayout());

        ...

编辑:

或者你可以这样做:

Exit.addActionListener(new ActionListener() 
            
    @Override
    public void actionPerformed(ActionEvent arg0) 
        System.exit(0); 
    
);

或: 您不必比较名称,您可以比较对象引用:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class HumanBenchmarkApp implements ActionListener 
    
    JFrame appWindow, reflexFrame, visualFrame, creditsFrame;
    JLabel title;
    JButton game1, game2, credits, exit;
    
    public HumanBenchmarkApp() 
        appWindow = new JFrame("Human Benchmark");
        appWindow.setSize(400, 400);
        JPanel content = new JPanel();
        content.setBorder(new EmptyBorder(10, 10, 10, 10));
        content.setLayout(new GridBagLayout());
        try
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        
        catch(Exception e)
            System.err.println(e.getMessage());
        
        appWindow.setLayout(new BoxLayout(appWindow.getContentPane(),BoxLayout.Y_AXIS));
        title = new JLabel("<html><h1><strong>Human Benchmark App</strong></h1><br></html>");
        game1 = new JButton("<html><h4>Reflex Action Test</h4></html>");
        game2 = new JButton("<html><h4>Visual Memory Test</h4></html>");
        credits = new JButton("<html><h4>Credits</h4></html>");
        exit = new JButton("<html><h4>Exit</h4></html>");
        game1.addActionListener(this);
        game2.addActionListener(this);
        credits.addActionListener(this);
        exit.addActionListener(this);
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.anchor = GridBagConstraints.NORTH;
        content.add(title, gbc);
        gbc.anchor = GridBagConstraints.CENTER;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        JPanel Buttons = new JPanel(new GridBagLayout());
        Buttons.add(game1, gbc);
        Buttons.add(game2, gbc);
        Buttons.add(credits, gbc);
        Buttons.add(exit, gbc);
        gbc.weighty = 1;
        content.add(Buttons);
        appWindow.add(content);
        appWindow.setVisible(true);
        appWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    
    public static void main(String[] args) 
        new HumanBenchmarkApp();
    
    
    @Override
    public void actionPerformed(ActionEvent e) 
        JButton clicked = (JButton)e.getSource();
        if (clicked == game1) 

        
        else if(clicked == game2) 

        
        else if(clicked == credits) 

        
        else if(clicked == exit) 
            System.exit(0);
        
    

【讨论】:

完美!!!! @Agzam 我听说过 lambda 表达式,但我们的老师没有教我们这些,所以我用基本的简单实现做了 @20CSE028 Afsal Baaqir A,我已编辑答案并添加了 2 个变体【参考方案2】:

问题是您的按钮退出的名称不是“退出”。这是你的代码:

Exit = new JButton("<html><h4>Exit</h4></html>");

相反,您可以比较退出和单击是否与 Agzam 描述的按钮相同。

    @Override
    public void actionPerformed(ActionEvent e) 
        JButton clicked = (JButton)e.getSource();
        if (clicked == game1) 

        
        else if(clicked == game2) 

        
        else if(clicked == credits) 

        
        else if(clicked == exit) 
            System.exit(0);
        
    

【讨论】:

以上是关于单击JFrame上的退出按钮需要关闭JFrame的主要内容,如果未能解决你的问题,请参考以下文章

如何捕获 JFrame 的关闭按钮单击事件?

如何捕获JFrame的关闭按钮单击事件?

双击图标时关闭JFrame

Java - 关闭 JFrame 窗口时的消息

groovy关闭JFrame窗口的方式与用户单击xclose窗口按钮的方式相同

JFrame关闭方法的问题