如何防止关闭 JDialog 会关闭整个应用程序
How to prevent that closing a JDialog closes the entire application
我有一个主(屏幕)图形用户界面 window 并且需要打开一些 "multi input" windows(jdialog 或在不可能时使用 jframe),例如添加首选项 (4带有 2 个文件选择器和 2 个单选按钮的文本字段)。
在这些 JDialogs(或 JFrames)中按 OK/Cancel 时,我的整个应用程序将关闭。
我不想要那个。我怎样才能避免这种情况?
第一次尝试:我尝试了 intelliJ 选项 "New -> Create Dialog class",它给了我一个带有 OK/Cancel 按钮的 JDialog。按其中一个按钮将关闭 JDialog 和我的整个应用程序。
第二次尝试:我写了一个 class "by hand",它创建了一个 JDialog(也尝试了 JFrame)。再次说明:按下其中一个按钮将关闭 JDialog 和我的整个应用程序。
我从 JDialog (JFrame) 中删除了 "dispose()" 和 "setVisible(false)" 选项,但我的整个应用程序仍然关闭。
主要class方法
public class mainScreen {
// Menu action listener (only relevant options)
class MenuActionListener implements ActionListener {
// menuListener
public void actionPerformed(ActionEvent ev) {
//myVariables myVars = new myVariables();
String[] dummy = null;
System.out.println("Selected: " + ev.getActionCommand());
switch(ev.getActionCommand()) {
case "Preferences":
showPreferencesDialog();
case "Exit":
System.exit(0);
break;
}
// method that opens the external class (see below in following code block)
private void showPreferencesDialog() {
prefJDialog myprefs = new prefJDialog(prefsPanel);
myprefs.showDialog();
boolean okPressed = myprefs.isOkPressed();
if (okPressed) {
JOptionPane.showMessageDialog(mainScreen.this.rootPanel,"OK pressed","About jExifToolGUI",JOptionPane.INFORMATION_MESSAGE);
} else {
JOptionPane.showMessageDialog(mainScreen.this.rootPanel,"Cancel pressed","About jExifToolGUI",JOptionPane.INFORMATION_MESSAGE);
}
}
// This is the class which is mention in the manifest
public mainScreen(JFrame frame) {
boolean preferences = false;
Preferences prefs = Preferences.userRoot();
createmyMenuBar(frame);
groupRadiobuttonsandListen();
fileNamesTableListener();
try {
myUtils.DisplayLogo(mainScreen.this.iconLabel);
} catch(IOException ex) {
System.out.println("Error reading Logo");
}
preferences = check_preferences();
if (!preferences) {
myUtils.checkExifTool(mainScreen.this.rootPanel);
}
programButtonListeners();
}
// main method in my main class for my project
public static void main(String[] args) {
JFrame frame = new JFrame("jExifToolGUI");
frame.setContentPane(new mainScreen(frame).rootPanel);
//frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
从主class
调用的JDialog class/method
package org.hvdw.jexiftoolgui;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class prefJDialog extends JDialog {
private JButton okButton;
private JButton cancelButton;
private JPanel prefsPanel;
private boolean okPressed;
public prefJDialog(JPanel prefsPanel) {
super(JOptionPane.getFrameForComponent(prefsPanel), true);
this.prefsPanel = prefsPanel;
setTitle("Preferences");
initDialog();
}
public void showDialog() {
setSize(800, 768);
double x = getParent().getBounds().getCenterX();
double y = getParent().getBounds().getCenterY();
setLocation((int) x - getWidth() / 2, (int) y - getHeight() / 2);
setVisible(true);
}
private void initDialog() {
JPanel pane = new JPanel();
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
pane.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10));
add(pane);
pane.add(Box.createVerticalGlue());
FlowLayout l = new FlowLayout(FlowLayout.RIGHT);
JPanel buttonsPane = new JPanel(l);
okButton = new JButton("Save"); //$NON-NLS-1$
buttonsPane.add(okButton);
pane.getRootPane().setDefaultButton(okButton);
cancelButton = new JButton("CANCEL"); //$NON-NLS-1$
buttonsPane.add(cancelButton);
buttonsPane.setMaximumSize(new Dimension(Short.MAX_VALUE, (int) l.preferredLayoutSize(buttonsPane).getHeight()));
pane.add(buttonsPane);
addListeners();
}
private void addListeners() {
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//saveProperties();
setVisible(false);
okPressed = true;
//close();
// dispose();
}
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
//dispose();
//close();
okPressed = false;
}
});
}
public boolean isOkPressed() {
return okPressed;
}
/*public void close() {
WindowEvent winClosingEvent = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(winClosingEvent);
}*/
}
那么如何防止在 JDialog 中单击“确定”或“取消”时整个应用程序关闭。它需要保持打开状态,直到用户单击右上角的 "window close" X,或从菜单 "File -> Exit"
我已经搜索 Google 几天了,但找不到解决方案(还有一个相同的问题没有答案)。
编辑:
在帕特里克的回答后,我将关闭方法更改为
public void close() {
this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
}
并删除了 /* 和 */。
我还激活了 close();再次在听众中,但这并没有什么不同。我的主应用程序仍然关闭。
switch(ev.getActionCommand()) {
case "Preferences":
showPreferencesDialog();
case "Exit":
System.exit(0);
break;
问题是您的 switch case 中没有 break
语句,因此代码会进入 "Exit" 逻辑并执行 System.exit(0)
这就是为什么我们每个问题都需要一个适当的 "MCVE"。当您 post 随机代码片段时,我们看不到整个逻辑流程。
我有一个主(屏幕)图形用户界面 window 并且需要打开一些 "multi input" windows(jdialog 或在不可能时使用 jframe),例如添加首选项 (4带有 2 个文件选择器和 2 个单选按钮的文本字段)。 在这些 JDialogs(或 JFrames)中按 OK/Cancel 时,我的整个应用程序将关闭。 我不想要那个。我怎样才能避免这种情况?
第一次尝试:我尝试了 intelliJ 选项 "New -> Create Dialog class",它给了我一个带有 OK/Cancel 按钮的 JDialog。按其中一个按钮将关闭 JDialog 和我的整个应用程序。
第二次尝试:我写了一个 class "by hand",它创建了一个 JDialog(也尝试了 JFrame)。再次说明:按下其中一个按钮将关闭 JDialog 和我的整个应用程序。
我从 JDialog (JFrame) 中删除了 "dispose()" 和 "setVisible(false)" 选项,但我的整个应用程序仍然关闭。
主要class方法
public class mainScreen {
// Menu action listener (only relevant options)
class MenuActionListener implements ActionListener {
// menuListener
public void actionPerformed(ActionEvent ev) {
//myVariables myVars = new myVariables();
String[] dummy = null;
System.out.println("Selected: " + ev.getActionCommand());
switch(ev.getActionCommand()) {
case "Preferences":
showPreferencesDialog();
case "Exit":
System.exit(0);
break;
}
// method that opens the external class (see below in following code block)
private void showPreferencesDialog() {
prefJDialog myprefs = new prefJDialog(prefsPanel);
myprefs.showDialog();
boolean okPressed = myprefs.isOkPressed();
if (okPressed) {
JOptionPane.showMessageDialog(mainScreen.this.rootPanel,"OK pressed","About jExifToolGUI",JOptionPane.INFORMATION_MESSAGE);
} else {
JOptionPane.showMessageDialog(mainScreen.this.rootPanel,"Cancel pressed","About jExifToolGUI",JOptionPane.INFORMATION_MESSAGE);
}
}
// This is the class which is mention in the manifest
public mainScreen(JFrame frame) {
boolean preferences = false;
Preferences prefs = Preferences.userRoot();
createmyMenuBar(frame);
groupRadiobuttonsandListen();
fileNamesTableListener();
try {
myUtils.DisplayLogo(mainScreen.this.iconLabel);
} catch(IOException ex) {
System.out.println("Error reading Logo");
}
preferences = check_preferences();
if (!preferences) {
myUtils.checkExifTool(mainScreen.this.rootPanel);
}
programButtonListeners();
}
// main method in my main class for my project
public static void main(String[] args) {
JFrame frame = new JFrame("jExifToolGUI");
frame.setContentPane(new mainScreen(frame).rootPanel);
//frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
从主class
调用的JDialog class/methodpackage org.hvdw.jexiftoolgui;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class prefJDialog extends JDialog {
private JButton okButton;
private JButton cancelButton;
private JPanel prefsPanel;
private boolean okPressed;
public prefJDialog(JPanel prefsPanel) {
super(JOptionPane.getFrameForComponent(prefsPanel), true);
this.prefsPanel = prefsPanel;
setTitle("Preferences");
initDialog();
}
public void showDialog() {
setSize(800, 768);
double x = getParent().getBounds().getCenterX();
double y = getParent().getBounds().getCenterY();
setLocation((int) x - getWidth() / 2, (int) y - getHeight() / 2);
setVisible(true);
}
private void initDialog() {
JPanel pane = new JPanel();
pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
pane.setBorder(BorderFactory.createEmptyBorder(10, 10, 5, 10));
add(pane);
pane.add(Box.createVerticalGlue());
FlowLayout l = new FlowLayout(FlowLayout.RIGHT);
JPanel buttonsPane = new JPanel(l);
okButton = new JButton("Save"); //$NON-NLS-1$
buttonsPane.add(okButton);
pane.getRootPane().setDefaultButton(okButton);
cancelButton = new JButton("CANCEL"); //$NON-NLS-1$
buttonsPane.add(cancelButton);
buttonsPane.setMaximumSize(new Dimension(Short.MAX_VALUE, (int) l.preferredLayoutSize(buttonsPane).getHeight()));
pane.add(buttonsPane);
addListeners();
}
private void addListeners() {
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//saveProperties();
setVisible(false);
okPressed = true;
//close();
// dispose();
}
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setVisible(false);
//dispose();
//close();
okPressed = false;
}
});
}
public boolean isOkPressed() {
return okPressed;
}
/*public void close() {
WindowEvent winClosingEvent = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(winClosingEvent);
}*/
}
那么如何防止在 JDialog 中单击“确定”或“取消”时整个应用程序关闭。它需要保持打开状态,直到用户单击右上角的 "window close" X,或从菜单 "File -> Exit"
我已经搜索 Google 几天了,但找不到解决方案(还有一个相同的问题没有答案)。
编辑: 在帕特里克的回答后,我将关闭方法更改为
public void close() {
this.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
}
并删除了 /* 和 */。 我还激活了 close();再次在听众中,但这并没有什么不同。我的主应用程序仍然关闭。
switch(ev.getActionCommand()) {
case "Preferences":
showPreferencesDialog();
case "Exit":
System.exit(0);
break;
问题是您的 switch case 中没有 break
语句,因此代码会进入 "Exit" 逻辑并执行 System.exit(0)
这就是为什么我们每个问题都需要一个适当的 "MCVE"。当您 post 随机代码片段时,我们看不到整个逻辑流程。