How to use GridBagConstraints to create the layout? - java

I want to layout my JPane like so:
-------
| |
| |
| |
-------
| |
-------
This way, the top section is bigger/taller than the bottom section (the top section consists of another JPanel and uses the Graphics object to display an image, while the bottom section also consists of another JPanel but uses the Graphics object to draw some lines and text).
I've heard that the best way to do this was using the GridBagLayout and GridBagConstraints.
I'm trying to figure out the appropriate properties for the GridBagConstraints, and I'm having some difficulties. This is what I have so far...
For the top part, I have:
gridx = 0
gridy = 0
weighty = 1.0; // expand downwards, because the bottom should never expand in the Y direction
fill = GridBagConstraints.BOTH
For the bottom part, I have:
gridx = 0
gridy = 1
fill = GridBagConstraints.HORIZONTAL
anchor = GridBagConstraints.PAGE_END
Unfortunately, all the ends up happening is a large gray rectangle appears (I have a white background for the application) - no images load, no lines/text appear.
What should I do? What should I adjust?
I've read a few tutorials, but it just seems really confusing, I got it working in my first application, but now when I try to do this it just doesn't seem to work for me.

In general, for gridbag layout
if you want a component scale, you must give its scale direction a weight, and any sizes (width/height) you set for that direction will be ignored by the layout manager.
If you don't want a component scale, the component must have its size defined (if you want, you can dig into this topic in documents of java). In your case of the bottom panel, you need to give its, at least, a preferred height.
This can work as your expectation
pnlTop.setBackground(Color.WHITE);
pnlBottom.setBackground(Color.BLUE);
// Because you don't want the bottom panel scale, you need to give it a height.
// Because you want the bottom panel scale x, you can give it any width as the
// layout manager will ignore it.
pnlBottom.setPreferredSize(new Dimension(1, 20));
getContentPane().setLayout(new GridBagLayout());
GridBagConstraints cst = new GridBagConstraints();
cst.fill = GridBagConstraints.BOTH;
cst.gridx = 0;
cst.gridy = 0;
cst.weightx = 1.0; // --> You miss this for the top panel
cst.weighty = 1.0;
getContentPane().add(pnlTop, cst);
cst = new GridBagConstraints();
cst.fill = GridBagConstraints.HORIZONTAL;
cst.gridx = 0;
cst.gridy = 1;
cst.weightx = 1.0; // You miss this for the bottom panel
cst.weighty = 0.0;
getContentPane().add(pnlBottom, cst);
Further more, if you want to use gridbag layout, I recommend you to try the painless-gridbag library http://code.google.com/p/painless-gridbag/ (I'm the author of that library). It doesn't solve this problem for you (as your problem concerns managing component's size in gridbag layout) but it will save you a lot of typing and make your code easier to maintain
pnlBottom.setPreferredSize(new Dimension(1, 20));
PainlessGridBag gbl = new PainlessGridBag(getContentPane(), false);
gbl.row().cell(pnlTop).fillXY();
gbl.row().cell(pnlBottom).fillX();
gbl.done();

not sure from your question, maybe will help you Top at 70%, Bottom at 30%
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
public class BorderPanels extends JFrame {
private static final long serialVersionUID = 1L;
public BorderPanels() {
getContentPane().setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
JPanel panel1 = new JPanel();
Border eBorder = BorderFactory.createEtchedBorder();
panel1.setBorder(BorderFactory.createTitledBorder(eBorder, "70pct"));
gbc.gridx = gbc.gridy = 0;
gbc.gridwidth = gbc.gridheight = 1;
gbc.fill = GridBagConstraints.BOTH;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weightx = gbc.weighty = 70;
getContentPane().add(panel1, gbc);
JPanel panel2 = new JPanel();
panel2.setBorder(BorderFactory.createTitledBorder(eBorder, "30pct"));
gbc.gridy = 1;
gbc.weightx = 30;
gbc.weighty = 30;
gbc.insets = new Insets(2, 2, 2, 2);
getContentPane().add(panel2, gbc);
pack();
}
public static void main(String[] args) {
new BorderPanels().setVisible(true);
}
}

If you may use 3th party libs, you may consider the FormLayout as well. It allows you to specify the height of each row, and the resize behavior.
I did not test this but
FormLayout layout = new FormLayout(
"pref", //columns
"50dlu:grow(0.2)","25dlu:grow(0.1)" //rows
);
might do the trick. More information on the syntax can be found in the JGoodies Forms pdf

Related

Items in GridBagLayout does not properly align

I'm trying to align 3 items in a GridBagLayout, 2 of the items being on top and 1 item at bottom. Both Items should be the same Size. I have tried to achieve this with BorderLayout and GridBagLayout but no luck.
This is my attempt with GridBagLayout as you can see they are not properly aligned. This is what I tried to do.
Add first item
Set the x to 1
Add second item
Set the y to 1
Add the last item
I was hoping this would work because It doesn't make sense to me why this would not work, Here is the code for it.
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
JTextField oldPkg = new JTextField();
container.add(oldPkg, gbc);
gbc.gridx = 1;
JTextField newPkg = new JTextField();
gbc.gridy = 1;
JTextField apkPath = new JTextField();
container.add(apkPath, gbc);
The result I want to achieve is
I have achieved it with FlowLayout but it doesn't resign packed when the frame is resized, and the bottom bar is a bit big.
How can I achieve this with GridBagLayout or any other layout so it remains the same on size changes?
Sometimes, you need to set back and try a different approach. Maybe starting with and piece of paper, where you can draw the layout and plot out the constraints.
This will lead you to understanding that apkPath needs to start at x of 0 and "span" two columns.
Currently apkPath is using the same x position as newPkg, you need to change it before using it again.
gbc.gridy = 1;
gbc.gridx = 0;
JTextField apkPath = new JTextField();
container.add(apkPath, gbc);
Okay, but now it's the same size as oldPkg, we need to tell GridBagLayout we want to span multiple columns
gbc.gridy = 1;
gbc.gridx = 0;
gbc.gridwidth = 2;
JTextField apkPath = new JTextField();
container.add(apkPath, gbc);
should now allow the textfield to flow over both columns
I might suggest having a look at How to Use GridBagLayout for more details
Slightly off topic:
Might I just suggest not bothering with 90% of the inbuilt layouts and just going with MigLayout.
There is a MigLayout core jar, and MigLayout swing jar. (Don't take the MigLayout SWT jar by mistake, and also don't use the SWT versions in the import statements).
I guess the licence is liberal. But, you can check whether it fits your needs.
http://www.miglayout.com/
(Just a happy user. Not affiliated)
This does a lot in just a few lines:
public class LayoutAnswer extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
LayoutAnswer window = new LayoutAnswer();
window.init();
window.pack();
window.setVisible(true);
window.setLocationRelativeTo(null);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
});
}
private JPanel panel = new JPanel( new MigLayout("insets 10","[300::, grow][400::, grow]","[100:150:200][100:150:200]") );
private JLabel lbl1 = new JLabel("One");
private JLabel lbl2 = new JLabel("Two");
private JLabel lbl3 = new JLabel("Three");
public void init() {
add(panel, BorderLayout.CENTER);
panel.add(lbl1, "");
panel.add(lbl2, "wrap");
panel.add(lbl3, "span 2");
}
}

GridBagLayout - Trouble placing components without anchor

I'm making an assignment planner program. For the containers (the assignments), I want to place certain components into certain places. However. I can only seem to move components around by using anchor. It seems as if my gridx and gridy do nothing. Could anyone point out my problem and possibly offer some suggestions. My code and a picture of the intended final result are provided below.
Code:
import javax.swing.*;
import java.awt.*;
import static java.awt.GridBagConstraints.*;
//import java.util.ArrayList;
public class MyWindow
{
private final JFrame frame = new JFrame();
private final int WINDOW_WIDTH = 500, WINDOW_DEPTH = 500;
private JPanel panel;
private JPanel toDoList, completed;
private int scrollPaneValue = 110;
//ArrayList<JFrame> frame = new ArrayList<>();
public MyWindow()
{
frame.setTitle("Assignment Planner");
this.contents();
}
private void contents()//make a border above each panel stating "TO-DO" or "COMPLETED"
{//use an arraylist to create containers ArrayList<JPanel> container = new ArrayList<>();
frame.setSize(WINDOW_WIDTH, WINDOW_DEPTH);
panel = new JPanel(new GridLayout(2, 1));
toDoList = new JPanel();
toDoList.setLayout(new /*GridLayout(0,1,5,5)*/BoxLayout(toDoList, BoxLayout.PAGE_AXIS));
toDoList.setPreferredSize(new Dimension(250, 110));
panel.add(toDoList);
completed = new JPanel();
//panelCompleted.setLayout(new GridLayout(0, 1)); //fix like one above
panel.add(completed);
JScrollPane scroll = new JScrollPane(toDoList);
panel.add(scroll); //scroll panes for both panels
JScrollPane scroll2 = new JScrollPane(completed);
panel.add(scroll2);
toDoList.add(Box.createRigidArea(new Dimension(0,1)));
toDoList.add(assignment());
scrollPaneValue += 110; //add these 2 lines of code, beginning after the first two containers to increase jscrollpane
toDoList.setPreferredSize(new Dimension(250, scrollPaneValue));
//toDoList.revalidate(); may not even need
frame.getContentPane().add(panel, BorderLayout.CENTER);//add the panel in the JFrame's content pane in the center
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
JPanel assignment()
{
JPanel container = new JPanel(new GridBagLayout());
container.setMaximumSize(new Dimension(500,100));
GridBagConstraints cDefault = new GridBagConstraints();
cDefault.weightx = 0.5;
cDefault.insets = new Insets(5,5,5,5);
JCheckBox cb;
JLabel dueDate, description;
JButton edit;
cb = new JCheckBox();
GridBagConstraints cCb = new GridBagConstraints();
cCb.weightx = 0.5;
cCb.weighty = 1;
cCb.fill = GridBagConstraints.NONE;//originally none
cCb.gridx = 0;
cCb.gridy = 0;
//cCb.gridwidth = 1;
//cCb.gridheight = 1;
cCb.anchor = FIRST_LINE_START;//may not need, plus needs static import
cCb.insets = cDefault.insets;
cb.setBackground(Color.RED);
container.add(cb, cCb);
dueDate = new JLabel("Due Date");
GridBagConstraints cDueDate = new GridBagConstraints();
cDueDate.gridx = 1;
cDueDate.gridy = 0;
cDueDate.gridwidth = 2;
//cDueDate.fill = GridBagConstraints.HORIZONTAL;
cDueDate.anchor = PAGE_START;
dueDate.setBackground(Color.BLUE);
//cDueDate.anchor = FIRST_LINE_START;
container.add(dueDate, cDueDate);
edit = new JButton("Edit");
GridBagConstraints e = new GridBagConstraints();
e.gridx = 4;
e.gridy = 0;
e.anchor = GridBagConstraints.FIRST_LINE_END;
e.insets = cDefault.insets;
edit.setBackground(Color.GREEN);
container.add(edit, e);
description = new JLabel("Description...");
GridBagConstraints d = new GridBagConstraints();
d.gridx = 1;
d.gridy = 3;
d.gridwidth = 3;
d.fill = GridBagConstraints.HORIZONTAL;
description.setBackground(Color.YELLOW);
container.add(description, d);
container.setBackground(Color.LIGHT_GRAY);//does no fill area behind checkbox
return container;
}
}
What I want the container to look like:
This just concerns my lack of knowledge with GridBagLayout.
Start with the section from the Swing tutorial on How to Use GridBagLayout for working examples and an explanation of all the constraints.
A few things about the code:
//container.setMaximumSize(new Dimension(500,100));
Don't set a maximum size. The layout manager will determine the size of the panel.
//cCb.weightx = 0.5;
//cCb.weighty = 1;
The above code assigns all the extra space of the panel to the check box, since it is the only component with a weightx/y constraint. I doubt you want that. Try commenting out those statements to see what happens.
dueDate.setOpaque(true);
dueDate.setBackground(Color.BLUE);
Yes, that is a good idea to set a background to see the actual size of the component. Problem is a JLabel is transparent by default so the background is never painted. You need need to make your labels opaque if you want to see the background. Another approach to help with debugging is to add LineBorder to the label, then you don't need to worry about transparency.
//e.gridx = 4;
e.gridx = 3;
Be careful with the grid value. You can't just use an value. The first component has a width of 1 and the second a width of 2, so the this component should start at 3.
I can only seem to move components around by using anchor
Actually, I don't this the anchor is doing anything. As I understand it, the anchor only has meaning when the component size is smaller than the grid size. In your original code, only the check box used weightx/y values, so that is the only component where this is true.
The GridBagLayout is one of the most complicated (and flexible) layout manager to use, so yes it takes practice to learn how to use it. Reread the tutorial and play with the constraints.

How to set JButton size with GridBagLayout

I want to set the size of my JButtons that are at the center of my screen to become larger but I can't seem to find how to do that using GridBagLayouts.
Here is how it looks like :
Here is my code :
// Client
c.fill = GridBagConstraints.BOTH;
c.anchor = GridBagConstraints.CENTER;
c.gridy = 5;
c.gridx = 5;
c.gridwidth = 1;
c.gridheight = 1;
c.insets = new Insets(10, 1, 1, 10);
p.add(b[0], c);
// Server
c.fill = GridBagConstraints.BOTH;
c.anchor = GridBagConstraints.CENTER;
c.gridy = 10;
c.gridx = 5;
c.gridwidth = 1;
c.gridheight = 1;
c.insets = new Insets(10, 1, 1, 10);
p.add(b[1], c);
I want the buttons to take up a larger portion of the empty space around them.
More information was added: Buttons have 50% of the width and [about] 20% of the height of parent [together 50% height including the space in between]. (Slightly rewritten to match the suggestion.)
Solution
Combination of simple Layouts Layouts. Although if you do it like this you will have 3 columns or 3 rows which can't be joined, the rest can easily be changed later:
// row variation
JPanel parent = new JPanel();
parent.setLayout(new GridLayout(3, 1));
parent.add(new JPanel()); // placeholder for 1st row
JPanel row = new JPanel(); // 2nd row
row.setLayout(new GridLayout(1, 3)); // create 3 cells of equal size
row.add(new JPanel()); // 2nd row, 1st cell placeholder
// now you have a 33% x 33% (oops) rectangle in the middle
JPanel controls = new JPanel();
controls.setLayout(new GridLayout(2, 1, 10, 10));
controls.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10);
controls.add(new JButton("Client"));
controls.add(new JButton("Server"));
row.add(controls); // add 2nd row, 2nd cell
row.add(new JPanel()); // 2nd row, 3rd cell placeholder
parent.add(row); // add 2nd row
parent.add(new JPanel()); // placeholder for 3rd row
Easy, but you won't be able to join the cells later:
JPanel parent = new JPanel();
parent.setLayout(newGridLayout(9, 9));
Bottom line: combine different layout managers, put your 2 buttons inside a panel and put some placeholders inside, then it should also work fine with GridBagLayout. That said, I would try to stay flexible by writing reusable components which can easily be combined with any layout manager. Then you don't have to use placeholders superfluous code in order to display the components correctly.
Old Answer
Alternative Solution: Use BoxLayout
BoxLayout is more intuitive and easier to understand when looking at code (of course this is only an opinion).
Decide how your window is structered (is it more like big horizontal components on top of each other PAGE_AXIS or big vertical components next to each other LINE_AXIS) and use this as the outer BoxLayout:
JPanel content = new JPanel(); // or frame
content.setLayout(new BoxLayout(content, BoxLayout.LINE_AXIS));
Add the components along the axis, where you have more than one component along the other axis use a 2nd BoxLayout. You can space components by creating rigid areas (empty rectangles always having the same size) or by adding glue (expanding like gum together with the components).
content.add(BoxLayout.createHorizntalGlue());
JPanel col = new JPanel();
col.setLayout(new BoxLayout(col, BoxLayout.PAGE_AXIS));
JButton clientBtn = new JButton("Client");
JButton serverBtn = new JButton("Server");
col.add(BoxLayout.createVerticalGlue());
col.add(clientBtn);
col.add(BoxLayout.createRigidArea(new Dimension(1, 10)));
col.add(serverBtn);
col.add(BoxLayout.createVerticalGlue());
content.add(col);
content.add(BoxLayout.createHorizontalGlue());
I can't imagine what do you want, but if you want your button to fill around, you can add
c.weightx = ...; //Specifies how to distribute extra horizontal space.
or c.weighty = ...; //Specifies how to distribute extra vertical space.
button.setMargin( new Insets(50, 50, 50, 50) );
This will add extra space to the button and allow the layout managers to do their job based on the preferred size of the button.

Controlling textbox height in a Java Swing layout

I have a form, and when it renders using pack, the textboxes have a nice default height. But when I resize it - or in this case, if I override getPreferredSize to make it larger on startup - the textboxes resize proportionally.
I keep going in circles trying to understand the layout manager classes... the related questions that are coming up seem like they're really close, but I'm just not following them!
In the class below, if I comment out the getPreferredSize overload, the textboxes are sized by the system to be "just right". Add getPreferredSize back, or resize manually, and the textbox proportions expand/contract with the form. There's got to be something simple I'm missing!
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.TitledBorder;
public class TestTextBox extends JFrame {
private JTextField jtfRate = new JTextField();//jtfAnnualInterestRate
private JButton jbtComputeLoan = new JButton("Compute Sentence");
// Constructor buids the panel
public TestTextBox() {
// a panel with the fields
JPanel p1 = new JPanel(new GridLayout(5, 2));
p1.add(new JLabel("Annual Interest Rate"));
p1.add(jtfRate);
p1.setBorder(new TitledBorder("This is a border with enough text that I want to see it"));
// a panel with the button
JPanel p2 = new JPanel(new FlowLayout(FlowLayout.CENTER));
p2.add(jbtComputeLoan);
// Put the panels on the frame
add(p1, BorderLayout.CENTER);
add(p2, BorderLayout.SOUTH);
}
#Override
public Dimension getPreferredSize() {
// This will help Pack to pack it up better
return new Dimension(600, 300);
}
public static void main(String[] args) {
TestTextBox jailCell = new TestTextBox();
jailCell.pack(); // Arrange controls compactly based on their properties
jailCell.setTitle("Calculate your Sentence");
jailCell.setLocationRelativeTo(null); // sure, center it, whatever
jailCell.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jailCell.setVisible(true);
}
}
Obviously, this is a case for a GUI layout tool. But this isn't production code, this is a Java class in which I'm trying my best to learn why it works - that way I'll know what the GUI tools are doing.
Update: Thanks to the answer I got, I was able to figure out the basics of the GridBag. It seems pretty closely related to HTML <table>s. It took much longer than it should have, mostly because I kept forgetting , c); to apply the GridBagConstraints to the control! Here's a sample of what the relatively simple add above turned into:
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 0;
c.gridy = 0;
p1.add(new JLabel("Annual Interest Rate"), c);
c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.gridx = 1;
c.gridy = 0;
c.weightx = 0.25;
p1.add(jtfRate, c);
The default behaviour of GridLayout is to provide each component with equal amounts of available space. This means, as you make the component larger, they will get bigger, as you make it smaller, the will get smaller.
You could use a GridBagLayout instead, which will allow you to layout your components in a grid pattern but control how much of the cell they should occupy...
Take a look at How to use GridBagLayout for more details...

Java Swing GridBagLayout Component Positioning

I am using Swing's GridBagLayout for the fist time and I have so far only added two components to a container, although I intend to add more below vertically. So far, the first component (a JLabel) is positioned correctly at PAGE_START, and I have remembered to set weight attributes for the components' corresponding GridBagConstraints. The second component (a JTextField) however is not positioning as I intended and it being centered in the container rather than moving up underneath the JLabel. I have attempted to use multiple anchor constants including FIRST_LINE_START, PAGE_START, NORTH & NORTHWEST but so far nothing is working.
And so, once again I call for the gifted coders of stackoverflow for help. Below is a snippet of the code and below that is an image of the problem graphically.
// Instantiate components and configure their corresponding GridBagConstraints attributes
// refPlusType properties
refPlusType = new JLabel("<html><h3>"+"Reference"+" - "+"Job Type"+" </h3><hr /></html>");
refPlusTypeGC = new GridBagConstraints();
refPlusTypeGC.gridx = 0; // Grid position
refPlusTypeGC.gridy = 0;
refPlusTypeGC.gridwidth = 2; // Number of colums occupied by component
refPlusTypeGC.insets = new Insets(5, 10, 5, 10); // Specifies margin
refPlusTypeGC.weightx = 0.1; // Required for anchor to work.
refPlusTypeGC.weighty = 0.1; // Required for anchor to work.
refPlusTypeGC.anchor = GridBagConstraints.PAGE_START; // Position in container
// addressLine1 properties
addressLine1 = new JTextField();
addressLine1GC = new GridBagConstraints();
addressLine1GC.gridx = 0;
addressLine1GC.gridy = 1;
addressLine1GC.gridwidth = 2;
addressLine1GC.insets = new Insets(0, 10, 0, 10);
addressLine1GC.fill = GridBagConstraints.HORIZONTAL; // Specifies component fill Horizontal space
addressLine1GC.weightx = 0.1;
addressLine1GC.weighty = 0.1;
addressLine1GC.anchor = GridBagConstraints.FIRST_LINE_START;
// Add components to this HALLogisticsDetailsPanel
this.add(refPlusType, refPlusTypeGC);
this.add(addressLine1, addressLine1GC);
Image below;
Thank you all for any help you can offer.
Try increasing the weighty for addressLine1 to a much larger value. I did a quick test setting it to 1000:
addressLine1GC.weighty = 1000.0;
and that pushed the addressLine1 field up under the label with the whitespace below.
anchor = NORTH works like a charm:
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
public class TestJPanels {
private JLabel refPlusType;
private JTextField addressLine1;
protected void initUI() {
final JFrame frame = new JFrame(TestJPanels.class.getSimpleName());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new GridBagLayout());
// Instantiate components and configure their corresponding GridBagConstraints attributes
// refPlusType properties
refPlusType = new JLabel("<html><h3>" + "Reference" + " - " + "Job Type" + " </h3><hr /></html>");
GridBagConstraints refPlusTypeGC = new GridBagConstraints();
refPlusTypeGC.gridwidth = GridBagConstraints.REMAINDER; // Number of colums occupied by component
refPlusTypeGC.insets = new Insets(5, 10, 5, 10); // Specifies margin
refPlusTypeGC.weightx = 1; // Required for anchor to work.
refPlusTypeGC.anchor = GridBagConstraints.PAGE_START; // Position in container
// addressLine1 properties
addressLine1 = new JTextField(20);
GridBagConstraints addressLine1GC = new GridBagConstraints();
addressLine1GC.insets = new Insets(0, 10, 0, 10);
addressLine1GC.fill = GridBagConstraints.HORIZONTAL; // Specifies component fill Horizontal space
addressLine1GC.weightx = 1;
addressLine1GC.weighty = 1;
addressLine1GC.anchor = GridBagConstraints.NORTH;
// Add components to this HALLogisticsDetailsPanel
panel.add(refPlusType, refPlusTypeGC);
panel.add(addressLine1, addressLine1GC);
frame.add(panel);
frame.setSize(600, 600);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestJPanels().initUI();
}
});
}
}
The best 'tutorial' for GridBagLayout that I have seen was created by Scott Stanchfield. You can find a link to the PowerPoint presentation he gave at JavaOne 2001 here
There used to be an article online with the same information, but it appears to have been swallowed up by Oracle.
Please read all the warnings about why GBL is not ideal. If you are determined to use it, Scott gives a great visual lesson on how to determine all the constraints by creating a simple sketch of your GUI.
Jim S.
Okay, I got it. I don't like accepting my own answers but here we go. At the end of the day I am trying to get the whole lot to bunch together properly at the top of the container. Adding weighty attributes to all the components individually means that the remaining space in the container is distributed between all of them (relative to their weighty attribute) therefore spacing them out.
The answer seems to be that by adding a weighty attribute to the lowest component in the GridBagLayout, the rest of the remaining space is allocated to below the lowest component and therefore pushing all components to the top. By default is seems that when remaining space is allocated to a component based on it's weight, it is allocated below it (at least on the y axis).
Here is the new code with three components to help demonstrate;
// Instantiate components and configure their corresponding GridBagConstraints attributes
// refPlusType properties
refPlusType = new JLabel("<html><h3>"+"Reference"+" - "+"Job Type"+" </h3><hr /></html>");
refPlusTypeGC = new GridBagConstraints();
refPlusTypeGC.gridx = 0; // Grid position
refPlusTypeGC.gridy = 0;
refPlusTypeGC.gridwidth = 2; // Number of colums occupied by component
refPlusTypeGC.insets = new Insets(5, 10, 5, 10); // Specifies margin
// addressLine1 properties
addressLine1 = new JTextField();
addressLine1GC = new GridBagConstraints();
addressLine1GC.gridx = 0;
addressLine1GC.gridy = 1;
addressLine1GC.gridwidth = 2;
addressLine1GC.insets = new Insets(0, 10, 0, 10);
addressLine1GC.fill = GridBagConstraints.HORIZONTAL; // Specifies component fill Horizontal space
// addressLine2 properties
addressLine2 = new JTextField();
addressLine2GC = new GridBagConstraints();
addressLine2GC.gridx = 0;
addressLine2GC.gridy = 2;
addressLine2GC.gridwidth = 2;
addressLine2GC.insets = new Insets(0, 10, 0, 10);
addressLine2GC.fill = GridBagConstraints.HORIZONTAL; // Specifies component fill Horizontal space
addressLine2GC.weighty = 1; // Required for anchor to work.
addressLine2GC.anchor = GridBagConstraints.NORTH; // Position in container
// Add components to this HALLogisticsDetailsPanel
this.add(refPlusType, refPlusTypeGC);
this.add(addressLine1, addressLine1GC);
this.add(addressLine2, addressLine2GC);

Categories

Resources