How do I center a java.awt.FileDialog on the scree

2019-05-15 11:51发布

问题:

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.

回答1:

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.



回答2:

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



回答3:

Try this code: dlg.setLocationRelativeTo(null);



回答4:

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