Swing:退出应用程序actionListener

时间:2017-09-18 06:44:01

标签: java swing

我想弄清楚如何通过按钮点击退出应用程序。 我面临的问题使我无法退出应用程序是因为我正在使用"扩展JFRame"来自主要班级。

例如,

app.class

public class app{
  public static void main(String[] args){
   SwingUtilities.invokeLater(new Runnable(){
   public void run(){
   JFrame frame = new MainFrame("Exercise one");
   frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
   .. .. ..
   frame.setVisible(true); 
   })
  }
}

MainFrame.java

public class MainFrame extends JFrame(){
 public MainFrame(String title){
  super(title)

      //set layout manager
      setLayout(new BorderLayout());

     //swing components
    JButton exit = new JButton("Exit");

    //add container 
    Container container = getContentPane();

    container.add(exit);

   //create actionlist logic 
    exit.addActionListener(new ActionListener()){
    @Override 
    public void actionPerformed(ActionEvent arg0){
          // on click , this logic will end the application
     }
    }

  }
}

我完全理解如何从app类取消应用程序。但是在我想要从MainFrame取消应用程序的情况下,可以完成它吗?

提前谢谢。

3 个答案:

答案 0 :(得分:1)

defaultCloseOperation仅在遇到WINDOW_CLOSING事件时由框架处理,setVisibledispose都不会触发此事件,这意味着defaultCloseOperation没有被处理

确保触发此操作的唯一方法是手动调度WINDOW_CLOSING事件

frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));

希望遵循此路径的一个主要原因是它确保应用程序遵循已配置的defaultCloseOperation并自己构思(如手动调用System.exit)< / p>

以下说明隐藏,处置和调度方法。只有调度方法才会关闭窗口并终止JVM

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.AbstractAction;
import static javax.swing.Action.NAME;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                frame.setLayout(new GridBagLayout());
                GridBagConstraints gbc = new GridBagConstraints();
                gbc.gridwidth = GridBagConstraints.REMAINDER;
                gbc.fill = GridBagConstraints.HORIZONTAL;

                frame.add(new JButton(new HideAction(frame)), gbc);
                frame.add(new JButton(new DisposeAction(frame)), gbc);
                frame.add(new JButton(new DispatchAction(frame)), gbc);
                frame.addWindowListener(new WindowAdapter() {
                    @Override
                    public void windowClosing(WindowEvent e) {
                        System.out.println("Closing");
                    }

                    @Override
                    public void windowClosed(WindowEvent e) {
                        System.out.println("Closed");
                    }
                });
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class HideAction extends AbstractAction {

        private JFrame frame;

        public HideAction(JFrame frame) {
            this.frame = frame;
            putValue(NAME, "Hide");
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            frame.setVisible(false);
        }

    }

    public class DisposeAction extends AbstractAction {

        private JFrame frame;

        public DisposeAction(JFrame frame) {
            this.frame = frame;
            putValue(NAME, "Dispose");
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            frame.dispose();
        }

    }

    public class DispatchAction extends AbstractAction {

        private JFrame frame;

        public DispatchAction(JFrame frame) {
            this.frame = frame;
            putValue(NAME, "Dispatch");
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            frame.dispatchEvent(new WindowEvent(frame, WindowEvent.WINDOW_CLOSING));
        }

    }
}

如果我在IDE中运行它,除非我使用dispatch选项,否则JVM将继续运行,我必须终止会话以完全关闭它。

我还注意到,调用dispose只会触发WINDOW_CLOSED事件,而调度方法会触发WINDOW_CLOSING事件

答案 1 :(得分:0)

问题解决了。 致@XtremeBaumer。

基本上,当使用&#34; classname&#34;扩展JFRame。 我们可以输入dispose()来完全杀死应用程序。这将导致JFrame窗口被操作系统销毁和清理。 :)

答案 2 :(得分:0)

确实,dispose()是正确的解决方案。我还建议添加一个pack()调用,以便UI正确显示:

public class MainFrame extends JFrame {
    public MainFrame(String title) {
        super(title);

        ...

        // create actionlist logic
        exit.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {
                System.out.println("--> closing app programmatically");
                MainFrame.this.dispose();
            }
        });
        this.pack();

    }
}

您可以使用WindowListener上的MainFrame来测试事件。调用它们就像用户按下关闭按钮一样:

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            JFrame frame = new MainFrame("Exercise one");
            frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
            // .. .. ..
            frame.setVisible(true);
            frame.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    System.out.println("--> closing...");
                }

                public void windowClosed(WindowEvent e) {
                    System.out.println("--> closed...");
                }
            });
        }
    });
}