JFrame.getLocationOnScreen() for minimized window

2019-07-07 06:40发布

问题:

I call getLocationOnScreen() from JFrame in my Swing application. If JFrame is minimized -32000, -32000 is returned.

It is expected:

Location Coordinates On Computer Showing X=-32000, Y=-32000

But I need to know the location of the window before it was minimized or would be the location if it is maximized again without actual maximizing it. Because I need to position JDialog relatively to the JFrame even though it is minimized.

Possible solution: Add WindowListener to JFrame and on windowIconified() event save the coordinates. And then use it instead of getLocationOnScreen().

Is there better solution using only JFrame methods?

Multiscreen configuration is expected and the following code is used.

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 = topContainer.getLocationOnScreen(); //might return -32000 when minimized
            if (gcBounds.contains(loc)) { //fails if -32000 is returned

回答1:

Simply use getLocation(). Minimized or not, it will always return the appropriate value:

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestJFrame {

    public void initUI() {
        final JFrame frame = new JFrame(TestJFrame.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 400);
        frame.setVisible(true);
        Executors.newScheduledThreadPool(1).scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.err.println(frame.getLocation());
            }
        }, 0, 1000, TimeUnit.MILLISECONDS);
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestJFrame().initUI();
            }

        });
    }
}