From: Fencer on
On 2010-02-15 17:50, Fencer wrote:
[snip my OP]

Thanks for your replies. I've decided to take a look at GridBagLayout as
suggested. Since I'm a layout-newbie I wanted to be able to print the
state of a GridBagConstraints object, so I wrote this helper class:

package main;

import java.awt.GridBagConstraints;

public class PrintGridBagConstraints {

public static void print(GridBagConstraints gbc) {
String out = "";

out += "gridx: " + (gbc.gridx == GridBagConstraints.RELATIVE ?
"RELATIVE" : gbc.gridx) + "\n";
out += "gridy: " + (gbc.gridy == GridBagConstraints.RELATIVE ?
"RELATIVE" : gbc.gridy) + "\n";
out += "gridwidth: " + getGridHeightOrWidth(gbc.gridwidth) + "\n";
out += "gridheight: " + getGridHeightOrWidth(gbc.gridheight) + "\n";
out += "weightx: " + gbc.weightx + "\n";
out += "weighty: " + gbc.weighty + "\n";
out += "anchor: " + getAnchor(gbc.anchor) + "\n";
out += "fill: " + Fill.fromInt(gbc.fill).toString() + "\n";

System.out.print(out);
}

private static String getAnchor(int anchor) {
Anchor a = Anchor.fromInt(anchor);

if (a == Anchor.UNDEFINED) {
return anchor + " - undefined";
}
else {
return a.toString();
}
}

private static String getGridHeightOrWidth(int heightOrWidth) {
if (heightOrWidth == GridBagConstraints.RELATIVE) {
return "RELATIVE";
}
else if (heightOrWidth == GridBagConstraints.REMAINDER) {
return "REMAINDER";
}
else {
return Integer.toString(heightOrWidth);
}
}

/*
* There are three kinds of possible values: orientation relative,
baseline relative and absolute.
* Orientation relative values are interpreted relative to the
container's component orientation
* property, baseline relative values are interpreted relative to
the baseline and absolute
* values are not.
* The absolute values are: CENTER, NORTH, NORTHEAST, EAST,
SOUTHEAST, SOUTH, SOUTHWEST, WEST,
* and NORTHWEST.
* The orientation relative values are: PAGE_START, PAGE_END,
LINE_START, LINE_END,
* FIRST_LINE_START, FIRST_LINE_END, LAST_LINE_START and LAST_LINE_END.
* The baseline relvative values are: BASELINE, BASELINE_LEADING,
BASELINE_TRAILING, ABOVE_BASELINE,
* ABOVE_BASELINE_LEADING, ABOVE_BASELINE_TRAILING, BELOW_BASELINE,
BELOW_BASELINE_LEADING, and
* BELOW_BASELINE_TRAILING. The default value is CENTER.
*/
enum Anchor {
/* Absolute values start. */
CENTER(GridBagConstraints.CENTER, "Absolute"),
NORTH(GridBagConstraints.NORTH, "Absolute"),
NORTHEAST(GridBagConstraints.NORTHEAST, "Absolute"),
EAST(GridBagConstraints.EAST, "Absolute"),
SOUTHEAST(GridBagConstraints.SOUTHEAST, "Absolute"),
SOUTH(GridBagConstraints.SOUTH, "Absolute"),
SOUTHWEST(GridBagConstraints.SOUTHWEST, "Absolute"),
WEST(GridBagConstraints.WEST, "Absolute"),
NORTHWEST(GridBagConstraints.NORTHWEST, "Absolute"),
/* Absolute values end. */

/* Orientation relative values start. */
PAGE_START(GridBagConstraints.PAGE_START, "Orientation relative"),
PAGE_END(GridBagConstraints.PAGE_END, "Orientation relative"),
LINE_START(GridBagConstraints.LINE_START, "Orientation relative"),
LINE_END(GridBagConstraints.LINE_END, "Orientation relative"),
FIRST_LINE_START(GridBagConstraints.FIRST_LINE_START,
"Orientation relative"),
FIRST_LINE_END(GridBagConstraints.FIRST_LINE_END, "Orientation
relative"),
LAST_LINE_START(GridBagConstraints.LAST_LINE_START,
"Orientation relative"),
LAST_LINE_END(GridBagConstraints.LAST_LINE_END, "Orientation
relative"),
/* Orientation relative values end. */

/* Baseline relative values start. */
BASELINE(GridBagConstraints.BASELINE, "Baseline relative"),
BASELINE_LEADING(GridBagConstraints.BASELINE_LEADING,
"Baseline relative"),
BASELINE_TRAILING(GridBagConstraints.ABOVE_BASELINE_TRAILING,
"Baseline relative"),
ABOVE_BASELINE(GridBagConstraints.ABOVE_BASELINE, "Baseline
relative"),

ABOVE_BASELINE_LEADING(GridBagConstraints.ABOVE_BASELINE_LEADING,
"Baseline relative"),

ABOVE_BASELINE_TRAILING(GridBagConstraints.ABOVE_BASELINE_TRAILING,
"Baseline relative"),
BELOW_BASELINE(GridBagConstraints.BELOW_BASELINE, "Baseline
relative"),

BELOW_BASELINE_LEADING(GridBagConstraints.BELOW_BASELINE_LEADING,
"Baseline relative"),

BELOW_BASELINE_TRAILING(GridBagConstraints.BELOW_BASELINE_TRAILING,
"Baseline relative"),
/* Baseline relative values end. */

UNDEFINED(-1337, "");

public static Anchor fromInt(int value) {
for (Anchor a : Anchor.values()) {
if (a.ordinal() == value) {
return a;
}
}

return Anchor.UNDEFINED;
}

@Override
public String toString() {
return this.name() + " - " + type;
}

private Anchor(int value, String type) {
this.type = type;
}

private String type;
}

enum Fill {
NONE(GridBagConstraints.NONE),
HORIZONTAL(GridBagConstraints.HORIZONTAL),
VERTICAL(GridBagConstraints.VERTICAL),
BOTH(GridBagConstraints.BOTH),

UNDEFINED(-1337);

public static Fill fromInt(int value) {
for (Fill f : Fill.values()) {
if (f.ordinal() == value) {
return f;
}
}

return Fill.UNDEFINED;
}

private Fill(int value) {
}
}
}

Was there an easier way to do that instead of writing that code? :-)

The output from the public static print method() can look like:
gridx: RELATIVE
gridy: RELATIVE
gridwidth: REMAINDER
gridheight: 1
weightx: 0.0
weighty: 0.0
anchor: ABOVE_BASELINE - Baseline relative
fill: VERTICAL

Btw, I found a spelling error in the official documentation when writing
that code (that exists in the docs for both java 6 and 7). The word
relvative appears under the description of the anchor field (I've
retained it in my comment of my Anchor enum).

Armed with this helper class I will now try to work GridBagLayout work
as I want it. I have another control I want place in a particular place
apart from the centered JPanel in my OP. I will post back if I can't
make it work.

- F
From: Knute Johnson on
On 2/15/2010 2:13 PM, Fencer wrote:
> On 2010-02-15 17:50, Fencer wrote:
> [snip my OP]
>
> Thanks for your replies. I've decided to take a look at GridBagLayout as
> suggested. Since I'm a layout-newbie I wanted to be able to print the
> state of a GridBagConstraints object, so I wrote this helper class:
>
> package main;
>
> import java.awt.GridBagConstraints;
>
> public class PrintGridBagConstraints {
>
> public static void print(GridBagConstraints gbc) {
> String out = "";
>
> out += "gridx: " + (gbc.gridx == GridBagConstraints.RELATIVE ?
> "RELATIVE" : gbc.gridx) + "\n";
> out += "gridy: " + (gbc.gridy == GridBagConstraints.RELATIVE ?
> "RELATIVE" : gbc.gridy) + "\n";
> out += "gridwidth: " + getGridHeightOrWidth(gbc.gridwidth) + "\n";
> out += "gridheight: " + getGridHeightOrWidth(gbc.gridheight) + "\n";
> out += "weightx: " + gbc.weightx + "\n";
> out += "weighty: " + gbc.weighty + "\n";
> out += "anchor: " + getAnchor(gbc.anchor) + "\n";
> out += "fill: " + Fill.fromInt(gbc.fill).toString() + "\n";
>
> System.out.print(out);
> }
>
> private static String getAnchor(int anchor) {
> Anchor a = Anchor.fromInt(anchor);
>
> if (a == Anchor.UNDEFINED) {
> return anchor + " - undefined";
> }
> else {
> return a.toString();
> }
> }
>
> private static String getGridHeightOrWidth(int heightOrWidth) {
> if (heightOrWidth == GridBagConstraints.RELATIVE) {
> return "RELATIVE";
> }
> else if (heightOrWidth == GridBagConstraints.REMAINDER) {
> return "REMAINDER";
> }
> else {
> return Integer.toString(heightOrWidth);
> }
> }
>
> /*
> * There are three kinds of possible values: orientation relative,
> baseline relative and absolute.
> * Orientation relative values are interpreted relative to the
> container's component orientation
> * property, baseline relative values are interpreted relative to the
> baseline and absolute
> * values are not.
> * The absolute values are: CENTER, NORTH, NORTHEAST, EAST, SOUTHEAST,
> SOUTH, SOUTHWEST, WEST,
> * and NORTHWEST.
> * The orientation relative values are: PAGE_START, PAGE_END, LINE_START,
> LINE_END,
> * FIRST_LINE_START, FIRST_LINE_END, LAST_LINE_START and LAST_LINE_END.
> * The baseline relvative values are: BASELINE, BASELINE_LEADING,
> BASELINE_TRAILING, ABOVE_BASELINE,
> * ABOVE_BASELINE_LEADING, ABOVE_BASELINE_TRAILING, BELOW_BASELINE,
> BELOW_BASELINE_LEADING, and
> * BELOW_BASELINE_TRAILING. The default value is CENTER.
> */
> enum Anchor {
> /* Absolute values start. */
> CENTER(GridBagConstraints.CENTER, "Absolute"),
> NORTH(GridBagConstraints.NORTH, "Absolute"),
> NORTHEAST(GridBagConstraints.NORTHEAST, "Absolute"),
> EAST(GridBagConstraints.EAST, "Absolute"),
> SOUTHEAST(GridBagConstraints.SOUTHEAST, "Absolute"),
> SOUTH(GridBagConstraints.SOUTH, "Absolute"),
> SOUTHWEST(GridBagConstraints.SOUTHWEST, "Absolute"),
> WEST(GridBagConstraints.WEST, "Absolute"),
> NORTHWEST(GridBagConstraints.NORTHWEST, "Absolute"),
> /* Absolute values end. */
>
> /* Orientation relative values start. */
> PAGE_START(GridBagConstraints.PAGE_START, "Orientation relative"),
> PAGE_END(GridBagConstraints.PAGE_END, "Orientation relative"),
> LINE_START(GridBagConstraints.LINE_START, "Orientation relative"),
> LINE_END(GridBagConstraints.LINE_END, "Orientation relative"),
> FIRST_LINE_START(GridBagConstraints.FIRST_LINE_START, "Orientation
> relative"),
> FIRST_LINE_END(GridBagConstraints.FIRST_LINE_END, "Orientation relative"),
> LAST_LINE_START(GridBagConstraints.LAST_LINE_START, "Orientation
> relative"),
> LAST_LINE_END(GridBagConstraints.LAST_LINE_END, "Orientation relative"),
> /* Orientation relative values end. */
>
> /* Baseline relative values start. */
> BASELINE(GridBagConstraints.BASELINE, "Baseline relative"),
> BASELINE_LEADING(GridBagConstraints.BASELINE_LEADING, "Baseline relative"),
> BASELINE_TRAILING(GridBagConstraints.ABOVE_BASELINE_TRAILING, "Baseline
> relative"),
> ABOVE_BASELINE(GridBagConstraints.ABOVE_BASELINE, "Baseline relative"),
>
> ABOVE_BASELINE_LEADING(GridBagConstraints.ABOVE_BASELINE_LEADING,
> "Baseline relative"),
>
> ABOVE_BASELINE_TRAILING(GridBagConstraints.ABOVE_BASELINE_TRAILING,
> "Baseline relative"),
> BELOW_BASELINE(GridBagConstraints.BELOW_BASELINE, "Baseline relative"),
>
> BELOW_BASELINE_LEADING(GridBagConstraints.BELOW_BASELINE_LEADING,
> "Baseline relative"),
>
> BELOW_BASELINE_TRAILING(GridBagConstraints.BELOW_BASELINE_TRAILING,
> "Baseline relative"),
> /* Baseline relative values end. */
>
> UNDEFINED(-1337, "");
>
> public static Anchor fromInt(int value) {
> for (Anchor a : Anchor.values()) {
> if (a.ordinal() == value) {
> return a;
> }
> }
>
> return Anchor.UNDEFINED;
> }
>
> @Override
> public String toString() {
> return this.name() + " - " + type;
> }
>
> private Anchor(int value, String type) {
> this.type = type;
> }
>
> private String type;
> }
>
> enum Fill {
> NONE(GridBagConstraints.NONE),
> HORIZONTAL(GridBagConstraints.HORIZONTAL),
> VERTICAL(GridBagConstraints.VERTICAL),
> BOTH(GridBagConstraints.BOTH),
>
> UNDEFINED(-1337);
>
> public static Fill fromInt(int value) {
> for (Fill f : Fill.values()) {
> if (f.ordinal() == value) {
> return f;
> }
> }
>
> return Fill.UNDEFINED;
> }
>
> private Fill(int value) {
> }
> }
> }
>
> Was there an easier way to do that instead of writing that code? :-)
>
> The output from the public static print method() can look like:
> gridx: RELATIVE
> gridy: RELATIVE
> gridwidth: REMAINDER
> gridheight: 1
> weightx: 0.0
> weighty: 0.0
> anchor: ABOVE_BASELINE - Baseline relative
> fill: VERTICAL
>
> Btw, I found a spelling error in the official documentation when writing
> that code (that exists in the docs for both java 6 and 7). The word
> relvative appears under the description of the anchor field (I've
> retained it in my comment of my Anchor enum).
>
> Armed with this helper class I will now try to work GridBagLayout work
> as I want it. I have another control I want place in a particular place
> apart from the centered JPanel in my OP. I will post back if I can't
> make it work.
>
> - F

Be sure to check out my GridBagLayout tester program at;

http://rabbitbrush.frazmtn.com/gridbagtester.html

--

Knute Johnson
email s/nospam/knute2010/

From: Fencer on
On 2010-02-16 06:17, Knute Johnson wrote:
>> - F
>
> Be sure to check out my GridBagLayout tester program at;
>
> http://rabbitbrush.frazmtn.com/gridbagtester.html
>

Thanks for that link, I will be sure to bookmark it! Below is my updated
program: It has a "group panel" in the center. The group panel holds two
buttons on the same line with space around them. At the bottom of
frame's content pane I have label acting as a status bar.

I know the code is overly verbose, it's for my learning purposes. I
can't say I have mastered GridBagLayout at all yet, but I can say I will
be using it from now on as much as I can so I do learn it.

One question about my program code, if I want to make the buttons have
the same width, how should I do that? Basically I want the button with
longest text to have its preferred width then increase the width of any
thinner buttons. In my case the button labeled "Open BioModel" should
have its width increased to match that of the button labeled "Load Saved
Session".

Here's the complete code:

package main;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.TitledBorder;

public class CenteredGroup {

public CenteredGroup() {
frame = new JFrame("BioModel explorer");

frame.setSize(640, 480);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

contentPane = (JPanel)frame.getContentPane();

contentPane.setLayout(new GridBagLayout());

JPanel groupPanel = new JPanel();

groupPanel.setPreferredSize(new Dimension(480, 100));
groupPanel.setBorder(new TitledBorder("Start a new session by
opening a BioModel or load a previously saved session"));
groupPanel.setLayout(new GridBagLayout());

JButton b1 = new JButton("Open BioModel");
JButton b2 = new JButton("Load Saved Session");

addButtonsToGroupPanel(groupPanel, b1, b2);

addGroupPanel(groupPanel);

statusLabel = new JLabel("My Status Bar");

statusLabel.setBorder(BorderFactory.createLineBorder(Color.BLUE,10));

addStatusLabel(statusLabel);
}

public void show() {
frame.setVisible(true);
}

protected void addGroupPanel(JPanel groupPanel) {
GridBagConstraints gbc = new GridBagConstraints();

gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.NONE;

contentPane.add(groupPanel, gbc);
}

protected void addStatusLabel(JLabel statusLabel) {
GridBagConstraints gbc = new GridBagConstraints();

gbc.gridx = 0;
gbc.gridy = 2;
gbc.gridwidth = 3;
gbc.gridheight = 1;
gbc.weightx = 0;
gbc.weighty = 0;
gbc.anchor = GridBagConstraints.LAST_LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;

frame.getContentPane().add(statusLabel, gbc);
}

protected void addButtonsToGroupPanel(JPanel groupPanel, JButton b1,
JButton b2) {
GridBagConstraints gbc = new GridBagConstraints();

gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.weightx = 0.5;
gbc.weighty = 0;
gbc.anchor = GridBagConstraints.CENTER;
gbc.fill = GridBagConstraints.NONE;

groupPanel.add(b1, gbc);

gbc.gridx = 1;

groupPanel.add(b2, gbc);
}

public static void main(String[] args) {
CenteredGroup inst = new CenteredGroup();

inst.show();
}

private JFrame frame = null;

private JPanel contentPane = null;

private JLabel statusLabel = null;
}

- F
From: markspace on
Fencer wrote:

> One question about my program code, if I want to make the buttons have
> the same width, how should I do that?


I just click the "same size" button. (In the code below, I think that's
implemented with the jPanel1Layout.linkSize(...) call.)

Here's some code that took me less than five minutes to lay out in a GUI
editor. It's not exactly the same as your code, but I did it by eye
rather than carefully copying what you did. And the buttons are
constrained to be the same size.

/*
* BioModelExplorer.java
*
* Created on Feb 16, 2010, 12:55:06 PM
*/

package test;


public class BioModelExplorer extends javax.swing.JFrame {

/** Creates new form BioModelExplorer */
public BioModelExplorer() {
initComponents();
}

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

jPanel1 = new javax.swing.JPanel();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
jPanel2 = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();


setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);


jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Start a
new session"));

jButton1.setText("Open BioModel");

jButton2.setText("Load a Saved Session");

javax.swing.GroupLayout jPanel1Layout = new
javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(

jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(28, 28, 28)
.addComponent(jButton1,
javax.swing.GroupLayout.PREFERRED_SIZE, 103,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(76, 76, 76)
.addComponent(jButton2,
javax.swing.GroupLayout.PREFERRED_SIZE, 137,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(45, Short.MAX_VALUE))
);

jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL,
new java.awt.Component[] {jButton1, jButton2});

jPanel1Layout.setVerticalGroup(

jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel1Layout.createSequentialGroup()
.addGap(36, 36, 36)

..addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jButton2)
.addComponent(jButton1))
.addContainerGap(41, Short.MAX_VALUE))
);


jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new
java.awt.Color(51, 51, 255), 10));

jLabel1.setText("Status bar...");

javax.swing.GroupLayout jPanel2Layout = new
javax.swing.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(

jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanel2Layout.createSequentialGroup()
.addContainerGap()
.addComponent(jLabel1)
.addContainerGap(399, Short.MAX_VALUE))
);
jPanel2Layout.setVerticalGroup(

jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING,
jPanel2Layout.createSequentialGroup()
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE,
Short.MAX_VALUE)
.addComponent(jLabel1)
.addContainerGap())
);

javax.swing.GroupLayout layout = new
javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()

..addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

..addGroup(javax.swing.GroupLayout.Alignment.TRAILING,
layout.createSequentialGroup()
.addComponent(jPanel2,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.addContainerGap())

..addGroup(javax.swing.GroupLayout.Alignment.TRAILING,
layout.createSequentialGroup()
.addComponent(jPanel1,
javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(44, 44, 44))))
);
layout.setVerticalGroup(

layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING,
layout.createSequentialGroup()
.addGap(156, 156, 156)
.addComponent(jPanel1,
javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)

..addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED,
118, Short.MAX_VALUE)
.addComponent(jPanel2,
javax.swing.GroupLayout.PREFERRED_SIZE,
javax.swing.GroupLayout.DEFAULT_SIZE,
javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap())
);

pack();
}// </editor-fold>

/**
* @param args the command line arguments
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new BioModelExplorer().setVisible(true);
}
});
}

// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JLabel jLabel1;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
// End of variables declaration

}
From: Knute Johnson on
On 2/16/2010 12:40 PM, Fencer wrote:
> Thanks for that link, I will be sure to bookmark it! Below is my updated
> program: It has a "group panel" in the center. The group panel holds two
> buttons on the same line with space around them. At the bottom of
> frame's content pane I have label acting as a status bar.
>
> I know the code is overly verbose, it's for my learning purposes. I
> can't say I have mastered GridBagLayout at all yet, but I can say I will
> be using it from now on as much as I can so I do learn it.
>
> One question about my program code, if I want to make the buttons have
> the same width, how should I do that? Basically I want the button with
> longest text to have its preferred width then increase the width of any
> thinner buttons. In my case the button labeled "Open BioModel" should
> have its width increased to match that of the button labeled "Load Saved
> Session".

GBL can make them the same width really easily if they are vertically
aligned with the fill element. Horizontally like that is a little more
difficult. You have to resort to tricks. Once you know the size of the
bigger one which you only will after the container is sized then you can
set the smaller one to the same size.

I have recreated your code to give you a simpler way of presenting your
application. One note, only one GridBagConstraints object is usually
necessary. Just adjust the fields and add your component with a
reference to the GBC and change the fields as necessary. You will see
in the example below I use only one but for two different components.

Also, you don't need to get at the ContentPane any more before adding
components to a JFrame. The add method has been overridden to add the
components to the ContentPane of the JFrame.

Back to the trick. Use a ComponentListener to check for a component
resized event. A resize event is triggered when the component is first
sized for display. Then set the preferred size of the other component
and call revalidate() which causes the component to be redrawn and
triggers another resized event.

The only other thing I might mention is that you have too many fixed
sizes for panels and frames. Usually one creates the content and then
calls pack() on the frame to size your application. That's not always
possible however but given wide range of display resolutions these days,
it is sometimes better to have fixed sizes. My example below uses your
sizes however.

Oh, and one other thing. Swing (JFrame, JWindow etc) GUI creation must
occur on the Event Dispatch Thread (search Google for EDT). That is
accomplished many ways but the simplest is to use the
EventQueue.invokeLater() method to wrap all GUI creation code.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class CG extends JFrame {
public CG() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridBagLayout());

GridBagConstraints c = new GridBagConstraints();

JPanel p = new JPanel(new GridBagLayout());
p.setPreferredSize(new Dimension(480,100));
p.setBorder(new TitledBorder("Panel Border"));

c.gridx = 0;
c.weightx = 1.0;
final JButton b1 = new JButton("Press Me");
p.add(b1,c);

c.gridx = 1;
final JButton b2 = new JButton("Please Don't Press Me");
p.add(b2,c);

b1.addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent ce) {
b1.setPreferredSize(b2.getPreferredSize());
b1.revalidate();
System.out.println(b1.getSize());
System.out.println(b2.getSize());
}
});

c.gridx = c.gridy = 0;
c.weighty = 1.0; // c.weightx is still 1.0
c.anchor = GridBagConstraints.CENTER;
add(p,c);

c.gridy = 1;
c.weighty = 0.1; // the panel above gets most of the weighty
c.fill = GridBagConstraints.HORIZONTAL; // c.weightx is still 1.0
c.anchor = GridBagConstraints.SOUTH;
JLabel l = new JLabel(
"Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah Blah
Blah");
l.setBorder(BorderFactory.createLineBorder(Color.BLUE,10));
add(l,c);
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
CG cg = new CG();
cg.setSize(640,480);
cg.setLocationRelativeTo(null);
cg.setVisible(true);
}
});
}
}

--

Knute Johnson
email s/nospam/knute2010/