Getting Each Monitor Inset In Java

432 views Asked by At

Don't mind the use of the Window Insets, but pay more attention to the use of the ScreenInsets, which is saved locally as Insets insets; I print the insets.bottom, and for every monitor the taskbar height shows up, even though the taskbar is only located on the first monitor.

The monitor insets on my second monitor should all be zero, but yet it acts as if the taskbar is located on both monitors. Setting the window to full size in the monitor the window is currently located on works, except it leaves room for the taskbar regardless which monitor are use it in.

From my understanding of the Toolkit.getScreenInsets(GraphicsConfiguration), it should return the correct insets for the specific GraphicsConfiguration you pass in, yet I'm passing in each GraphicsDevice's GraphicsConfiguration and getting the same results back.

JFrame window;

public void setSizeToFullScreen()
    {
        GraphicsEnvironment ge=GraphicsEnvironment.getLocalGraphicsEnvironment(); 
        GraphicsDevice[] screenDevices=ge.getScreenDevices();
        Point p=window.getLocationOnScreen();       
            for(int i=0;i<screenDevices.length;i++)
            {

                Rectangle2D b=screenDevices[i].getDefaultConfiguration().getBounds();
                if(SMath.getMath().doesRectangleContainPoint(b.getX(), b.getY(), b.getWidth(), b.getHeight(), p.getX(),p.getY()))
                {
                    Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(screenDevices[i].getDefaultConfiguration());
                    System.out.println("Monitor:  "+i+":  task bar height:  "+insets.bottom);
                    this.setSize(b.getWidth()+1 -(insets.right+insets.left)-(this.window.getInsets().left+this.window.getInsets().right), b.getHeight()+1-(insets.top+insets.bottom)-(this.window.getInsets().top+this.window.getInsets().bottom));
                    this.setLocation(b.getX()+insets.left+window.getInsets().left, b.getY()+insets.top+window.getInsets().top);
                    return;
                }
            }       
    }

My question is, in Java, how can we figure out which monitor actually has the taskbar, or the better question, how can we get the correct monitor insets for each monitor in Java.

1

There are 1 answers

0
NeuroDuck On

Re: "..., yet it acts as if the taskbar is located on both monitors".

I found the following:

Referring to Windows->Control Panel->Appearance and Personalization-> Display->Screen Resolution:

When gs[0] (= the display shown with a "1" inside a circle in the Control Panel window above) has the Toolbar, the reported Insets are correct.

I.e., they are reported to be = 0 for the no-Toolbar screen and = 49 for the screen that has the Toolbar.

When any other gs[x] has the Toolbar, the reported Insets are wrong :-(. I.e., they are reported to be = 49 for all screens.

In my application, I want "JDialog dialog0" to always appear 500 to the right of the lower-left corner of my "big" display, and "JFrame frameBalloonHerderGui" to always appear in the upper-left corner of my "small" display.

I want the JDialog to have a fixed size in the lower-left corner of my "big" display, and the JFrame should pretty much fill the "small" display it's in.

I did give the graphicsConfiguration for the display I wanted each JDialog/JFrame to appear in to their constructors. Alas, that is not enough to allow the Insets to be correct.

To accomplish the positioning above, I wrote a function that I call for my JDialog and JFrame as follows:

// I'll omit the creation of the grapicsConfiguration for now.
JDialog dialog0 = new JDialog( gc);  

ScreenAndTaskBarHeights h = getThisComponentsScreensTaskBarHeight( dialog0);

final int myWidth = 1170;
final int myHeight = 800;
final int myScreenXInset = 500;
final int myScreenYInset = 10;

dialog0.setBounds( 
    h.screenOriginX + myScreenXInset, 
    h.screenOriginY + h.screenHeight - myHeight - h.taskBarHeight - myScreenYInset,
    myWidth, myHeight);

dialog0.setVisible( true);

// I'll omit the creation of the grapicsConfiguration for now.
JFrame frameBalloonHerderGui = new JFrame( gc);

ScreenAndTaskBarHeights h = 
    getThisComponentsScreensTaskBarHeight( frameBalloonHerderGui);

final int myWidth = 1695;
final int myScreenInset = 10;

frameBalloonHerderGui.setBounds( 
    h.screenOriginX + myScreenInset,  
    h.screenOriginY + myScreenInset,
    myWidth, h.screenHeight - (myScreenInset * 2) - h.taskBarHeight);

frameBalloonHerderGui.setVisible( true);

The workaround I found is that the screenSize.x & .y = (0,0) for the display that has the TaskBar, and some big positive or negative numbers for the other displays.

The function below successfully implements this workaround. I also made a simple class so I could pass multiple values back to the caller as shown above.

// Add additional data members here to your liking.
static class ScreenAndTaskBarHeights
{
    int screenOriginX = -1;
    int screenOriginY = -1;
    int screenHeight  = -1;
    int taskBarHeight = -1;

    ScreenAndTaskBarHeights()
    {           
    }

    void setValues(
        int newScreenOriginX, int newScreenOriginY,
        int newScreenHeight, int newTaskBarHeight)
    {
        screenOriginX = newScreenOriginX;
        screenOriginY = newScreenOriginY;
        screenHeight  = newScreenHeight;
        taskBarHeight = newTaskBarHeight;
    }
}

static ScreenAndTaskBarHeights 
getThisComponentsScreensTaskBarHeight( Component c)
{
    ScreenAndTaskBarHeights screenAndTaskBarHeights =
        new ScreenAndTaskBarHeights();

    GraphicsConfiguration gc = c.getGraphicsConfiguration();

    Insets scnMax = Toolkit.getDefaultToolkit().getScreenInsets( gc);

    // This should be the TaskBar height specific to the gc that we 
    // passed in, but it's not :-(.
    //
    //      int taskBarHeight = scnMax.bottom;
    //
    // However, this seems to be a successful workaround:
    //
    Rectangle screenSize = gc.getBounds();

    boolean thisScreenHasTheToolbar =
        (screenSize.x == 0 && screenSize.y == 0);

    // Change scnMax.bottom to catch wherever you're worried that the
    // TaskBar may be lurking.
    //
    screenAndTaskBarHeights.setValues(
        screenSize.x, screenSize.y, screenSize.height,
        (thisScreenHasTheToolbar) ? scnMax.bottom : 0);

    return screenAndTaskBarHeights;     
}