Controlling GridBagLayout layout

I am arranging components on JFrame, but doesn’t seem to work correctly. I use GridBagLayout, but wasn’t successful. I am trying to center "checkoutBtn" and "checkinBtn"

If you want to see exact illustratoin follow the below link.

http://webdev.apl.jhu.edu/%7Emed/fall03/homework/04LibrarySwing.html

My code is the following:

//set library panel
    constraints.weightx = 1000;
    constraints.weighty = 1;
    constraints.fill = GridBagConstraints.BOTH;
    addComponent(libraryPanel, 0, 0, 5, 6);

    //set checkoutBtn
    constraints.weightx = 0;
    constraints.weighty = 0;
    constraints.fill = GridBagConstraints.NONE;
    addComponent(checkoutBtn, 5, 2, 1, 1);

    //set check in button
    constraints.weightx = 0;
    constraints.weighty = 0;
    constraints.fill = GridBagConstraints.CENTER;
    addComponent(checkinBtn, 5, 3, 1, 1);

    //set checkoutlog Panel
    constraints.weightx = 1000;
    constraints.weighty = 1;
    constraints.fill = GridBagConstraints.BOTH;
    addComponent(checkoutlogPanel, 6, 0, 1, 6);



    private void addComponent(Component component,
                            int column, int row, int width, int height) {

    // set gridx and gridy
    constraints.gridx = column;
    constraints.gridy = row;

    // set gridwidth and gridheight
    constraints.gridwidth = width;
    constraints.gridheight = height;

    // set constraints and add component
    layout.setConstraints(component, constraints);
    contentPane.add(component, constraints);
  }











dkim18Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Mick BarryJava DeveloperCommented:
Personally I avoid using GBL (in fact never use it), I find BoxLayout a lot more intuitive and easier to use.
I'm sure a GBL expert is out there somewhere that can help you.
yongsingCommented:
I don't think you need a GridBagLayout. Just use a FlowLayout. For the check in and check out buttons, put them in a separate panel first, so that they will have the same size.

// Put check in and check out buttons on a panel
Panel panel = new JPanel(new GridLayout(1, 2));
panel.add(checkoutBtn);
panel.add(checkinBtn);

// Add all three panels to content pane
getContentPane().setLayout(new FlowLayout());
getContentPane().add(libraryPanel);
getContentPane().add(panel);
getContentPane().add(checkoutlogPanel)
zzynxSr. Software engineerCommented:
I guess this is the best you can do:
Since the width of your (check in/out) buttons is approximately the same as the width of "Patrons" this is what I should do:

* Panel 1: "In-Library"
* Panel 2: the buttons + "Check-out log"
   (use a BorderLayout with the buttons (in a panel) in the West, and the "Check-out log in the Center)

Now create a panel with a Gridlayout (with 0 columns and 1 row) where you add Panel 1 and Panel 2. (Panel 1 and Panel 2 always keep the same width)

Success
CompTIA Cloud+

The CompTIA Cloud+ Basic training course will teach you about cloud concepts and models, data storage, networking, and network infrastructure.

grim_toasterCommented:
As a question, what do you mean it doesn't work correctly?  What is happening that shouldn't be?  As I cannot recreate your problem (not enough code for starts), but I'm guessing that the following line:

constraints.fill = GridBagConstraints.CENTER;

should in fact be:

constraints.anchor = GridBagConstraints.CENTER;

API: fill - This field is used when the component's display area is larger than the component's requested size. It determines whether to resize the component, and if so, how.

API: anchor - This field is used when the component is smaller than its display area. It determines where, within the display area, to place the component
zzynxSr. Software engineerCommented:
>> grimm_toaster
>> As a question, what do you mean it doesn't work correctly?  
>> What is happening that shouldn't be?
Read carefully: He says: I am trying to center "checkoutBtn" and "checkinBtn"
grim_toasterCommented:
>> Read carefully: He says: I am trying to center "checkoutBtn" and "checkinBtn"

Yes I know what they're trying to do, but they don't say what's happening when they run it, for example does the button take up the full amount of space, is it left aligned?
dkim18Author Commented:
When I run it, two buttons are between two panels(libraryPanel and checklogoutPanel)
but located on upper area, so I am trying to lower those two buttons.

For more information, The display must work well even when resized. When growing beyond its preferred size, the buttons and labels should remain their preferred size (i.e. do not grow). The three GUI components containing employees, books and log entries shall grow to take up the extra space. When shrinking the display those three components will display scroll bars.

Do you think I have other options?
I know GBL works for sure, but it is just difficult to use.
zzynxSr. Software engineerCommented:
If you use my way of working then replace "the buttons" in Panel 2 by buttonsPanel.

Where

* buttonsPanel having a GridBagLayout
               containing panelX in the Center

* panelX having a FlowLayout (with Center alignment)
         containing panelY

* panelY having a GridLayout (0 rows, 1 column)
  [which keeps your two buttons having the same size]
         containing your button1 and button2

             
grim_toasterCommented:
dkim18:  Did you try changing the .fill to .anchor (for the Center one)?  Did that help?

zzynxSr. Software engineerCommented:
Since you want to use GBL, here's what you want:

    //set library panel
    constraints.weightx = 1000;
    constraints.weighty = 1;
    constraints.fill = GridBagConstraints.BOTH;
    addComponent(libraryPanel, 0, 0, 5, 6);

    buttonPanel.setLayout(new java.awt.GridBagLayout());

    //set checkoutBtn (in the buttonPanel)
    constraints.weightx = 0;
    constraints.weighty = 0;
    constraints.fill = GridBagConstraints.NONE;
    addToComponent(buttonPanel, checkoutBtn, 0, 0, 1, 1);

    //set check in button (in the buttonPanel)
    constraints.weightx = 0;
    constraints.weighty = 0;
    constraints.fill = GridBagConstraints.CENTER;
    addToComponent(buttonPanel, checkinBtn, 0, 1, 1, 1);

    // set buttonPanel
    addComponent(buttonPanel, 5, 0, 6, 1);

    //set checkoutlog Panel
    constraints.weightx = 1000;
    constraints.weighty = 1;
    constraints.fill = GridBagConstraints.BOTH;
    addComponent(checkoutlogPanel, 6, 0, 1, 6);


    private void addToComponent(Component parentComponent,
                                Component component,
                                int column, int row, int width, int height) {

    // set gridx and gridy
    constraints.gridx = column;
    constraints.gridy = row;

    // set gridwidth and gridheight
    constraints.gridwidth = width;
    constraints.gridheight = height;

    // set constraints and add component
    layout.setConstraints(component, constraints);
    parentComponent.add(component, constraints);
    }

Remark that I created a new function addToComponent()
A copy of your function but where you can pass the parent to add the component to.
Success.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
zzynxSr. Software engineerCommented:
The trick is to introduce a new JPanel ("buttonPanel" in the above containing the two buttons) which you place between the two other panels in the gridbaglayout
BUT with a height that equals the height of the other two panels. (6)

BTW,
I adapted the code to your GBL matrix, but you can simplify it.
You only need three columns; one for each panel.
And the height of each panel can be reduced from 6 to 1 too.
This gives:

//set library panel
    constraints.weightx = 1000;
    constraints.weighty = 1;
    constraints.fill = GridBagConstraints.BOTH;
    addComponent(libraryPanel, 0, 0, 1, 1);

    buttonPanel.setLayout(new java.awt.GridBagLayout());

    //set checkoutBtn (in the buttonPanel)
    constraints.weightx = 0;
    constraints.weighty = 0;
    constraints.fill = GridBagConstraints.NONE;
    addToComponent(buttonPanel, checkoutBtn, 0, 0, 1, 1);

    //set check in button (in the buttonPanel)
    constraints.weightx = 0;
    constraints.weighty = 0;
    constraints.fill = GridBagConstraints.CENTER;
    addToComponent(buttonPanel, checkinBtn, 0, 1, 1, 1);

    // set buttonPanel
    addComponent(buttonPanel, 1, 0, 1, 1);

    //set checkoutlog Panel
    constraints.weightx = 1000;
    constraints.weighty = 1;
    constraints.fill = GridBagConstraints.BOTH;
    addComponent(checkoutlogPanel, 2, 0, 1, 1);
dkim18Author Commented:
Your last line of "private void addToComponent" function gives me error.

parentComponent.add(component, constraints);

I think add method requires only one parameter.
dkim18Author Commented:
grim_toaster

 .fill to .anchor helped to even two button but not for the centering buttons
Mick BarryJava DeveloperCommented:
This may be useful from a general perspective:
http://java.sun.com/docs/books/tutorial/uiswing/layout/index.html
grim_toasterCommented:
Could you post a bit more of the code then?
zzynxSr. Software engineerCommented:
>> Your last line of "private void addToComponent" function gives me error.

Well, I thought it would be clearer to you if I kept the idea of using a function for the adding.
But I hope you got the idea. Yes? If not ask.

This is how I would (re)write it without the addToComponent:

    //set library panel
    constraints.weightx = 1000;
    constraints.weighty = 1;
    constraints.fill = GridBagConstraints.BOTH;
    addComponent(libraryPanel, 0, 0, 1, 1);

    buttonPanel.setLayout(new java.awt.GridBagLayout());

    java.awt.GridBagConstraints gridBagConstraints;
    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 0;
    buttonPanel.add(checkoutBtn, gridBagConstraints);

    gridBagConstraints = new java.awt.GridBagConstraints();
    gridBagConstraints.gridx = 0;
    gridBagConstraints.gridy = 1;
    buttonPanel.add(checkinBtn, gridBagConstraints);

    // set buttonPanel
    addComponent(buttonPanel, 1, 0, 1, 1);

    //set checkoutlog Panel
    constraints.weightx = 1000;
    constraints.weighty = 1;
    constraints.fill = GridBagConstraints.BOTH;
    addComponent(checkoutlogPanel, 2, 0, 1, 1);

Hope you get it right now.
I'm pretty sure it's the right solution.
dkim18Author Commented:
   JPanel libraryPanel = new JPanel(new GridLayout(1, 2));
    JPanel patronsPanel = new JPanel(new BorderLayout());
    JPanel bookPanel = new JPanel(new BorderLayout());

    //instantiate library panel's border and scrollpane
    libraryPanel.add(bookPanel, BorderLayout.BEFORE_FIRST_LINE);
    JScrollPane bookJSP = new JScrollPane(bookList);
    patronsPanel.add(bookJSP);

    //instantiate library panel's border and scrollpane
    libraryPanel.add(patronsPanel, BorderLayout.BEFORE_FIRST_LINE);
    JScrollPane patronsJSP = new JScrollPane(patronsList);
    bookPanel.add(patronsJSP);

    //instantiate patrons and book labels and its location
    patronsLabel = new JLabel("Patrons:");
    bookLabel = new JLabel("Available Books:");
    bookPanel.add(patronsLabel, BorderLayout.BEFORE_FIRST_LINE);
    patronsPanel.add(bookLabel, BorderLayout.BEFORE_FIRST_LINE);

    //instantiate check out panel, mode, border and label
    JPanel checkoutlogPanel = new JPanel(new BorderLayout());
    checkoutlogPanel.add(new JScrollPane(logList));
    checkoutlogPanel.add(logLabel, BorderLayout.BEFORE_FIRST_LINE);
    libraryPanel.setBorder(new TitledBorder(new EtchedBorder(), "In-Library"));
    checkoutlogPanel.setBorder(new TitledBorder(new EtchedBorder(),
                                    "Check-out Log"));


    constraints.weightx = 1000;
    constraints.weighty = 1;
    constraints.fill = GridBagConstraints.BOTH;
    addComponent(libraryPanel, 0, 0, 5, 6);


    constraints.weightx = 0;
    constraints.weighty = 0;
    constraints.anchor = GridBagConstraints.CENTER;
    addComponent(checkoutBtn, 5, 3, 1, 1);


    constraints.weightx = 0;
    constraints.weighty = 0;
    constraints.anchor = GridBagConstraints.CENTER;
    addComponent(checkinBtn, 5, 4, 1, 1);


    constraints.weightx = 1000;
    constraints.weighty = 1;
    constraints.fill = GridBagConstraints.BOTH;
    addComponent(checkoutlogPanel, 6, 0, 1, 6);

...
...
...
  private void addComponent(Component component,
                            int column, int row, int width, int height) {

    // set gridx and gridy
    constraints.gridx = column;
    constraints.gridy = row;

    // set gridwidth and gridheight
    constraints.gridwidth = width;
    constraints.gridheight = height;

    // set constraints and add component
    layout.setConstraints(component, constraints);
    contentPane.add(component, constraints);


  }
zzynxSr. Software engineerCommented:
Hi dkim18, that code is an answer to grim_toaster, right?

I see that you keep using widths more than 1.
I think you didn't get the idea:
   Simply place
     - your left libraryPanel at (0,0)
     - your buttonPanel at (1, 0)
     - your right checkoutlogPanel at (2,0)
   all having widths and heights of 1.
grim_toasterCommented:
Try putting the below in, I completely agree with zzynx that you will need to put the buttons in their own panel, but I'm also not too sure about your addComponent method, it gets a bit confusing!  Plus, really not sure what the layout.setConstraints(component, constraints); is for, as the add should sort everything out, but anyway...


        final JPanel buttonsPanel = new JPanel();
        buttonsPanel.setLayout(new GridBagLayout());

        constraints.gridx = GridBagConstraints.RELATIVE;
        constraints.insets = new Insets(10, 10, 10, 10);
        constraints.fill = GridBagConstraints.HORIZONTAL;
        buttonsPanel.add(checkoutBtn, constraints);
        constraints.gridy = 1;
        buttonsPanel.add(checkinBtn, constraints);
       
        constraints.gridy = 0;
        constraints.fill = GridBagConstraints.BOTH;
        constraints.weightx = 1;
        constraints.weighty = 1;
       
        this.getContentPane().add(libraryPanel, constraints);
        this.getContentPane().add(buttonsPanel, constraints);
        this.getContentPane().add(checkoutlogPanel, constraints);
grim_toasterCommented:
Oops, pretty similar to zzynx's code!  Sorry about that!  Should refresh before I post any comments... ;)
zzynxSr. Software engineerCommented:
>> to dkim18:
Remark that you can even leave all the weightx's to 1 (as in grim_toaster's example)
Life (and the use of GBL) can be easy, can't it? ;)
dkim18Author Commented:
I finally did it. It is hard to understand...
Thank you for all your help anyway.
zzynxSr. Software engineerCommented:
>> I finally did it. It is hard to understand...
Glad to hear that. I mean... the first part :)
>> Thank you for all your help anyway.
My pleasure.
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.