4

In Windows, each screen has an number or identity assigned I assume is relative to how I physically connected my monitor cables. Key to my question is that I can reconfigure these screens but they will keep their identity.

Java's call to GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices() will give me an array of GraphicsDevice.

How can I correlate the order of screens in the array with the Window numbering? I'd be interested in a cross-platform solution.

For example, my Windows configuration looks like this enter image description here

but the array returned looks like this

screens[0] = relates to screen 2
screens[1] = relates to screen 3
screens[2] = relates to screen 1

NB the code I get I'd like to use is along the lines of this

frame.setLocation(
     screens[i].getDefaultConfiguration().getBounds().x, frame.getY());

where i should be the physical number and not the position in the array (or its mapping if you see what I mean).

Toby
  • 9,523
  • 8
  • 36
  • 59

2 Answers2

2

You could sort the screen devices by their locations:

Arrays.sort(screens, new Comparator<GraphicsDevice>() {
    public int compare(GraphicsDevice screen1,
                       GraphicsDevice screen2) {
        Rectangle bounds1 = screen1.getDefaultConfiguration().getBounds();
        Rectangle bounds2 = screen2.getDefaultConfiguration().getBounds();
        int c = bounds1.y - bounds2.y;
        if (c == 0) {
            c = bounds1.x - bounds2.x;
        }
        return c;
    }
});
VGR
  • 40,506
  • 4
  • 48
  • 63
  • 1
    It should be noted that if you change the order of the array returning from GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(), your primary screen is changed as well (GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice()). So better make a copy of the returned array not to lose the primary device. – bmlkc Sep 24 '14 at 13:40
  • Wow. This is a serious bug, and quite a surprise to me since Java is usually very good at employing [defensive copying](http://stackoverflow.com/questions/12000655/regarding-an-immutable-class-defensive-copying). Compare with the notorious [Class.getSigners() security bug](https://www.cs.auckland.ac.nz/courses/compsci725s2c/archive/termpapers/725lun.pdf). – VGR Sep 24 '14 at 14:39
0

Nothing guarantees that GraphicsDevice order returned in getScreenDevices() will be the same as you see it in your OS settings. Also i don't know any convenient way to retrieve system screens order (and i doubt there is one, you will surely have to call some native OS APIs to get the exact order).

You can use available information about GraphicsDevice to order them in your application:

  • Default device - GraphicsEnvironment.getLocalGraphicsEnvironment ().getDefaultScreenDevice ()

  • Devices bounds - graphicsDevice.getDefaultConfiguration ().getBounds ()

Device ID might also tell you something - graphicsDevice.getIDstring () - though i cannot check right now whether it is affected by system screens order or not.

Mikle Garin
  • 10,083
  • 37
  • 59