代码之家  ›  专栏  ›  技术社区  ›  Anthony

当默认监视器是HiDPI时,在第二个监视器上显示JFrame

  •  0
  • Anthony  · 技术社区  · 4 年前

    我想让我的swing应用程序在启动时在同一位置记住并恢复应用程序。 在我的配置中,主监视器是4K ui scale 1.75,第二个监视器full HD ui scale 1.0,我不能将JFrame放到第二个监视器上。Java将JFrame的位置乘以1.75,从而使JFrame越界。

    • 0<x<2194(3840/1.75)—>x
    • 2194<x<3840->x/1.75

    import java.awt.GraphicsDevice;
    import java.awt.GraphicsEnvironment;
    import java.awt.event.ComponentAdapter;
    import java.awt.event.ComponentEvent;
    import javax.swing.*;
    
    // javac TestJFrame.java && java -cp . TestJFrame
    public class TestJFrame {
    
        public static void showStats() {
            GraphicsDevice defaultScreen = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
            System.out.println("Default configuration bounds: " + 
                    defaultScreen.getDefaultConfiguration().getBounds());
            System.out.println("Default display mode: " + 
                    defaultScreen.getDisplayMode().getWidth() + ";" + defaultScreen.getDisplayMode().getHeight());
            for (GraphicsDevice screen : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
                System.out.println("Bounds: " + screen.getDefaultConfiguration().getBounds());
                System.out.println("Display mode: " + screen.getDisplayMode().getWidth() + ";" + screen.getDisplayMode().getHeight());
            }
        }
    
        public static void showJFrame(int x, int y) {
            //GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getDefaultConfiguration(); // also doesn't work
            final JFrame frame = new JFrame();
            frame.setTitle("Test " + x + ";" + y);
            frame.setLocation(x, y);
            frame.addComponentListener(new ComponentAdapter() {
                public void componentMoved(ComponentEvent e) {
                    JFrame frameEvent = (JFrame) e.getComponent();
                    System.out.println("JFrame " + x + ";" + y + " moved to " + 
                            frameEvent.getX() + ";" + frameEvent.getY());
                }
            });
            frame.pack();
            frame.setVisible(true);
        }
    
        public static void main(String[] args) {
            showStats(); // UI scale 1.75.Default configuration bounds: java.awt.Rectangle[x=0,y=0,width=2194,height=1234]; Default display mode: 3840;2160
            // Bounds: java.awt.Rectangle[x=3840,y=0,width=1920,height=1080] Display mode: 1920;1080 Bounds: java.awt.Rectangle[x=0,y=0,width=2194,height=1234] Display mode: 3840;2160
            showJFrame(100, 100); // OK moved to 100;100
            showJFrame(3000, 200); // OK moved to 1714;114 // 3000 / 1.75 = 1714
            showJFrame(4000, 300); // Error: out of both screens moved to 7000;525 // 4000 * 1.75 = 7000
        }
    }
    
    0 回复  |  直到 4 年前