Заставьте модальное диалоговое окно Java Swing вести себя как диалоговые окна Mac OSX

Я пишу небольшое приложение, которое требует, чтобы ProgressBar отображался по центру под заголовком фрейма, как это часто встречается в приложениях Mac OSX. У меня две проблемы:

1. Мне удалось позиционировать, но мне пришлось жестко закодировать высоту TitleBar родительского фрейма. Есть ли «мягкий» способ получить высоту TitleBar?

В конструкторе диалога:

 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. Несмотря на то, что диалоговое окно является модальным, я все равно могу щелкнуть родительский фрейм и переместить его. Как я могу заставить диалог «прилипнуть» к родительскому фрейму? То есть, когда родительский фрейм перемещается, диалоговое окно перемещается вместе с ним, как если бы оно было прикреплено.

Любая помощь/указатели будут высоко оценены.

Вот код:



    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);
      }

    }


person Lyndon    schedule 29.12.2011    source источник
comment
Несмотря на то, что диалоговое окно является модальным, я все равно могу щелкнуть родительский фрейм Является ли фрейм родителем диалогового окна?   -  person Andrew Thompson    schedule 29.12.2011
comment
Да, Эндрю, фрейм является родителем диалога.   -  person Lyndon    schedule 30.12.2011


Ответы (1)


int titleBarHeight = frame.getInsets().top;

Несмотря на то, что диалоговое окно является модальным, я все равно могу щелкнуть родительский фрейм и переместить его.

Тогда вы делаете что-то не так, потому что этого НЕ должно происходить.

Опубликуйте свой SSCCE, демонстрирующий проблему.

person camickr    schedule 29.12.2011
comment
кадр.getInsets().top; правильно, он получает высоту TitleBar. Спасибо. - person Lyndon; 30.12.2011
comment
Вот SSCCE с двумя классами, родительским JFrame и JDialog. Запустите, нажмите кнопку «Открыть диалог», чтобы загрузить диалог. Затем нажмите на заголовок JFrame и переместите его. - person Lyndon; 30.12.2011
comment
Обратите внимание, что я запускаю это на iMac на OSX 10.6, я не знаю, имеет ли это значение. - person Lyndon; 30.12.2011
comment
Я начинаю думать, что модальный JDialog на OSX НЕ мешает его владельцу JFrame перемещаться. Правда, с JFrame-владельцем ничего сделать нельзя, но это просто неуместно. - person Lyndon; 16.01.2012
comment
Я вижу, что Quaqua сделала то, что мне нужно, но для достижения желаемых результатов потребовалось много кода с использованием ComponentAdapter... - person Lyndon; 16.01.2012