I have never been able to figure this one out; the usual suspects don't work.
Given:
FileDialog dlg=null;
dlg=new FileDialog(owner,"Select File to Load",FileDialog.LOAD);
dlg.setFile(null);
dlg.setVisible(true);
is there any way to get that dialog centered?
A key point is that at setVisible(), the calling thread is blocked until the dialog is dismissed; and any positioning prior to that seems to be ignored.
The below solution works for SWT, probably it can do the trick for AWT as well...
As it shows the dialog in left top corner of the current shell, a quick-and-dirty solution is to create a new, well-positioned and invisible shell and to open FileDialog from it. I got an acceptable result with the following code:
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Shell;
public class CenteredFileDialog extends Dialog {
protected Shell shell;
public FileDialog dialog;
private int width = 560; // WinXP default
private int height = 420;
public CenteredFileDialog(Shell parent, int style) {
super(parent, style);
shell = new Shell(getParent(), SWT.APPLICATION_MODAL);
dialog = new FileDialog(shell, style);
}
public Object open() {
shell.setSize(width, height);
Rectangle parentBounds = getParent().getBounds();
shell.setLocation(
parentBounds.x + (parentBounds.width - width) / 2,
parentBounds.y + (parentBounds.height - height) / 2);
Object result = dialog.open();
shell.dispose();
return result;
}
}
The class can be used this way:
CenteredFileDialog saveDialog = new CenteredFileDialog(getShell(), SWT.SAVE);
saveDialog.dialog.setFilterExtensions(new String[] { "*.txt" });
saveDialog.dialog.setFilterNames(new String[] { "Text (*.txt)" });
...
String f = (String)saveDialog.open();
if ( f != null ) {
name = f;
recentPath = saveDialog.dialog.getFilterPath();
}
The class only partially solves the problem for Windows platform (On MacOS the dialog is screen-centered anyway; on Linux I did not test) - first time the dialog appears centered relatively to the parent shell (which is what we need), and "remembers" its absolute position on the screen. By subsequent calls it always pops up in the same place, even if the main application window moved.
Despite the oddity, from my perspective the new behaviour is definitely better than the default unprofessionally looking top-left docking of the dialog.
Appears that this may still be a bug.... see last line of this (though its dated 2003)
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4333836
I threw this together
FileDialog fd = new FileDialog(f, title, FileDialog.LOAD);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
int w = fd.getSize().width;
int h = fd.getSize().height;
int x = (dim.width-w)/2;
int y = (dim.height-h)/2;
System.out.println("Dialog location: " + fd.getLocation().toString());
fd.setLocation(x, y);
System.out.println("Dialog location: " + fd.getLocation().toString());
fd.setVisible(true);
And my output was:
Dialog location: java.awt.Point[x=0,y=0]
Dialog location: java.awt.Point[x=840,y=525]
But the screen was still in the top left corner
Try this code: dlg.setLocationRelativeTo(null);
Using Java 7, Eclipse 4.4.1 and Ubuntu 14.04 I was able to find a solution for centering AWT FileDialog
.
I was determined to find a solution because Apple recommends using awt.FileDialog over Swing's JFileChooser
for a more native look and feel.
The trick is to give your FileDialog
instance a size
before setting its location
.
Use the bounds
of the contentPane
of your main application frame
to calculate the distance of the left corner Point
(minX, minY) of FileDialog
from the contentPane
's center Point
.
Then set the location
of your FileDialog
to this calculated Point
, et voilá ... centered.
final FileDialog fileDialog = new FileDialog(applicationFrame,
"Choose a file", FileDialog.LOAD);
/* Lots of code to be able to center an awt.FileDialog on screen... */
Rectangle rect = applicationFrame.getContentPane().getBounds();
/*
* Making sure FileDialog has a size before setVisible, otherwise
* left corner's distance from contentPane center cannot be found.
*/
fileDialog.pack();
fileDialog.setSize(800, 600);
fileDialog.validate();
double width = fileDialog.getBounds().getWidth();
double height = fileDialog.getBounds().getHeight();
double x = rect.getCenterX() - (width / 2);
double y = rect.getCenterY() - (height/ 2);
/* Could be new Point(x, y) */
Point leftCorner = new Point();
leftCorner.setLocation(x, y);
fileDialog.setLocation(leftCorner);
fileDialog.setVisible(true);