为什么jframe在最大化时会隐藏任务栏?

时间:2011-06-21 09:13:34

标签: java swing jframe taskbar

我在jFrame中使用setUndecorated(true);getRootPane().setWindowDecorationStyle(JRootPane.FRAME);。这很好但现在当我最大化我的框架时,它甚至遍布整个窗口甚至任务栏都不可见。如何使框架不隐藏任务栏?

此外,当我多次最小化我的帧时,光标会更改为此<->,当光标位于帧的边框上时,通常会更改帧的大小。我能为此做点什么吗?


然后一个小代码可以重现这个东西:

import javax.swing.JFrame;
import javax.swing.JRootPane;
public class Demo extends JFrame {
    public Demo() {
        setSize(250,125);
        setUndecorated(true);
        getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
        setVisible(true);
    }
    public static void main(String[] args) {
        new Demo();
    }
}

4 个答案:

答案 0 :(得分:5)

这是一个已知错误:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4737788

从这个链接引用:

  

解决方法是继承JFrame和   覆盖setExtendedState方法,   抓住任何最大化事件之前   它们发生并设定最大值   适当的框架范围   在调用超类之前   setExtendedState方法。

import java.awt.*;
import javax.swing.*;

public class PFrame extends JFrame
{
private Rectangle maxBounds;

public PFrame()
{
    super();        
    maxBounds = null;
}

//Full implementation has other JFrame constructors

public Rectangle getMaximizedBounds()
{
    return(maxBounds);
}

public synchronized void setMaximizedBounds(Rectangle maxBounds)
{
    this.maxBounds = maxBounds;
    super.setMaximizedBounds(maxBounds);
}

public synchronized void setExtendedState(int state)
{       
    if (maxBounds == null &&
        (state & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_BOTH)
    {
        Insets screenInsets = getToolkit().getScreenInsets(getGraphicsConfiguration());         
        Rectangle screenSize = getGraphicsConfiguration().getBounds();
        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);
        super.setMaximizedBounds(maxBounds);
    }

    super.setExtendedState(state);
}
}

答案 1 :(得分:0)

也许您可以设置jFrame的最大大小,并根据屏幕大小对其进行限制。

修改

另请查看setExtendedState

答案 2 :(得分:0)

Fortega答案有效,但是不需要某些部分(或者Java 8不再需要):

  • Rectangle不需要保存。
  • 该代码未考虑双屏配置。特别是,如果窗口更改屏幕,GraphicsConfiguration也会更改。
  • 据我测试,唯一需要覆盖的是setExtendedState

在考虑双屏配置时,至少在Windows上 ,以下代码无法正常工作:

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);

在以下双屏设置中:

  • 左屏幕1920x1080(非主要屏幕),位置:-1920、0
  • 右屏幕1920x1080(主屏幕),位置:0、0

maxBounds将包含负x(-1920),但是setMaximizedBounds某种程度上期望屏幕空间中的坐标(其中(x,y)(0,0)开始),而不是虚拟屏幕:

  • 它将设置为setMaximizedBounds(x=-1920,y=0,width=1920,height=1050)
  • Windows将在左侧屏幕上看到该窗口(因为每个屏幕上只有一个任务栏,仅在该屏幕上显示该窗口),但是该窗口不会显示在屏幕上,因为它是越界的。
  • 如果屏幕的分辨率或更糟糕的是其缩放比例(对于笔记本电脑,Windows 10将应用缩放比例,例如:25%,使屏幕“不是” 1920x1080),则上述代码不适应。例如,如果我的配置有3个屏幕,其中最右边是主要屏幕,则该窗口将在左侧和中间屏幕上显示不佳。我认为我无法在以下代码中解决此问题。

以下代码在Windows(双屏)上运行:

  @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);
  }

在简单的JFrame上:

  • 在左侧屏幕(“ screen = 0”)上最大化将打印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]
  • 在右侧屏幕(“ screen = 1”)上最大化将打印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]

答案 3 :(得分:0)

从 Fortega 答案开始,即使添加 125% 屏幕 sizi,您也可以使其工作

Rectangle screenSize = getGraphicsConfiguration().getBounds();
GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
screenSize.setSize(new Dimension(gd.getDisplayMode().getWidth(), gd.getDisplayMode().getHeight()));
......