views:

128

answers:

2

Hi,

while my swing app is running I change the size of the screen (e.g. from 1024x768 to 800x600).

Is there any event I can listen to to be notified about this?

Alternatively I could check the screen size in every couple of second, but the Toolkit.getScreenSize() keeps telling me the old value.
How could I get the real screen size after the change?

Environment: Linux (tested on SuSE ES 11 and Ubuntu 9.04)

I appreciate your help.
Marton

+1  A: 

To compute the display size, you can use (taken from GraphicsConfiguration javadoc)

  Rectangle virtualBounds = new Rectangle();
  GraphicsEnvironment ge = GraphicsEnvironment.
          getLocalGraphicsEnvironment();
  GraphicsDevice[] gs =
          ge.getScreenDevices();
  for (int j = 0; j < gs.length; j++) { 
      GraphicsDevice gd = gs[j];
      GraphicsConfiguration[] gc =
          gd.getConfigurations();
      for (int i=0; i < gc.length; i++) {
          virtualBounds =
              virtualBounds.union(gc[i].getBounds());
      }
  } 

You can then query the width and height of virtualBounds.

This will also work in multi-monitor setups.

As far as I know, there is no JDK supported method to detect changes, so polling is your only bet, or use JNA and native code. If your top-level window is maximized, then resizing the display will also resize any maximized windows, so you could listen for changes there also. See this sun tutorial for examples of writing component listeners.

If you don't have a top-level maximized window, then you may also be able to achieve the same effect by creating a hidden maximized window. I can't say for sure if this will work, but it is worth trying.

mdma
Thank your for the quick answer.Unfortunately the above snippet keeps displaying the old size (1024x768) on Ubuntu 9.04.Best regards,Marton
Marton Sigmond
That's strange, since in essence it uses the same APIs as the accepted answer.
mdma
Yes, it is strange, that the GraphicsConfiguration.getBounds() returns improper value, while the GraphicsDevice.getDisplayMode() returns the good one.On the other hand the GraphicsDevice.getDisplayMode() seems to be to heavyweight, so performing it in every couple of seconds might not be the best idea. I might have to choose a native call instead.
Marton Sigmond
+1  A: 

The following worked for me, but I'm on a Mac, so I can't say for sure that it will work on Linux:

System.out.println(GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getDisplayMode().getWidth() + "x" + GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getDisplayMode().getHeight());

//Ignore this block, it was simply to give me a chance to change my resolution
Scanner readUserInput=new Scanner(System.in);
System.out.println("Waiting on input, go change your resolution");
String myName=readUserInput.nextLine();

System.out.println(GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getDisplayMode().getWidth() + "x" + GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices()[0].getDisplayMode().getHeight());

The output (blah is actually input) was as follows:

1440x900
Waiting on input, go change your resolution
blah
1280x960

Obviously if you have multiple screen devices, you will have to exercise greater caution.

Segphault