Java: JFrame has different sizes on different screens?

La
3

I've been working continuously on a Java program for several years. The main window is a JFrame, i.e. The class inherits from JFrame. The problem is that the JFrame changes size when I use a different monitor or computer.

On my desktop PC, the size is as I set it to be. However, when I start the program on my laptop in a Linux Mint live system, the main window shrinks by about 3 cm. This shifts my JLabel so that their texts merge when they are tied on the x-axis. Here is an excerpt from my code where I give the JFrame its properties:

// set globally
private static JMenuBar menuBar;
static JPanel contentPane;

// in the constructor
contentPane = new JPanel (null);
contentPane.setPreferredSize (new Dimension (571, 360));

this.setJMenuBar (menuBar);
this.add (contentPane);
this.setTitle ("My dear title");
this.setSize (571, 360);
this.setResizable (false);
Dimension dim = Toolkit.getDefaultToolkit (). GetScreenSize ();
this.setLocation (dim.width / 2 - this.getSize (). Width / 2, dim.height / 2 - this.getSize (). Height / 2);
this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
this.setVisible (true);

So how come the JFrame is shrinking? And how can I prevent that?

Incidentally, I've changed the program title here to something nonsensical. I only use the JPanel because I originally built the main window in the BlueJ IDE with a GUI builder and then inserted the code in Eclipse. I attach details about the monitors as a picture.

Thanks in advance for your help. If details are missing or you need more code, please ask; I will then edit the question afterwards.

Monitor PC:

Java: JFrame has different sizes on different screens

Monitor laptop:

Java: JFrame has different sizes on different screens - 1
Le

As far as I can see, you are using a layout manager for your frame at least, but you set the manager for the panel to zero. These managers are explicitly there to relieve you of the positioning and scaling of the elements, so that you don't get any major problems on different screens.

Use Layout Manager for each component in which you arrange other components. You can still specify desired sizes with setPreferredSize, there's nothing wrong with that.

I would remove the call to setResizable so that users can still freely decide how big the window should be. I find denying this functionality to be user-unfriendly.

Then I would exchange the call to setSize for pack. The window can calculate how much space it needs for its components.

PS.: I would also ask why the menu bar and content pane have to be static. It certainly works with object-bound attributes as well.

La

Thanks for your tips.

I checked my code again. I have not explicitly specified a layout manager for the JFrame. However, I found out via the getLayout () method of the JFrame class that my own seems to be using a BorderLayout.

Therefore I gave the JPanel a new BorderLayout () in the constructor instead of zero. I had to change the order of a control in which I added it to the JPanel, but the JFrame now looks a little tidier. The funny thing is that I also had to add an "empty", invisible control (in this case a JLabel) so that the last control (here a JButton) doesn't take up the entire size of the JFrame. But it works so far.

Unfortunately, the window to me - whether with setSize () or pack () - on my laptop is still about 3 cm too small. At least I was able to reduce the height by 20 pixels using the Layout Manager.

I can understand your objection to the setResizable. However, I wanted the main window to be of a fixed size because it is rather small. A window that is actually small and drawn larger doesn't look so good, I think.

The menu bar is no longer static. But I had to leave the JPanel as it is (and the other controls) because I want to access it within static methods. Tried to move the method that made the statics of several other methods necessary to a different class. Unfortunately it was not possible because my code is now too "overgrown" for it.

In any case, thanks again for your tips.

Le

I have not explicitly specified a layout manager for the JFrame.

Swing always automatically uses the Layout Manager, unless you explicitly deactivate / overwrite it (for the individual components). For a JFrame it is - exactly - a BorderLayout and a JPanel uses a FlowLayout by default.

The BorderLayout is primitively divided into areas (top, bottom, left, right, center), with the center being the most weighted. All elements that you do not explicitly classify in an area are packed in the middle. On the one hand, they take up most of the space and, on the other hand, they could overlap. With FlowLayout, on the other hand, the elements are pushed onto the surface one after the other and, if necessary, breaks are automatically inserted.

I would recommend either passing nothing to the panel's constructor or a modified FlowLayout (check out the possible constructor overloads: https://docs.oracle.com/....html#api).