简体   繁体   中英

How to make JDialog onTop only for his parent?

Lets say, we have a few JFrame windows visible in same time and for each window JDialog appears. When our windows in cascading mode and for dialogs setAlwaysOnTop is true then all dialogs will be visible over last window.

I just want to associate a Dialog component with its owner, so that when you'll be switching between Frames you'll get only one dialog on top and won't lose this dialog when click on a frame.

Dialogs have constructor like this:

setAlwaysOnTop(true);
setModal(false);

Thanks in advance!

How to make JDialog onTop only for his parent?
  • setParent in the constructor properly

  • have to use setModalityType fe ModalityType.DOCUMENT_MODAL ModalityType.APPLICATION_MODAL instead of setModal

  • setModal is valid to the container which intialized / is parent for this JDialog

  • don't to use more than one JFrame , use JDialog instead, reuse this container for another action

for example

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class SuperConstructor extends JFrame {

    private static final long serialVersionUID = 1L;

    public SuperConstructor() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setPreferredSize(new Dimension(300, 300));
        setTitle("Super constructor");
        Container cp = getContentPane();
        JButton b = new JButton("Show dialog");
        b.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent evt) {
                FirstDialog firstDialog = new FirstDialog(SuperConstructor.this);
            }
        });
        cp.add(b, BorderLayout.SOUTH);
        JButton bClose = new JButton("Close");
        bClose.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent evt) {
                System.exit(0);
            }
        });
        add(bClose, BorderLayout.NORTH);
        pack();
        setVisible(true);
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                SuperConstructor superConstructor = new SuperConstructor();
            }
        });
    }

    private class FirstDialog extends JDialog {

        private static final long serialVersionUID = 1L;

        FirstDialog(final Frame parent) {
            super(parent, "FirstDialog");
            setPreferredSize(new Dimension(200, 200));
            setLocationRelativeTo(parent);
            setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
            JButton bNext = new JButton("Show next dialog");
            bNext.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent evt) {
                    SecondDialog secondDialog = new SecondDialog(parent, false);
                }
            });
            add(bNext, BorderLayout.NORTH);
            JButton bClose = new JButton("Close");
            bClose.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent evt) {
                    setVisible(false);
                }
            });
            add(bClose, BorderLayout.SOUTH);
            pack();
            setVisible(true);
        }
    }
    private int i;

    private class SecondDialog extends JDialog {

        private static final long serialVersionUID = 1L;

        SecondDialog(final Frame parent, boolean modal) {
            //super(parent); // Makes this dialog unfocusable as long as FirstDialog is visible
            setPreferredSize(new Dimension(200, 200));
            setLocation(300, 50);
            setModal(modal);
            setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
            setTitle("SecondDialog " + (i++));
            setModalityType(Dialog.ModalityType.APPLICATION_MODAL);
            JButton bClose = new JButton("Close");
            bClose.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent evt) {
                    setVisible(false);
                }
            });
            add(bClose, BorderLayout.SOUTH);
            pack();
            setVisible(true);
        }
    }
}

In the API one of JDialog constructor is JDialog(Dialog owner, boolean modal) which means that you can create a dialog and specify the parent container as well as the modality. In the modal section, setting it to true means that this dialog will be modal and you cannot access the parent window while the dialog is in display.

But again, you can use the setModal() method to accomplish the same.

just set the Model true and Just set Relativelocation(parent); and dont use setontop(true) for the JDialog.

and then if u back open that time u will get dialog ontop every time. but that will be differ when u Drag the Parent Frame.

I managed to solve this problem building a focus listener that does this job. You can then set this listener to the window you want the dialog stays always visible until is closed. Here is what worked for me:

public class WindowFocusListenerDialogFocus implements WindowFocusListener {
    private JFrame _dialogFrame;


    public WindowFocusListenerDialogFocus(JFrame dialogFrame) {
        _dialogFrame = dialogFrame;
    }


    @Override
    public void windowLostFocus(WindowEvent e) {
        System.out.println("Focus lost!");
    }


    @Override
    public void windowGainedFocus(WindowEvent e) {
        System.out.println("Focus gained!");
        _dialogFrame.toFront();
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM