这让我想起了我最喜欢的一篇文章,在 StackOverflow 上使用Window.setLocationByPlatform(true) 。
如何最好地定位 Swing GUI
编辑 1:
您可以将 a 添加FocusListener
到您的JDialog
and onfocusGained(...)
方法中,您可以setLocationRelativeTo(null)
同时使用 theJFrame
和 the JDialog
,这样无论它们之前在哪里,它们都会出现在屏幕的中心。
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
/**
* Created with IntelliJ IDEA.
* User: Gagandeep Bali
* Date: 1/14/13
* Time: 7:34 PM
* To change this template use File | Settings | File Templates.
*/
public class FrameFocus
{
private JFrame mainwindow;
private CustomDialog customDialog;
private void displayGUI()
{
mainwindow = new JFrame("Frame Focus Window Example");
customDialog = new CustomDialog(mainwindow, "Modal Dialog", true);
mainwindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
JButton mainButton = new JButton(
"Click me to open a MODAL Dialog");
mainButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (!customDialog.isShowing())
customDialog.setVisible(true);
}
});
contentPane.add(mainButton);
mainwindow.setContentPane(contentPane);
mainwindow.pack();
mainwindow.setLocationByPlatform(true);
mainwindow.setVisible(true);
}
public static void main(String... args)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
new FrameFocus().displayGUI();
}
});
}
}
class CustomDialog extends JDialog
{
private JFrame mainWindow;
public CustomDialog(JFrame owner, String title, boolean modal)
{
super(owner, title, modal);
mainWindow = owner;
JPanel contentPane = new JPanel();
JLabel dialogLabel = new JLabel(
"I am a Label on JDialog.", JLabel.CENTER);
contentPane.add(dialogLabel);
setContentPane(contentPane);
pack();
addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
mainWindow.setLocationRelativeTo(null);
setLocationRelativeTo(null);
}
@Override
public void focusLost(FocusEvent e) {
/*
* Nothing written for this part yet
*/
}
});
}
}
编辑 2:
我在这里和那里进行了一些搜索,结果证明,在我看来,实际上Monitor Screen
您的应用程序首先出现在哪个实例上,将确定它是GraphicsConfiguration。虽然当我在 API 中漫游时,上述事物只有一个 getter 方法,GraphicsConfiguration
而没有相同的 setter 方法(您仍然可以通过任何顶级窗口的构造函数指定一个,即JFrame(...) / JDialog(. ..))。
现在你可以用这段代码来占据你的头脑,它可以用来确定你想要设置的适当位置,同样,focusGain()
在我看来,你可能不得不使用方法来满足你问题的条件 2。看一下附加的代码,虽然不需要创建一个new JFrame/JDialog
,只需看如何获取屏幕坐标(您可以在focusGain()
方法中添加以确定整个应用程序的位置。)
GraphicsEnvironment ge = GraphicsEnvironment.
getLocalGraphicsEnvironment();
GraphicsDevice[] gs = ge.getScreenDevices();
for (int j = 0; j < gs.length; j++) {
GraphicsDevice gd = gs[j];
GraphicsConfiguration[] gc =
gd.getConfigurations();
for (int i=0; i < gc.length; i++) {
JFrame f = new
JFrame(gs[j].getDefaultConfiguration());
Canvas c = new Canvas(gc[i]);
Rectangle gcBounds = gc[i].getBounds();
int xoffs = gcBounds.x;
int yoffs = gcBounds.y;
f.getContentPane().add(c);
f.setLocation((i*50)+xoffs, (i*60)+yoffs);
f.show();
}
}
编辑 3:
尝试改变这一点:
int x = loc.getX() + (mainWindow.getWidth() - getWidth()) / 2;
int y = loc.getY() + (mainWindow.getHeight() - getHeight()) / 2;
setLocation(x, y);
只是:
setLocationRelativeTo(mainWindow);
为了测试上述内容,我FrameFocus
按原样使用了我的类,尽管我已将您的更改添加到我的CustomDialog
方法中,如修改后的CustomDialog
类中所示。
class CustomDialog extends JDialog
{
private JFrame mainWindow;
public CustomDialog(JFrame owner, String title, boolean modal)
{
super(owner, title, modal);
mainWindow = owner;
JPanel contentPane = new JPanel();
JLabel dialogLabel = new JLabel(
"I am a Label on JDialog.", JLabel.CENTER);
contentPane.add(dialogLabel);
setContentPane(contentPane);
pack();
addFocusListener(new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
//mainWindow.setLocationRelativeTo(null);
//setLocationRelativeTo(null);
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gs = ge.getScreenDevices();
for (int j = 0; j < gs.length; j++) {
GraphicsDevice gd = gs[j];
GraphicsConfiguration[] gc = gd.getConfigurations();
for (int i=0; i < gc.length; i++) {
Rectangle gcBounds = gc[i].getBounds();
Point loc = mainWindow.getLocationOnScreen();
if (gcBounds.contains(loc)) {
System.out.println("at " + j + " screen");
int x = gcBounds.x + (gcBounds.width - mainWindow.getWidth()) / 2;
int y = gcBounds.y + (gcBounds.height - mainWindow.getHeight()) / 2;
mainWindow.setLocation(x, y);
//x = (int) (loc.getX() + (mainWindow.getWidth() - CustomDialog.this.getWidth()) / 2);
//y = (int) (loc.getY() + (mainWindow.getHeight() - CustomDialog.this.getHeight()) / 2);
//CustomDialog.this.setLocation(x, y);
CustomDialog.this.setLocationRelativeTo(mainWindow);
break;
}
}
}
}
@Override
public void focusLost(FocusEvent e) {
/*
* Nothing written for this part yet
*/
}
});
}
}