Изменить разрешение экрана в Java

У меня есть программа, использующая визуальные сценарии (sikuli-script), чтобы пользователи могли создавать свои собственные визуальные сценарии. Программа должна работать в нескольких системах, которые могут иметь разные разрешения экрана.

Sikuli сопоставляет выделенные изображения попиксельно, поэтому на системах с другим разрешением изображения найти не удастся.

Поэтому есть ли способ изменить настройки разрешения в Windows через код Java?

Переход в полноэкранный режим невозможен, поскольку изображения, которые необходимо захватить, поступают из разных программных пакетов, т. Е. Мой программный пакет находится выше того места, откуда должны поступать изображения (и сворачивается во время захвата).


person Jamesbraders    schedule 27.06.2012    source источник


Ответы (1)


Поэтому есть ли способ изменить настройки разрешения в Windows через код Java?

1.да можно, почему бы и нет

import java.awt.Color;
import java.awt.DisplayMode;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.image.BufferStrategy;

public class MultiBufferTest {

    private Frame mainFrame;
    private static Color[] COLORS = new Color[]{
        Color.red, Color.blue, Color.green, Color.white, Color.black,
        Color.yellow, Color.gray, Color.cyan, Color.pink, Color.lightGray,
        Color.magenta, Color.orange, Color.darkGray};
    private static DisplayMode[] BEST_DISPLAY_MODES = new DisplayMode[]{
        new DisplayMode(640, 480, 32, 0),
        new DisplayMode(640, 480, 16, 0),
        new DisplayMode(640, 480, 8, 0)};

    public MultiBufferTest(int numBuffers, GraphicsDevice device) {
        try {
            GraphicsConfiguration gc = device.getDefaultConfiguration();
            mainFrame = new Frame(gc);
            mainFrame.setUndecorated(true);
            mainFrame.setIgnoreRepaint(true);
            device.setFullScreenWindow(mainFrame);
            if (device.isDisplayChangeSupported()) {
                chooseBestDisplayMode(device);
            }
            Rectangle bounds = mainFrame.getBounds();
            mainFrame.createBufferStrategy(numBuffers);
            BufferStrategy bufferStrategy = mainFrame.getBufferStrategy();
            for (float lag = 2000.0f; lag > 0.00000006f; lag = lag / 1.33f) {
                for (int i = 0; i < numBuffers; i++) {
                    Graphics g = bufferStrategy.getDrawGraphics();
                    if (!bufferStrategy.contentsLost()) {
                        g.setColor(COLORS[i]);
                        g.fillRect(0, 0, bounds.width, bounds.height);
                        bufferStrategy.show();
                        g.dispose();
                    }
                    try {
                        Thread.sleep((int) lag);
                    } catch (InterruptedException e) {
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            device.setFullScreenWindow(null);
        }
    }

    private static DisplayMode getBestDisplayMode(GraphicsDevice device) {
        for (int x = 0; x < BEST_DISPLAY_MODES.length; x++) {
            DisplayMode[] modes = device.getDisplayModes();
            for (int i = 0; i < modes.length; i++) {
                if (modes[i].getWidth() == BEST_DISPLAY_MODES[x].getWidth()
                        && modes[i].getHeight() == BEST_DISPLAY_MODES[x].getHeight()
                        && modes[i].getBitDepth() == BEST_DISPLAY_MODES[x].getBitDepth()) {
                    return BEST_DISPLAY_MODES[x];
                }
            }
        }
        return null;
    }

    public static void chooseBestDisplayMode(GraphicsDevice device) {
        DisplayMode best = getBestDisplayMode(device);
        if (best != null) {
            device.setDisplayMode(best);
        }
    }

    public static void main(String[] args) {
        try {
            int numBuffers = 2;
            if (args != null && args.length > 0) {
                numBuffers = Integer.parseInt(args[0]);
                if (numBuffers < 2 || numBuffers > COLORS.length) {
                    System.err.println("Must specify between 2 and " + COLORS.length + " buffers");
                    System.exit(1);
                }
            }
            GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice device = env.getDefaultScreenDevice();
            MultiBufferTest test = new MultiBufferTest(numBuffers, device);
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.exit(0);
    }
}

2. не делайте этого, это может раздражать пользователей, а из-за отсутствия кода можно изменить разрешение в Native OS (у моего коллеги более 100 ярлыков на трех экранах, любое изменение разрешения меняет ярлыки size и location, результат - просто беспорядок)

3.используйте JLabel вместо Icons (уложите с правильным LayoutManager в контейнер), или поместите Icons в JList или JTable, тогда вам никогда/не будет дела до чего-либо

4. Используйте только LayoutManager, а не позиционирование или изменение разрешения экрана, вы можете установить меньшее Size (для JFrame) на экране для Apps start_up, пусть пользователь сам решит, какой Dimmension будет на своем экране.

person mKorbel    schedule 27.06.2012
comment
Спасибо за код, но мне нужно изменить разрешение в родной ОС, так как мое программное обеспечение будет свернуто, чтобы пользователь мог выбрать параметр из программного обеспечения, работающего под ним. Если изменение собственного разрешения экрана ОС с помощью кода невозможно, есть ли способ узнать, что это такое, с помощью кода? - person Jamesbraders; 27.06.2012
comment
не делайте этого, (-: я буду запускать ваш код только один раз, никто не сможет убедить меня запустить это снова :-), просто и вполне возможно только в полноэкранном режиме (без воздействия на рабочий стол конечного пользователя) - person mKorbel; 27.06.2012
comment
Хорошо, полноэкранный режим невозможен, поэтому при необходимости пользователю придется указать, чтобы он изменил его вручную. Это очень специальное программное обеспечение, работающее на ПК, которое предназначено исключительно для управления некоторым лабораторным оборудованием, поэтому изменение рабочего стола конечного пользователя не является проблемой, поскольку другим вариантом может быть неработающее программное обеспечение. - person Jamesbraders; 27.06.2012
comment
javacoffeebreak.com/faq/faq0015.html : возвращает текущее разрешение экрана. - person Jamesbraders; 27.06.2012