2

I have a program that uses visual scripting (sikuli-script) to allow the users to create their own visual scripts. The program needs to work across multiple systems that could have different screen resolutions.

Sikuli matches highlighted images on a pixel-by-pixel basis, so on systems with different resolutions will fail to find images.

Therefore is there a way that I can change the resolution settings in windows through java code?

Going full-screen is not an option as images that need to be captured come from different software packages, i.e. my software package sits above where the images need to come from (and is minimized when a capture is taking place)

Jamesbraders
  • 143
  • 2
  • 3
  • 9

1 Answers1

6

Therefore is there a way that I can change the resolution settings in windows through java code?

1.yes is possible, why not

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.don't do that, could annoying users, and on code lack can to change resolution in Native OS (my coworker has more than 100shortcuts on three screen, any change for resolution to change shotcuts size and location, result is simple mess)

3.use JLabel for Icons(layed with proper LayoutManager into container), or put Icons to the JList or JTable, then you never / don't care about something

4.use only LayoutManager rather than possitioning or change for screen resolution, you can set for smaller Size (for JFrame) on the screen for Apps start_up, let's user decide about final Dimmension on her/his screen

mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • Cheers for code, but I need to change the resolution in the Native OS as my software will minimise to allow the user to select parameter from software running beneath. If changing the native os screen resolution through code is not possible, is there a way I can find out what it is through code? – Jamesbraders Jun 27 '12 at 11:58
  • not don't do that, (-: I'll be runs your code only once time, no one can to convince me to runs that again :-), simple and quite possible only with fullscreen (without impact to the enduser desktop) – mKorbel Jun 27 '12 at 12:12
  • OK well fullscreen is not an option so will have to instruct user to change it manually if required. It is a highly bespoke bit of software running on a PC that is solely for controlling some laboratory equipment so changing the endusers desktop is not an issue, as the other option would be the software not working – Jamesbraders Jun 27 '12 at 12:33
  • http://www.javacoffeebreak.com/faq/faq0015.html : returns current screen resolution – Jamesbraders Jun 27 '12 at 12:48
  • What is the purpose of the block that cycles through displaying all the colors fullscreen faster and faster? – VolleyJosh Apr 28 '22 at 18:28
  • This code works for me to set the resolution. But when the program exists, the resolution is reset back to what it was, even if I remove the finally{device.setFullScreenWindow(null)}. Is there an additional method call that's required to persist the setting? – VolleyJosh Apr 28 '22 at 18:31