在 JTabbedPane 上的 JPanel 上将 JDialog 居中
Posted
技术标签:
【中文标题】在 JTabbedPane 上的 JPanel 上将 JDialog 居中【英文标题】:Center JDialog over JPanel on JTabbedPane 【发布时间】:2012-02-16 09:14:14 【问题描述】:我已经尝试了在这里和其他网站上找到的所有建议。
我似乎无法将此 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);
);
【问题讨论】:
感谢您的回复。无论我将哪个组件用于 relativeTo,dialog.setLocationRelativeTo(relativeTo) 都没有正确地将对话框居中。然后,我获取了 Window.setLocationRelativeTo() 的源代码并将其放在我的班级中,以便能够正确调试它。事实证明,问题在于 dialog.getBounds() 被调用并返回 (0,0) 因为对话框尚未打包。因为它没有被打包,所以它没有尺寸——这弄乱了 setLocationRelativeTo() 中的数学。解决办法,先调用 dialog.pack()。 【参考方案1】:通过将tabbedPane
设置为全局然后dialog.setLocationRelativeTo(tabbedPane);
,我稍微接近了您的目标
编辑:一个更精细,并且可能在视觉上准确的解决方案是计算 JDialog 的 x、y 坐标,如下所示:
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);
老实说,我没有让它完美运行,但这是我的理论!
【讨论】:
hach .. 已经停止阅读您在点击“作为全局”时的预编辑答案 :-) 这既不需要也不需要 - 只需将层次结构向上移动即可。至于手动计算:对话框位置在屏幕坐标中,而组件位置相对于它所在的容器,因此您首先需要将后者转换为屏幕坐标(参见 setLocationRelativeTo 的来源;-) 同意全局位,当我希望找到正确的位置时,这是一种懒惰的解决方法。我也有一种感觉 tabbedPane 相对于它的父级定位。老实说,在我的实验中,我很懒惰(再次)并使用 JFrame 的位置进行数学运算,因为 tabbedPane 很好地坐落在其中;)我真的应该在我的回复中提到这一点>. 【参考方案2】:使对话框相对于给定组件居中的方法(无需手动计算,内部处理组件到屏幕的坐标映射):
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);
【讨论】:
以上是关于在 JTabbedPane 上的 JPanel 上将 JDialog 居中的主要内容,如果未能解决你的问题,请参考以下文章