2012-01-22 3 views
2

Я пробовал все предложения, которые я нашел здесь и на других сайтах.Центр JDialog над JPanel на JTabbedPane

Невозможно, чтобы этот JDialog был центрирован над панелью на JTabbedPane.

Обратите внимание: у меня должна быть кнопка закрытия, поэтому я не могу использовать стандартные методы JOptionPane.showDialogXYZ().

Любые идеи?

import java.awt.BorderLayout; 
import java.awt.Dialog.ModalityType; 
import java.awt.Frame; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 

import javax.swing.JButton; 
import javax.swing.JDialog; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JTabbedPane; 
import javax.swing.SwingUtilities; 

public class CenterDialog extends JFrame 
{ 
    public CenterDialog() 
    { 
     setResizable(false); 

     setName(getClass().getSimpleName()); 
     setTitle("My Frame"); 
     setSize(300, 300); 

     JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP); 

     // Add the panel 
     tabbedPane.addTab("Button panel", new MyButtonPanel()); 

     add(tabbedPane, BorderLayout.CENTER); 

     getContentPane().add(tabbedPane); 
    } 

    private class MyButtonPanel extends JPanel 
    { 

     public MyButtonPanel() 
     { 
      JButton btnShowDialog = new JButton("Show Dialog"); 
      btnShowDialog.addActionListener(new BtnShowDialogActionListener()); 
      add(btnShowDialog); 
     } 

     private class BtnShowDialogActionListener implements ActionListener 
     { 
      public void actionPerformed(ActionEvent e) 
      { 
       // TODO: Figure out how to center this dialog box 
       final String YES = "Yup"; 
       final String NO = "Nope"; 
       final Object[] options = { YES, NO }; 

       final JOptionPane optionPane = new JOptionPane("Is this centered.", JOptionPane.QUESTION_MESSAGE, 
         JOptionPane.YES_NO_OPTION, null, options, NO); 

       Frame f = JOptionPane.getFrameForComponent(((JButton) e.getSource()).getParent()); 
       final JDialog dialog = new JDialog(f, "Question", ModalityType.APPLICATION_MODAL); 

       dialog.setContentPane(optionPane); 
       dialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE); 

       dialog.addWindowListener(new WindowAdapter() 
       { 
        public void windowClosing(WindowEvent we) 
        { 
         System.out.println("Ignoring close button"); 
        } 
       }); 

       optionPane.addPropertyChangeListener(new PropertyChangeListener() 
       { 
        public void propertyChange(PropertyChangeEvent e) 
        { 
         String prop = e.getPropertyName(); 

         if (dialog.isVisible() && (e.getSource() == optionPane)) 
         { 
          if (prop.equals(JOptionPane.VALUE_PROPERTY)) 
          { 
           dialog.setVisible(false); 
          } 
         } 
        } 
       }); 

       dialog.pack(); 
       dialog.setVisible(true); 
      } 
     } 
    } 

    private static void createAndShowGUI() 
    { 
     // Create and set up the window. 
     CenterDialog frame = new CenterDialog(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       try 
       { 
        createAndShowGUI(); 
       } 
       catch (Exception e) 
       { 
        e.printStackTrace(); 
        System.exit(0); 
       } 
      } 
     }); 
    } 

} 

}

+0

Спасибо за ответы. Независимо от того, какой компонент I использовал для relativeTo, dialog.setLocationRelativeTo (relativeTo) не центрировал диалог должным образом. Затем я взял источник для Window.setLocationRelativeTo() и поместил его в свой класс, чтобы я смог правильно его отладить. Оказывается, проблема в том, что dialog.getBounds() вызывается и возвращает (0,0), потому что диалог еще не был упакован. Поскольку он не был упакован, он не имел размеров - это испортило математику в setLocationRelativeTo(). Решение, сначала вызовите dialog.pack(). – bigleftie

ответ

7

Метод, который центрирует диалог относительно данного компонента (без ручного расчета, необходимого, обрабатывает компонент до экрана отображения координат внутри):

dialog.setLocationRelativeTo(someComponent); 

Выберите компонент, в зависимости от того, что именно вы хотите достижения:

// center relative to the button 
dialog.setLocationRelativeTo((Component) e.getSource()); 

// center relative to button's parent 
dialog.setLocationRelativeTo(((Component) e.getSource()).getParent()); 

// center relative to the tabbedPane 
JTabbedPane tabbed = // walk the parent chain until you reach it 
dialog.setLocationRelativeTo(tabbed); 
2

я получил немного ближе к тому, что вы после этого, установив tabbedPane как глобальный, а затем dialog.setLocationRelativeTo(tabbedPane);

Edit: более сложный, и, вероятно, визуально точным, решение является расчет координаты x, y вашего JDialog, что-то вроде этого:

int xDiff = (tabbedPane.getWidth() - dialog.getWidth())/2; 
int x = tabbedPane.getX() + xDiff; 
int yDiff = (tabbedPane.getHeight() - dialog.getHeight())/2; 
int y = tabbedPane.getY() + yDiff; 
dialog.setLocation(x, y); 

Если честно, я ди не получится, он отлично работает, но есть моя теория!

+1

hach ​​.. перестали читать ваш предварительный ответ, нажав на «как глобальный» :-). Который ни нужен, ни нужен - просто идите вверх по иерархии. Что касается ручных вычислений: расположение диалога находится в координатах экрана, а расположение компонента относительно контейнера, в котором он живет, поэтому вам сначала нужно преобразовать последнее в координаты экрана (см. Источник setLocationRelativeTo ;-) – kleopatra

+0

Согласовано на глобальном бит, это было своего рода ленивое обходное решение, в то время как я искал, чтобы получить информацию о правильном. У меня также было чувство, что tabbedPane позиционируется относительно его родителя. Если честно, в своих экспериментах я был ленив (снова) и использовал место JFrame для математики, так как tabbedPane устроилась красиво и напряженно внутри него;) Я действительно должен был упомянуть об этом в своем ответе >. c24w