Reputation: 12972
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.
Upvotes: 3
Views: 2445
Reputation: 12972
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);
Upvotes: 1
Reputation: 231
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.
Upvotes: 1
Reputation: 47608
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();
}
});
}
}
Upvotes: 2
Reputation: 85
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.
Upvotes: 4