我想弄清楚如何通过按钮点击退出应用程序。 我面临的问题使我无法退出应用程序是因为我正在使用"扩展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取消应用程序的情况下,可以完成它吗?
提前谢谢。
答案 0 :(得分:1)
defaultCloseOperation
仅在遇到WINDOW_CLOSING
事件时由框架处理,setVisible
或dispose
都不会触发此事件,这意味着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...");
}
});
}
});
}