Question

Upon disconnecting an external monitor from my laptop, I lose some of my apps as the disconnected monitor is still set as the default. Some of my windows are trying to display on the disconnected monitor.

I have a workaround, such as right clicking on the app icon and selecting move then using the arrow key to move the windows to my laptop. I'm wondering if there is a way in Java to listen for the disconnect, then reset my default screen to my laptop.

I thought about getting the number of and ID's of the screens that are available at startup and adding them to a property file. If a screen is disconnected, get the number of and ID's of the available screens again and compare those values to the values in my property file. I could then set the default to the screen that matches the new values and the stored values.

I haven't started coding this up yet. This is more investigative than anything at this point.

Was it helpful?

Solution

The AWT gives you access to screen information, although "external" is subjective as you might have 2 built-in monitors or 2 external ones.

At a basic level, you can count the monitors at any moment:

int numberOfMonitors = 0;
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gs = ge.getScreenDevices();
for (int j = 0; j < gs.length; j++) {
    GraphicsDevice gd = gs[j];
    GraphicsConfiguration[] gc = gd.getConfigurations();
    if (gc.getType() == TYPE_RASTER_SCREEN) numberOfMonitors++;
}
System.out.println("Number of monitors: " + numberOfMonitors);

To detect the attachment of a new monitor, you will need to poll for the result.

This is a pure Java solution; to my knowledge if you want anything more accurate than this then you'll probably need to call some native tools on the platform(s) you are targeting. For example, probing sysfs in Linux.

OTHER TIPS

Basically I would say this is pretty hard or impossible to do with Java only. The reason is Java is a cross platform language and all this is handled by the underlying operating system. Please keep in mind, that it's hard to find a robust, cross platform solution for this problem.

You're asking how to detect, if a monitor is connected or disconnected:

Under Windows you can hook on WM_DEVICECHANGE via Java Native Access.

Maybe an idea is to check from time to time getScreenDevices() and detect changes, but this is more a workaround than a real solution.

You're also asking how you can change the primary display. There is an example how you can use the WinAPI for this task.

For other operating system you need to find other ways. I hope this answer gives an idea, that this could be quite hard to solve, especially with Java.

If you're targeting Windows with your Java app, there is a hardware workaround.

Connecting a monitor with a DisplayPort cable allows Windows to know when a display is off (be it by power button or disconnected cable). When Windows detects a monitor going offline, it moves all windows in the disconnected monitor to a screen that remains on. No extra coding needed. Although a limited use case, this could save you some trouble if you have control over the hardware.

On the other hand, if you code your own solution, you would do well to test your solution on this kind of setup to make sure the result of Windows moving windows around and your software moving windows around does not lead to unwanted behaviour.

(This is my experience on a Windows 10 box with NVIDIA/HP GPUs/monitors, YMMV)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top