NhatNienne
NhatNienne

Reputation: 1061

GridBagLayout: Setting the position of components

I read some questions which stated that GBL is better than the normal GridLayout for positioning the components.

Links: first , second, Oracle Tutorial

Well so I tried to add some components (buttons) to my GBL but it somehow always centers my components. The only way to seperate the 2 Buttons is to place Dummies into my project which looks awful.

public class GridGUI extends JPanel {

private JButton button;

public GridGUI() {
    setLayout(new GridBagLayout());
    GridBagConstraints comps = makeGbc(0,1);
    JPanel panel = new JPanel();
    button = new JButton("Datei speichern");
    button.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // TODO Auto-generated method stub

        }

    });
    panel.add(button);
    add(panel,comps);

    comps = makeGbc(1,1);
    button = new JButton("Datei laden");
    panel.add(new JPanel());
    panel.add(new JPanel());
    panel.add(new JPanel());
    panel.add(new JPanel());
    panel.add(new JPanel());
    panel.add(new JPanel());
    panel.add(new JPanel());
    panel.add(new JPanel());
    panel.add(new JPanel());
    panel.add(new JPanel());
    panel.add(new JPanel());
    panel.add(button);
    add(panel,comps);
}

private GridBagConstraints makeGbc(int x, int y) {
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridwidth = 1;
    gbc.gridheight = 1;
    gbc.gridx = x;
    gbc.gridy = y;
    gbc.weightx = x;
    gbc.weighty = 1.0;
    gbc.insets = new Insets(5, 5, 5, 5);
    gbc.anchor = (x == 0) ? GridBagConstraints.LINE_START : GridBagConstraints.LINE_END;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    return gbc;
}

public static void showGUI() {
    JFrame frame = new JFrame("Pop-Art-Collage");
    frame.getContentPane().add(new GridGUI());
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.pack();
    frame.setSize(800, 800);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            showGUI();
        }

    });
}

}

The GUI

But I want them to appear at the top of the GUI and not in the center.

Also I tried to resize the buttons by using button.setSize(x,y) but they always stayed the same.

Thanks in advance

Edit:

Okay I tried now the solution I got but I got into some other problems.

    GridBagConstraints comps = makeGbc(0,1,20,50,0,0);
    button = new JButton("Datei speichern");
    button.setPreferredSize(new Dimension(200,25));
    add(button,comps);
    JButton button2 = new JButton("Datei laden");
    button2.setPreferredSize(new Dimension(100,25));
    comps = makeGbc(1,1,20,150,0,100);
    add(button2,comps);

new

Here is my problem that I set the prefered size for both buttons the same but it still doesnt show correctly for the second one. (the 4 Numbers after x,y of makeGbc are the Insets values top,left,bottom,right)

Upvotes: 1

Views: 1704

Answers (1)

m.cekiera
m.cekiera

Reputation: 5395

Your buttons are in the middle, not on the top, because you place it there:

gbc.anchor = (x == 0) ? GridBagConstraints.LINE_START : GridBagConstraints.LINE_END;

GridBagConstraints.LINE_END and GridBagConstraints.LINE_START puts components in the centere. Try with:

gbc.anchor = (x == 0) ? GridBagConstraints.FIRST_LINE_START : GridBagConstraints.FIRST_LINE_END;

Also:

  • try to set size of buttons with setPreferredSize(), GBL with frame.pack() should respect choosen sizes,

  • you add your buttons to new JPanels, and then to container with GBL, so it place your buttons in center. Add your buttons directly to GridGUI, and it will be placed according to GridBagConstraints(), for example:

    button = new JButton("Datei laden");
    add(button,makeGbc(1,1));
    
  • you use one class field JButton button, for two different buttons, this way you are not able to change first button state, after you change button reference - if you try to change for example text in button, from different part of application, by using button class field you can access only second button.

EDIT

I am not sure what effect you exactly want, but I would try to add your GridGUI first to new JPanel, then to JFrame (in main method):

JFrame frame = new JFrame("Pop-Art-Collage");
JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT)); //add FlowLayout.LEFT,
panel.add(new GridGUI());
frame.getContentPane().add(panel);

Now, the FlowLayout should keep all components to left, and you can control the space between buttons by changing insets. For first button, a would set all inputs to 0, and in second one, the new Insets(0,x,0,0), where x is desired distance. Like this:

add(button,makeGbc(0,1,0,0,0,0));
add(button2,makeGbc(0,1,0,150,0,0));

But I am not sure, how this set of layouts will behave when you add more components, so the easier way, is to use only frame.pack(), without frame.setSize(), and then extend it by adding new components. Then it should be easier to predict how changes will work.

Also pay attention to a fact, that in a example code above, you set different setPreferredSize() for both buttons.

Upvotes: 3

Related Questions