Как я могу получить разрешение экрана в Java?

Как можно получить разрешение экрана (ширина х высота) в пикселях?

Я использую JFrame и java swing методы.

12 ответов

Решение

Вы можете получить размер экрана с помощью Toolkit.getScreenSize() метод.

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double width = screenSize.getWidth();
double height = screenSize.getHeight();

В конфигурации с несколькими мониторами вы должны использовать это:

GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
int width = gd.getDisplayMode().getWidth();
int height = gd.getDisplayMode().getHeight();

Если вы хотите получить разрешение экрана в DPI, вам придется использовать getScreenResolution() метод на Toolkit,


Ресурсы:

Этот код будет перечислять графические устройства в системе (если установлено несколько мониторов), и вы можете использовать эту информацию для определения соответствия мониторов или автоматического размещения (некоторые системы используют небольшой боковой монитор для отображения в реальном времени, когда приложение работает в фон и такой монитор можно определить по размеру, цвету экрана и т. д.):

// Test if each monitor will support my app's window
// Iterate through each monitor and see what size each is
GraphicsEnvironment ge      = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[]    gs      = ge.getScreenDevices();
Dimension           mySize  = new Dimension(myWidth, myHeight);
Dimension           maxSize = new Dimension(minRequiredWidth, minRequiredHeight);
for (int i = 0; i < gs.length; i++)
{
    DisplayMode dm = gs[i].getDisplayMode();
    if (dm.getWidth() > maxSize.getWidth() && dm.getHeight() > maxSize.getHeight())
    {   // Update the max size found on this monitor
        maxSize.setSize(dm.getWidth(), dm.getHeight());
    }

    // Do test if it will work here
}

Этот звонок даст вам информацию, которую вы хотите.

Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

К сожалению не помогает, если у вас несколько дисплеев, а в Windows также сообщает масштабированные значения, если вы изменили настройку шрифта «Масштаб и макет» со 100%. Например, при масштабе шрифта 150% мой экран 1920x1080 отображается как 1280x720, что (бесполезно) изменяет разрешение, которое использует мое приложение.

Вместо этого я использую этот метод, который считывает режимы отображения по умолчанию для каждого для доступа к исходной позиции экрана + размерам и возвращает набор прямоугольников, отсортированных в порядке слева->право по оси X на экране:

      /** Get actual screen display sizes, ignores Windows font scaling, sort left to right */
public static List<Rectangle> getDisplays() {
  return Arrays.stream(GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices())
     .map(GraphicsDevice::getDefaultConfiguration)
     // For scaled sizes use .map(GraphicsConfiguration::getBounds) instead of:
     .map(c -> {
            var dm = c.getDevice().getDisplayMode();
            var bounds = c.getBounds();
            return new Rectangle((int)bounds.getX(), (int)bounds.getY(), dm.getWidth(), dm.getHeight());
      })
     .sorted(Comparator.comparing(Rectangle::getX))
     .toList();
}

Приведенный выше код работает под Windows и WSL.

Эти три функции возвращают размер экрана в Java. Этот код учитывает настройки нескольких мониторов и панели задач. Включенные функции: getScreenInsets (), getScreenWorkingArea () и getScreenTotalArea ().

Код:

/**
 * getScreenInsets, This returns the insets of the screen, which are defined by any task bars
 * that have been set up by the user. This function accounts for multi-monitor setups. If a
 * window is supplied, then the the monitor that contains the window will be used. If a window
 * is not supplied, then the primary monitor will be used.
 */
static public Insets getScreenInsets(Window windowOrNull) {
    Insets insets;
    if (windowOrNull == null) {
        insets = Toolkit.getDefaultToolkit().getScreenInsets(GraphicsEnvironment
                .getLocalGraphicsEnvironment().getDefaultScreenDevice()
                .getDefaultConfiguration());
    } else {
        insets = windowOrNull.getToolkit().getScreenInsets(
                windowOrNull.getGraphicsConfiguration());
    }
    return insets;
}

/**
 * getScreenWorkingArea, This returns the working area of the screen. (The working area excludes
 * any task bars.) This function accounts for multi-monitor setups. If a window is supplied,
 * then the the monitor that contains the window will be used. If a window is not supplied, then
 * the primary monitor will be used.
 */
static public Rectangle getScreenWorkingArea(Window windowOrNull) {
    Insets insets;
    Rectangle bounds;
    if (windowOrNull == null) {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        insets = Toolkit.getDefaultToolkit().getScreenInsets(ge.getDefaultScreenDevice()
                .getDefaultConfiguration());
        bounds = ge.getDefaultScreenDevice().getDefaultConfiguration().getBounds();
    } else {
        GraphicsConfiguration gc = windowOrNull.getGraphicsConfiguration();
        insets = windowOrNull.getToolkit().getScreenInsets(gc);
        bounds = gc.getBounds();
    }
    bounds.x += insets.left;
    bounds.y += insets.top;
    bounds.width -= (insets.left + insets.right);
    bounds.height -= (insets.top + insets.bottom);
    return bounds;
}

/**
 * getScreenTotalArea, This returns the total area of the screen. (The total area includes any
 * task bars.) This function accounts for multi-monitor setups. If a window is supplied, then
 * the the monitor that contains the window will be used. If a window is not supplied, then the
 * primary monitor will be used.
 */
static public Rectangle getScreenTotalArea(Window windowOrNull) {
    Rectangle bounds;
    if (windowOrNull == null) {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        bounds = ge.getDefaultScreenDevice().getDefaultConfiguration().getBounds();
    } else {
        GraphicsConfiguration gc = windowOrNull.getGraphicsConfiguration();
        bounds = gc.getBounds();
    }
    return bounds;
}

Вот некоторый функциональный код (Java 8), который возвращает позицию x самого правого края самого правого экрана. Если экраны не найдены, возвращается 0.

  GraphicsDevice devices[];

  devices = GraphicsEnvironment.
     getLocalGraphicsEnvironment().
     getScreenDevices();

  return Stream.
     of(devices).
     map(GraphicsDevice::getDefaultConfiguration).
     map(GraphicsConfiguration::getBounds).
     mapToInt(bounds -> bounds.x + bounds.width).
     max().
     orElse(0);

Вот ссылки на JavaDoc.

GraphicsEnvironment.getLocalGraphicsEnvironment ()
GraphicsEnvironment.getScreenDevices ()
GraphicsDevice.getDefaultConfiguration ()
GraphicsConfiguration.getBounds ()

Вот фрагмент кода, который я часто использую. Он возвращает всю доступную область экрана (даже при настройке нескольких мониторов), сохраняя исходные позиции монитора.

public static Rectangle getMaximumScreenBounds() {
    int minx=0, miny=0, maxx=0, maxy=0;
    GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
    for(GraphicsDevice device : environment.getScreenDevices()){
        Rectangle bounds = device.getDefaultConfiguration().getBounds();
        minx = Math.min(minx, bounds.x);
        miny = Math.min(miny, bounds.y);
        maxx = Math.max(maxx,  bounds.x+bounds.width);
        maxy = Math.max(maxy, bounds.y+bounds.height);
    }
    return new Rectangle(minx, miny, maxx-minx, maxy-miny);
}

На компьютере с двумя мониторами Full-HD, где левый установлен в качестве основного монитора (в настройках Windows), функция возвращает

java.awt.Rectangle[x=0,y=0,width=3840,height=1080]

При той же настройке, но с правым монитором, установленным в качестве основного монитора, функция возвращает

java.awt.Rectangle[x=-1920,y=0,width=3840,height=1080]

Это разрешение экрана, которое в данный момент назначено данному компоненту (на этом экране видно что-то вроде большей части корневого окна).

public Rectangle getCurrentScreenBounds(Component component) {
    return component.getGraphicsConfiguration().getBounds();
}

Использование:

Rectangle currentScreen = getCurrentScreenBounds(frameOrWhateverComponent);
int currentScreenWidth = currentScreen.width // current screen width
int currentScreenHeight = currentScreen.height // current screen height
// absolute coordinate of current screen > 0 if left of this screen are further screens
int xOfCurrentScreen = currentScreen.x

Если вы хотите уважать панели инструментов и т. Д., Вам также нужно рассчитать с этим:

GraphicsConfiguration gc = component.getGraphicsConfiguration();
Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
double width = screenSize.getWidth();
double height = screenSize.getHeight();
framemain.setSize((int)width,(int)height);
framemain.setResizable(true);
framemain.setExtendedState(JFrame.MAXIMIZED_BOTH);

Есть много ответов, но я все еще чувствую, что они недостаточно адекватны, мой подход вычисляет глобальные переменные, связанные с размером экрана, один раз, а также с использованием одного цикла для всех мониторов:

      public final class ScreenArea {
    public static final Rectangle RECTANGLE;
    public static final int 
        LEFT, RIGHT, 
        TOP, BOTTOM, 
        MIN_WIDTH, MAX_WIDTH, 
        MIN_HEIGHT, MAX_HEIGHT, 
        TOTAL_WIDTH, TOTAL_HEIGHT;
    
    static {
        // Initialise local vars
        int left, right, top, bottom, minWidth, maxWidth, minHeight, maxHeight;
        left = top = minWidth = minHeight = Integer.MAX_VALUE;
        right = bottom = maxWidth = maxHeight = Integer.MIN_VALUE;
        // In a single loop process all bounds
        Rectangle bounds;
        for (GraphicsDevice device : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()) {
            bounds = device.getDefaultConfiguration().getBounds();
            if (left > bounds.x)
                left = bounds.x;
            if (right < bounds.x + bounds.width)
                right = bounds.x + bounds.width;
            if (top > bounds.y)
                top = bounds.y;
            if (bottom < bounds.y + bounds.height)
                bottom = bounds.y + bounds.height;
            if (minWidth > bounds.width)
                minWidth = bounds.width;
            if (maxWidth < bounds.width)
                maxWidth = bounds.width;
            if (minHeight > bounds.height)
                minHeight = bounds.height;
            if (maxHeight < bounds.height)
                maxHeight = bounds.height;
        }
        TOTAL_WIDTH = right - left;
        TOTAL_HEIGHT = bottom - top;
        RECTANGLE = new Rectangle(TOTAL_WIDTH, TOTAL_HEIGHT);
        // Transfer local to immutable global vars
        LEFT = left; RIGHT = right; TOP = top; BOTTOM = bottom;
        MIN_WIDTH = minWidth; MAX_WIDTH = maxWidth;
        MIN_HEIGHT = minHeight; MAX_HEIGHT = maxHeight;
    }
}

Затем вы можете использовать в любое время как есть:

      System.out.printf("LEFT=%d, ", ScreenArea.LEFT);
System.out.printf("RIGHT=%d%n", ScreenArea.RIGHT);
System.out.printf("TOP=%d, ", ScreenArea.TOP);
System.out.printf("BOTTOM=%d%n", ScreenArea.BOTTOM);
System.out.printf("MIN_WIDTH=%d, ", ScreenArea.MIN_WIDTH);
System.out.printf("MAX_WIDTH=%d%n", ScreenArea.MAX_WIDTH);
System.out.printf("MIN_HEIGHT=%d, ", ScreenArea.MIN_HEIGHT);
System.out.printf("MAX_HEIGHT=%d%n", ScreenArea.MAX_HEIGHT);
System.out.printf("SCREEN_AREA=%s%n", ScreenArea.RECTANGLE);

Что на моей настройке с двумя мониторами он печатает:

      LEFT=0, RIGHT=3840
TOP=0, BOTTOM=1080
MIN_WIDTH=1920, MAX_WIDTH=1920
MIN_HEIGHT=1080, MAX_HEIGHT=1080
SCREEN_AREA=java.awt.Rectangle[x=0,y=0,width=3840,height=1080]
int resolution =Toolkit.getDefaultToolkit().getScreenResolution();

System.out.println(resolution);
int screenResolution = Toolkit.getDefaultToolkit().getScreenResolution();
System.out.println(""+screenResolution);
Другие вопросы по тегам