简体   繁体   中英

Make Java Swing Modal Dialog Behave Like Mac OSX Dialogs

I am writing a small app that requires a ProgressBar to appear centred under the frame's TitleBar as is often seen in Mac OSX apps. I have two problems:

1 . I have managed the positioning but I had to hard code the parent Frame's TitleBar height. Is there a 'soft' way to get the TitleBar's height?

In the Dialog's constructor:

 Dimension dimensionParentFrame = parent.getSize();
 Dimension dimensionDialog = getSize();
 int x = parent.getX() + ((dimensionParentFrame.width - dimensionDialog.width)/2);
 setLocation(x, parent.getY() + 22);              // TODO HARD CODE WARNING TITLE HEIGHT

2 . Even though the Dialog is modal, I can still click on the parent Frame and move it. How can I make the Dialog 'stick' to the parent Frame? That is, when the parent Frame is moved the Dialog moves with it as if attached.

Any help/pointers would be much appreciated.

Here is the code:



    import javax.swing.JFrame;
    import javax.swing.JButton;
    import java.awt.BorderLayout;
    import java.awt.EventQueue;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;


    public class ModalDialogDemoFrame extends JFrame
    {
      ModalDialogDemoFrame modalDialogDemo;
      public ModalDialogDemoFrame() 
      {
        modalDialogDemo = this;
        setBounds(100, 100, 400, 400);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JButton buttonDialog = new JButton("Open Dialog");
        buttonDialog.addActionListener(new ActionListener() 
        {
          public void actionPerformed(ActionEvent arg0) 
          {
            // Create a Modal Dialog with this Frame as Parent.
            ModalDialog modalDialog = new ModalDialog(modalDialogDemo, true);
            modalDialog.setVisible(true);
          }
        });
        getContentPane().add(buttonDialog, BorderLayout.CENTER);
      }

      /**
       * @param args
       */
      public static void main(String[] args)
      {
        EventQueue.invokeLater(new Runnable()
        {
          public void run()
          {
            try
            {
              ModalDialogDemoFrame window = new ModalDialogDemoFrame();
              window.setVisible(true);
            }
            catch (Exception e)
            {
              e.printStackTrace();
            }
          }
        });
      }

    }

    import java.awt.Dimension;

    import javax.swing.JDialog;
    import javax.swing.JFrame;
    import javax.swing.JButton;
    import java.awt.BorderLayout;
    import java.awt.event.ActionListener;
    import java.awt.event.ActionEvent;


    public class ModalDialog extends JDialog
    {
      public ModalDialog(JFrame parent, boolean modal) 
      {
        super(parent, modal);
        Dimension dimensionParentFrame = parent.getSize();
        setSize(new Dimension((parent == null) ? 300 : dimensionParentFrame.width / 2, 75));
        Dimension dimensionDialog = getSize();
        int x = parent.getX() + ((dimensionParentFrame.width - dimensionDialog.width)/2);
        setLocation(x, parent.getY() + parent.getInsets().top);
        setUndecorated(true);
        setModal(modal);
        setModalityType(ModalityType.APPLICATION_MODAL);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        JButton buttonClose = new JButton("Close");
        buttonClose.addActionListener(new ActionListener() 
        {
          public void actionPerformed(ActionEvent e) 
          {
            dispose();
          }
        });
        getContentPane().add(buttonClose, BorderLayout.CENTER);
      }

    }

int titleBarHeight = frame.getInsets().top;

Even though the Dialog is modal, I can still click on the parent Frame and move it.

Then you are doing something wrong because this should NOT happen.

Post your SSCCE that demonstrates the problem.

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