Why jframe hides taskbar when maximized?

前端 未结 3 1868
不思量自难忘°
不思量自难忘° 2021-01-17 02:52

I\'m using setUndecorated(true); and getRootPane().setWindowDecorationStyle(JRootPane.FRAME); in my jFrame. This works great but now when I maximiz

3条回答
  •  伪装坚强ぢ
    2021-01-17 03:28

    Fortega answer worked however, some part is not needed (or no longer needed with Java 8):

    • The Rectangle does not need to be saved.
    • The code does not take into account dual screen configuration. In particular, the GraphicsConfiguration will change if the window change screen.
    • As far as I tested, the only required override is setExtendedState.

    When factoring dual screen configuration, at least on Windows, the below code does not work as intended:

    Rectangle maxBounds = new Rectangle(screenInsets.left + screenSize.x, 
                                        screenInsets.top + screenSize.y, 
                                        screenSize.x + screenSize.width - screenInsets.right - screenInsets.left,
                                        screenSize.y + screenSize.height - screenInsets.bottom - screenInsets.top);
    

    On the following dual screen set up:

    • Left screen 1920x1080 (not primary), position: -1920, 0
    • Right screen 1920x1080 (primary), position: 0, 0

    The maxBounds will contains negative x (-1920) but the setMaximizedBounds is somehow expecting a coordinate in the screen space (where (x,y) starts at (0,0)) , not the virtual screen:

    • It will set to setMaximizedBounds(x=-1920,y=0,width=1920,height=1050)
    • Windows will see the window on the left screen (because I have one taskbar per screen showing only window on that screen) however the window won't be shown on the screen because it is off bounds.
    • If the resolution of the screen, or worse, its scale factor (with a laptop, Windows 10 will apply a scale factor, ex: 25%, making the screen "not so" 1920x1080), then the above code does not adapt. For example, if my configuration have 3 screens with the right most being the primary, the window will badly display on the left and middle screen. I don't think I fixed this in the below code.

    The following code work on Windows, with dual screen:

      @Override
      public synchronized void setExtendedState(final int state) {
        if ((state & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH) {
          final GraphicsConfiguration cfg = getGraphicsConfiguration();
          final Insets screenInsets = getToolkit().getScreenInsets(cfg);
          final Rectangle screenBounds = cfg.getBounds();
          final int x = screenInsets.left + screenBounds.x * 0;
          final int y = screenInsets.top + screenBounds.y * 0;
          final int w = screenBounds.width - screenInsets.right - screenInsets.left;
          final int h = screenBounds.height - screenInsets.bottom - screenInsets.top;
          final Rectangle maximizedBounds = new Rectangle(x, y, w, h);
    
          System.out.println("cfg (" + cfg + ") screen.{bounds: " + screenBounds + ", insets: " + screenInsets + ", maxBounds: " + maximizedBounds);
    
          super.setMaximizedBounds(maximizedBounds);
        }
        super.setExtendedState(state);
      }
    

    On a simple JFrame:

    • Maximizing on the left screen ("screen=0") will print cfg (D3DGraphicsConfig[dev=D3DGraphicsDevice[screen=0],pixfmt=0]) screen.{bounds: java.awt.Rectangle[x=-1920,y=0,width=1920,height=1080], insets: java.awt.Insets[top=0,left=0,bottom=30,right=0], maxBounds: java.awt.Rectangle[x=0,y=0,width=1920,height=1050]
    • Maximizing on the right screen ("screen=1") will print cfg (D3DGraphicsConfig[dev=D3DGraphicsDevice[screen=1],pixfmt=0]) screen.{bounds: java.awt.Rectangle[x=0,y=0,width=1920,height=1080], insets: java.awt.Insets[top=0,left=0,bottom=30,right=0], maxBounds: java.awt.Rectangle[x=0,y=0,width=1920,height=1050]

提交回复
热议问题