2

What is the correct way to display a Java JFrame Window on Linux (and here under different Window Managers), Mac and Windows allways in the same way?

We have actually some trouble with a JFrame, that is very inconsistent because on Windows the JFrame is maximized, on my Linux Notebook with awesome WM, the Window is only packed, and under Mac the Window gets half maximized, so its bigger then on Linux but not packed...

We tried to set the Screen just to the Maximium Size, which seems to work very well under windows, but not under Mac and Linux (Awesome WM).

Here is a very simple Frame, which explains what we are doing currently:

import java.awt.Dimension;
import java.awt.Toolkit;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class JFrameMaximize extends JFrame {
    private static final long serialVersionUID = 1L;

    public JFrameMaximize() {
    setVisible(true);
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    JPanel panel = new JPanel();
    // A Fake Dimension, inside this panel are a lot of swing components
    panel.setPreferredSize(new Dimension(333, 666));

    setContentPane(panel);

    // Now we want to set the Extended State
    if (Toolkit.getDefaultToolkit().isFrameStateSupported(MAXIMIZED_BOTH)) {
        setExtendedState(MAXIMIZED_BOTH);
    } else {
        System.out.println("Oh oh... i have a problem...");

        // Now we need a Fullscreen but we dont have the size of a WindowManager Panels and
        // stuff
        Dimension max = Toolkit.getDefaultToolkit().getScreenSize();
        // asume that the screen has a 20px bar on top (=awesome wm)
        max.height -= 20;
        setSize(max);
        setLocation(0, 20);
        // The alternative is to call pack() here, but then the window is totally broken, because of the internal components. Every Panel we load in here has a different size, so the window will scale up and down on every panel change.
    }
    }

    public static void main(String... args) {
    new JFrameMaximize();
    }
}

the problem is that some Window Managers dont have the Maximize_both extendend state, so we have to calculate - which is impossible to know for every PC! How do we can set the window to a correct size on every window manager?

Is the only solution a fixed default size, which is given to the JFrame? and the try to maximize the window?

reox
  • 5,036
  • 11
  • 53
  • 98

1 Answers1

1

Some observations:

  • Always start on the event dispatch thread.

  • Invoke pack() then adjust the frame size then do setVisible().

  • Consider using getMaximumWindowBounds():

    GraphicsEnvironment env =
        GraphicsEnvironment.getLocalGraphicsEnvironment();
    Rectangle bounds = env.getMaximumWindowBounds();
    

Revised sscce:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Toolkit;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class JFrameMaximize extends JFrame {

    public JFrameMaximize() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        JPanel panel = new JPanel();
        // A fake panel representing many swing components
        panel.setPreferredSize(new Dimension(333, 666));
        panel.setBorder(BorderFactory.createLineBorder(Color.blue, 10));
        this.add(panel);
        this.pack();
        // Now we want to set the Extended State, if supported
        if (Toolkit.getDefaultToolkit().isFrameStateSupported(MAXIMIZED_BOTH)) {
            System.out.println("Frame state supported.");
            this.setExtendedState(MAXIMIZED_BOTH);
        } else {
            System.out.println("Frame state not supported.");
            Dimension max = Toolkit.getDefaultToolkit().getScreenSize();
            // TODO see getMaximumWindowBounds()
            max.height -= 20;
            this.setSize(max);
            this.setLocation(0, 20);
        }
        this.setVisible(true);
    }

    public static void main(String... args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new JFrameMaximize();
            }
        });
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • okay but what i do in this case? `getMaximumWindowBounds(): java.awt.Rectangle[x=0,y=0,width=1280,height=800] getScreenSize(): java.awt.Dimension[width=1280,height=800]`- my windowmanager does not care about... – reox Jan 19 '12 at 08:56
  • Ouch! I see useful numbers on Aqua and GTK+. Your result sounds like an implementation defect. You may be stuck with a magic number in that case. Can you condition it on some property like `os.name`? – trashgod Jan 19 '12 at 10:27
  • i made the choise to detect these bad window managers: i check if getScreenSize and getMaximumWindowBounds gives the same result (if i cant set the extended state) and then give the window a certain size. in the most cases these window managers has their own resizing, or just show the app in fullscreen, so i think it will work out good enough... – reox Jan 19 '12 at 15:14
  • I don't know of a better workaround. Ping me if you add an answer with any new findings that arise. – trashgod Jan 19 '12 at 19:34