Java Jframe中2个Jdialogs的setModal问题
当我将第一个Java Jframe中2个Jdialogs的setModal问题,java,swing,modal-dialog,jframe,jdialog,Java,Swing,Modal Dialog,Jframe,Jdialog,当我将第一个JDialog设置为模态,第二个设置为非模态时,我面临着一些问题 这是我正在尝试实现的功能: 单击“测试对话框!”按钮,将出现一个名为自定义对话框的JDialog 主管道将打开 如果单击自定义对话框主菜单中的“是”选项,则另一个 JDialog命名自定义对话框搜索将打开 如果在自定义对话框搜索中单击“是”选项,则 自定义主对话框应该放在前面 我应该能够选择任何JDialog。例如,如果我选择 自定义对话框搜索,另一个对话框应转到 反之亦然 我面临的问题是,当我在自定义对话框主对话框中
JDialog
设置为模态,第二个设置为非模态时,我面临着一些问题
这是我正在尝试实现的功能:
JDialog
主管道将打开JDialog
命名自定义对话框搜索将打开JDialog
。例如,如果我选择
自定义对话框搜索,另一个对话框应转到
反之亦然import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JButton;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.ActionEvent;
import java.awt.Dimension;
public class TestTheDialog implements ActionListener {
JFrame mainFrame = null;
JButton myButton = null;
public TestTheDialog() {
mainFrame = new JFrame("TestTheDialog Tester");
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {System.exit(0);}
});
myButton = new JButton("Test the dialog!");
myButton.addActionListener(this);
mainFrame.setLocationRelativeTo(null);
mainFrame.getContentPane().add(myButton);
mainFrame.pack();
mainFrame.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(myButton == e.getSource()) {
System.err.println("Opening dialog.");
CustomDialog myDialog = new CustomDialog(mainFrame, true, "Custom Dialog Main?");
System.err.println("After opening dialog.");
if(myDialog.getAnswer()) {
System.err.println("The answer stored in CustomDialog is 'true' (i.e. user clicked yes button.)");
}
else {
System.err.println("The answer stored in CustomDialog is 'false' (i.e. user clicked no button.)");
}
}
}
public static void main(String argv[]) {
TestTheDialog tester = new TestTheDialog();
}
}
import javax.swing.JDialog;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionEvent;
public class CustomDialog extends JDialog implements ActionListener {
private JPanel myPanel = null;
private JButton yesButton = null;
private JButton noButton = null;
private boolean answer = false;
private JFrame parentFrame;
public boolean getAnswer() { return answer; }
public CustomDialog(JFrame frame, boolean modal, String myMessage) {
super(frame, modal);
parentFrame = frame;
myPanel = new JPanel();
getContentPane().add(myPanel);
myPanel.add(new JLabel(myMessage));
yesButton = new JButton("Yes");
yesButton.addActionListener(this);
myPanel.add(yesButton);
noButton = new JButton("No");
noButton.addActionListener(this);
myPanel.add(noButton);
pack();
setLocationRelativeTo(frame);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(yesButton == e.getSource()) {
CustomDialogSearch myDialog = new CustomDialogSearch(parentFrame, false, "CustomDialog Search?");
System.err.println("User chose yes.");
answer = true;
myDialog.getAnswer();
System.out.println("myDialog.getAnswer()="+myDialog.getAnswer());
myDialog.show();
if(myDialog.getAnswer()==true)
{
System.out.println("tofront");
this.toFront();
}
//setVisible(false);
}
else if(noButton == e.getSource()) {
System.err.println("User chose no.");
answer = false;
setVisible(false);
}
}
}
import javax.swing.JDialog;
import java.awt.event.ActionListener;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;
import java.awt.event.ActionEvent;
public class CustomDialogSearch extends JDialog implements ActionListener {
private JPanel myPanel = null;
private JButton yesButton = null;
private JButton noButton = null;
private boolean answer = false;
public boolean getAnswer() { return answer; }
public CustomDialogSearch(JFrame frame, boolean modal, String myMessage) {
super(frame, modal);
myPanel = new JPanel();
getContentPane().add(myPanel);
myPanel.add(new JLabel(myMessage));
yesButton = new JButton("Yes");
yesButton.addActionListener(this);
myPanel.add(yesButton);
noButton = new JButton("No");
noButton.addActionListener(this);
myPanel.add(noButton);
pack();
setLocationRelativeTo(frame);
setVisible(true);
}
public void actionPerformed(ActionEvent e) {
if(yesButton == e.getSource()) {
System.err.println("Search User chose yes.");
answer = true;
//setVisible(false);
}
else if(noButton == e.getSource()) {
System.err.println("Search User chose no.");
answer = false;
setVisible(false);
}
}
}
我甚至尝试将CustomDialogSearch的父级设置为CustomDialog
行为仍然不正确
我认为你在这里是正确的,但是你需要使用对话框。例如:
- 将自定义对话框主(“父”对话框)的模态类型设置为。当此对话框可见时,执行此操作将阻止除其子窗口以外的所有窗口
- 将自定义对话框搜索(“子”对话框)的模态类型设置为。这样它就不会阻塞任何其他窗口,您可以从子窗口转到父窗口,反之亦然
import java.awt.Dialog;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Demo {
private void createAndShowGUI() {
JButton button = new JButton("Create Parent modal dialog");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();
JFrame owner = (JFrame)SwingUtilities.windowForComponent(button);
Demo.this.createAndShowParentDialog(owner);
}
});
JFrame frame = new JFrame("Demo");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(button);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void createAndShowParentDialog(JFrame owner) {
JButton button = new JButton("Create Child non-modal dialog");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();
JDialog parent = (JDialog)SwingUtilities.windowForComponent(button);
Demo.this.createAndShowChildrenDialog(parent);
}
});
JDialog parentDialog = new JDialog(owner, "Parent dialog");
parentDialog.setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
parentDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
parentDialog.getContentPane().add(button);
parentDialog.pack();
parentDialog.setLocationRelativeTo(null);
parentDialog.setVisible(true);
}
private void createAndShowChildrenDialog(JDialog parent) {
JButton backButton = new JButton("Back to parent dialog");
backButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();
Window dialog = SwingUtilities.windowForComponent(button);
dialog.getOwner().toFront();
}
});
JDialog childDialog = new JDialog(parent, "Child dialog");
childDialog.setModalityType(Dialog.ModalityType.MODELESS);
childDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
childDialog.getContentPane().add(backButton);
childDialog.pack();
childDialog.setLocationRelativeTo(null);
childDialog.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Demo().createAndShowGUI();
}
});
}
}
编辑
我可以选择父JDialogs和子JDialogs的窗口,但当我
选择父JDialog窗口,子JDialog仍在前面
父JDialog的
我现在对问题有了更好的理解。此行为取决于本机窗口系统处理聚焦窗口和活动窗口的方式。话虽如此,例如,如果调用,它将尝试将窗口置于堆栈顶部,但某些平台不允许拥有其他窗口的窗口出现在其子窗口顶部。调用方法时也会发生同样的情况。有关更多详细信息,请参阅javadocs
我已经在Windows7上测试了我的代码(32位,如果它有什么不同的话),父对话框变成了焦点,但是它的子对话框仍然显示在顶部(没有焦点)。如上所述,如何处理此问题取决于窗口系统。我在您的代码中也看到了相同的行为。即使在我们提到这个对话框之后,子JDialog也不会返回到父JDialog。我可以选择父JDialog和子JDialog的窗口,但是当我选择父JDialog窗口时,子JDialog仍然在父JDialog的前面。这与我将CustomDialogSearch的父级设置为CustomDialogSearch时观察到的行为相同谢谢您的详细解释。