【发布时间】:2020-09-10 11:43:51
【问题描述】:
在 Windows 10 上采用 OpenJDK 11。JFrame 后代构造函数:
getGraphicsConfiguration().getBounds()
java.awt.Rectangle[x=0,y=0,width=2560,height=1440]
Toolkit.getDefaultToolkit().getScreenInsets(getGraphicsConfiguration())
java.awt.Insets[top=0,left=0,bottom=40,right=0]
set*Size(new Dimension(2560, 1400));
pack();
getSize();
java.awt.Dimension[width=2560,height=1400]
getInsets();
java.awt.Insets[top=31,left=8,bottom=8,right=8]
getContentPane().getSize()
java.awt.Dimension[width=2544,height=1361]
...但窗口并没有覆盖整个桌面空间减去任务栏(因为那些额外的 8 插图)。为什么?
使用我的答案的示例代码:
package javaapplication2;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GraphicsConfiguration;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JPanel;
public final class TestFrame extends JFrame {
private static final long serialVersionUID = 1L;
private static final class CustomPanel extends JPanel {
private static final long serialVersionUID = 1L;
public CustomPanel(Dimension d) {
setMinimumSize(d);
setPreferredSize(d);
setMaximumSize(d);
//this is just an example, there is custom layout code here, not using Swing, but it needs Dimension d to work
}
}
public TestFrame() {
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
GraphicsConfiguration gc = getGraphicsConfiguration();
Rectangle screenBounds = gc.getBounds();
Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets(gc);
Dimension expectedFrameSize = new Dimension(screenBounds.width - screenInsets.left - screenInsets.right, screenBounds.height - screenInsets.top - screenInsets.bottom);
setExtendedState(JFrame.MAXIMIZED_BOTH);
setVisible(true);
Dimension frameSize = getSize();
Insets frameInsets = getInsets();
setVisible(false);
Dimension contentSize = new Dimension(frameSize.width - frameInsets.left - frameInsets.right, frameSize.height - frameInsets.top - frameInsets.bottom);
getContentPane().add(new CustomPanel(contentSize));
setVisible(true);
setResizable(false);
System.out.println("screenBounds " + screenBounds);
System.out.println("screenInsets " + screenInsets);
System.out.println("expectedFrameSize " + expectedFrameSize);
System.out.println("frameSize " + frameSize);
System.out.println("frameInsets " + frameInsets);
System.out.println("contentSize " + contentSize);
System.out.println("assert expectedFrameSize == frameSize " + expectedFrameSize.equals(frameSize));
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new TestFrame().setVisible(true);
}
});
}
}
我希望能够计算Dimension dimension 而不使窗口暂时可见。但是使用 JDK 中可用的方法无法得出正确的大小:
getGraphicsConfiguration().getBounds()
Toolkit.getDefaultToolkit().getScreenInsets(getGraphicsConfiguration())
【问题讨论】:
-
框架的插图是框架的一部分,因此它确实覆盖了桌面空间。你究竟想要什么? a) maximize the frame, b) a borderless window, 或 c) a fullscreen window?
-
当前框架并没有像最大化的窗口那样占用整个桌面空间。在左边、右边和底部有几个像素宽(我猜是 8 像素宽)的条带,下面的窗口是可见的。我还需要在显示框架之前计算内容窗格的大小,因为很多事情都取决于这个大小。所以我想计算最大化的大小,并将其设置为那个大小,而不是实际最大化。因此,尽管它说框架是 2560 宽,但我不能在这些波段中看到其他窗口,而且我的显示器肯定是 2560 宽。
-
操作系统(或其桌面)决定如何表示边框。如果它决定有一个半透明的阴影,它算作边框的一部分,那就是它的方式。同样,不清楚你想要什么。如果您想要与最大化框架相同的行为,那么为什么不最大化它呢?如果你不想有边框,为什么不关闭边框呢?如果您只想在显示之前知道内容窗格的大小,为什么不使用您自己发布的代码,这表明在显示框架之前,
pack()之后的大小是已知的? -
然后致电
setExtendedState(MAXIMIZED_BOTH)。或者提供一个易于理解的解释,为什么您不能选择使用专门用于该目的的 API。 -
所以你的问题是
setExtendedState(JFrame.MAXIMIZED_BOTH)在框架不可见时不会立即影响框架的大小? size 是屏幕大小减去 screen insets,还要减去标题栏(但不包括上边框),其大小没有查询 API。如果那是你的问题,你应该一开始就这么说,而不是试图模仿setExtendedState。