尝试考虑 Java 中的任务栏会导致 window 大小不准确

Trying to account for taskbar in Java results in inaccurate window size

当我尝试 运行 这段代码时,它导致 JFrame 出于某种原因稍微向右移动了大约 10 个像素,而且 window 的高度超出了任务栏,当期望的效果是让它在任务栏完成时。

我试过将 jframe 设置为未装饰,这解决了整个问题,一切都在它应该在的地方结束。但是第二次我将 undecorated 设置为 false,它似乎取代并破坏了 window 的位置。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;

import javax.swing.JComponent;
import javax.swing.JFrame;

public class Component extends JComponent
{


/**
 * 
 */
private static final long serialVersionUID = 1L;

public int width, height;
public int tps;

private Game game;

public Component()
{
    Toolkit kit = this.getToolkit();
    width = (int) kit.getScreenSize().getWidth();
    height = (int) GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().getHeight();
    setLayout(new BorderLayout());
    setPreferredSize(new Dimension(width, height));

    game = new Game(this);
    add(game);

    initWindow("Test", this);
}

public void initWindow(String title, JComponent component)
{
    JFrame jf = new JFrame(title);
    jf.setResizable(false);
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    jf.add(component);
    jf.pack();
    jf.setLocationRelativeTo(null);

    jf.setVisible(true);
}

}

问题是您在 Component 的构造函数中调用 setPreferredSize,因此它的大小调整请求应用于 content框架。当 JFrame 创建装饰时,它会添加到该维度。解决方案是将对 setPreferredSize 的调用应用到 JFrame,例如在 initWindow:

public void initWindow(String title, JComponent component)
{
    JFrame jf = new JFrame(title);
    Toolkit kit = this.getToolkit();
    int width = (int) kit.getScreenSize().getWidth();
    int height = (int) GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().getHeight();
    jf.setPreferredSize(new Dimension(width, height));
    // ...
}

这是一个演示程序,至少在我的系统上,它重现了问题并演示了解决方案。取消注释 1 并注释掉 2 会重现问题。反转注释掉的那一行就解决了。

public class FitToScreenDemo {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JComponent component = new JComponent() {};
        frame.add(component);
//      component.setPreferredSize(getDimensionWithoutTaskBar()); // 1
        frame.setPreferredSize(getDimensionWithoutTaskBar());     // 2
        frame.pack();
        frame.setVisible(true);
    }

    private static Dimension getDimensionWithoutTaskBar() {
        return new Dimension((int) Toolkit.getDefaultToolkit().getScreenSize().getWidth(),
            (int) GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().getHeight());
    }
}