Отображение JFrame на втором мониторе, когда монитором по умолчанию является HiDPI - PullRequest
0 голосов
/ 23 апреля 2020

Мне бы хотелось, чтобы мое приложение Swing запоминало и восстанавливало приложение в том же месте во время запуска. В моей конфигурации основной монитор 4K UI масштаба 1,75, а второй монитор Full HD UI масштаба 1,0, я не могу установить JFrame на второй монитор. Java перемещает JFrame за пределы, поскольку он умножает местоположение на 1,75.

  • 0 <х <2194 (3840 / 1,75) -> х
  • 2194 <х <3840 -> х / 1,75
  • 3840 <х -> х * 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
    }
}
...