0

Here is the minimal example what problem I am facing in my main GUI design

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import javax.swing.BoxLayout;
class GuiTester
{

JFrame mainFrame = new JFrame();
JPanel panel = new JPanel();

GuiTester()
{

    JButton newButton = new JButton();
    JButton continueButton = new JButton();
    panel.setLayout(new BoxLayout( panel, BoxLayout.Y_AXIS));
    panel.add(newButton);
    panel.add(continueButton);
    panel.add(new JButton());
    panel.add(new JButton());
    panel.add(new JButton());
    mainFrame.getContentPane().add(panel);
    mainFrame.setLocationRelativeTo(null); // if I do it here then the display of window is little towards the right side down corner.
    mainFrame.pack();
    //mainFrame.setLocationRelativeTo(null) if I do it here instead of earlier than mainFrame.pack() it works great.
    mainFrame.setVisible(true);
}

public static void main(String[] args) {
    GuiTester gui = new GuiTester();
  }
}

So my question is that how pack() working differently when we do setLocationRelativeTo(null) prior to it and later to it?

And if we do setLocationRelativeTo(null) after pack() it works good.

Although the difference in this minimal example is not huge but in my actual working GUI this is creating a huge problem. Please explain.

EDIT My second question is that I have heard that it is recommended to call setVisible(true) or setReiszable(false) prior to pack(), why it is so?

OldSchool
  • 2,123
  • 4
  • 23
  • 45
  • 1
    See also [How to best position Swing GUIs?](http://stackoverflow.com/q/7143287/418556) in which the exact another different GUI positioning philosophy takes over. – Andrew Thompson Aug 05 '15 at 01:59
  • *"..have heard that it is recommended to call `setVisible(true)` or `setReiszable(false)` prior to `pack()`"* True for the 2nd, false for the 1st. But please limit each thread to one (specific) question. In this case, I feel that the 1st specific question has been [answered](http://stackoverflow.com/a/31822168/418556). – Andrew Thompson Aug 05 '15 at 02:01

1 Answers1

4

setLocationRelativeTo uses the current size of the window to make decisions about where it should be placed, since the window hasn't been sized yet, it's using 0x0, pack provides the initial size, so calling this first provides setLocationRelativeTo with the information it needs

You have to recognize that until a component is laid out (or in the case, until the is window packed or sized) it has no size.

For example...

mainFrame.setLocationRelativeTo(null);
mainFrame.pack();

This says, position the window, which is sized 0x0 to the center point of the screen, then use pack to provide an actual size

Where as...

mainFrame.pack();
mainFrame.setLocationRelativeTo(null);

Says, pack the frame to provide it with an initial size and the position it relative to the center of the screen, which takes into consideration windows size as calculated by pack

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I have also heard that we should call setVisible(true) or setResizable prior to pack, why it is so? – OldSchool Aug 05 '15 at 01:57
  • 1
    Actually, you should call `pack` before `setVisible`, or more to the point, call `setVisible` last. The point here is if you make the window visible first and then call `pack`, it can appear on the screen unpacked and the suddenly "pop" to the packed size, which is not a great user experience. You should call `setResizable` before `pack` because this can change the frame borders of the windows and can produce undesirable margins around the content. So, use `setResizable`, `pack`, `setVisible` in that order as a general rule of thumb ;) – MadProgrammer Aug 05 '15 at 01:59
  • Please have a look at this answer http://stackoverflow.com/questions/14595897/why-is-calling-jframe-pack-adding-extra-space – OldSchool Aug 05 '15 at 02:01
  • 1
    The accepted answer on that question (which is correct info.) is *"Make sure to call `setResizable(false)` before calling `pack()` or `setVisible(true)`"* .. Although it does not explicitly state that `setVisible(true)` should be called *last,* it is *implied* by the order of the method calls in that sentence. – Andrew Thompson Aug 05 '15 at 02:03
  • @AndrewThompson oh I misinterpreted that sorry – OldSchool Aug 05 '15 at 02:04
  • No problem. Glad I could help clarify it. :) – Andrew Thompson Aug 05 '15 at 02:05
  • 2
    But OK.. just to clear any remaining doubts. The reason to call `setResizable(false)` before `pack()` is that the window 'chrome' (decorations around the edges of the window) might change between resizable and non resizable modes. By packing the window *after* the resizable property is set, the API will account for the (typically thinner) chrome used for a non-resizable window. – Andrew Thompson Aug 05 '15 at 02:08
  • @AndrewThompson But how 'chrome' changes between resizable and non resizable modes? – OldSchool Aug 06 '15 at 12:20