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

HelpMeImStuck :

When I try to run this code, it results in a JFrame that is slightly displaced to the right by around 10 pixels for some reason, and also the height of the window extends beyond the taskbar, when the desired effect is to make it finish AT the taskbar.

I've tried setting the jframe to Undecorated, which fixes the entire issue, everything ends up where it should be. But the second I set undecorated to false, it seems to displace and ruin the window's position.

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

}
SDJ :

The issue is that you are calling setPreferredSize within the constructor of your Component, so the sizing request it is applied to the content of the frame. When the JFrame creates the decoration, it adds to that dimension. The solution is to apply the call to setPreferredSize to the JFrame, for example within 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));
    // ...
}

Here is a demo program which, at least on my system, reproduces the problem and demonstrates the solution. Uncommenting 1 and commenting out 2 reproduces the problem. Reversing the commented out line solves it.

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=155402&siteId=1