【发布时间】:2020-11-01 04:59:27
【问题描述】:
我尝试布局三个 JPanel,使左侧面板占据大约 66% 的宽度,另外两个面板共享另外 33%。
为了正确计算布局,我遇到了这个有趣的行为,屏幕尺寸被正确确定为 4K 分辨率。
但是,ComponentEvent 仅报告 2575x1415,尽管 JFrame 按照通过扩展状态设置的全屏打开。最小化/最大化 JFRame 使其变为最小尺寸和全屏尺寸,但报告的尺寸保持不变。
这是为什么呢?
17:51:25.450 [main] INFO net.ck.game.ui.TestFrame - screen width height 3840 2160
17:51:25.615 [AWT-EventQueue-0] ERROR net.ck.game.ui.TestFrame - java.awt.Rectangle[x=-7,y=-7,width=2575,height=1415]
我的示例代码:
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JFrame;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class TestFrame extends JFrame
{
static final long serialVersionUID = 1L;
private static final Logger logger = (Logger) LogManager.getLogger(TestFrame.class);
public static void main(String[] args)
{
JFrame frame;
/**
* https://stackoverflow.com/questions/11497910/java-setfullscreenwindow-keep-on-top/11499100#11499100
*/
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice[] gs = ge.getScreenDevices();
for (int i = 0; i < gs.length; i++)
{
DisplayMode dm = gs[i].getDisplayMode();
int screenWidth = dm.getWidth();
int screenHeight = dm.getHeight();
logger.info("screen width height {} {}", screenWidth, screenHeight);
}
frame = new JFrame();
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
frame.setMinimumSize(new Dimension(900, 840));
frame.setVisible(true);
frame.toFront();
/**
* thanks to stackoverflow:
* https://stackoverflow.com/questions/2781939/setting-minimum-size-limit-for-a-window-in-java-swing
* https://stackoverflow.com/questions/8333187/how-to-check-current-window-size-in-java-swing
*/
frame.addComponentListener(new ComponentAdapter()
{
/**
* changing the component resize event to not have the UI smaller thank the
* minimum to show the three panels next stop, wondering how they can be
* enlarged accordingly
*/
public void componentResized(ComponentEvent ev)
{
logger.error(ev.getComponent().getBounds().toString());
Dimension d = frame.getSize();
Dimension minD = frame.getMinimumSize();
if (d.width < minD.width)
d.width = minD.width;
if (d.height < minD.height)
d.height = minD.height;
frame.setSize(d);
}
});
}
}
【问题讨论】:
-
我不使用 4k 屏幕,所以无法测试。我唯一的建议是通过将代码包装在
SwingUtilities.invokeLater()中来确保在 EDT 上执行 GUI 代码。 -
CompnentEvent 报告影响缩放的大小,即如果您在摇摆中绘制一个像素,如果您的操作系统设置为 200% 缩放,它实际上可能是屏幕上的 2x2 像素。由于您使用的是 4K 屏幕,这很有可能。
-
@weisj 啊,所以 DisplayMode 显示“实际未缩放的大小”,而 ComponentEvent 报告的大小考虑了缩放比例?嗯,有没有办法从 DisplayMode 确定缩放后的大小是多少?编辑:我忘了提:我检查过,我使用 150% 缩放,所以它加起来(有点)。
-
@camickr 谢谢你的提醒 - 原始代码在invokeLater()中,我实际上忘记将它添加到这里的示例中。