components are separated when they are suppose to be in succession vertically - java

I want the image and the title (JLabel) to both me centered and be at the top of the page but instead the image is at the top of the page and centered but the title is 3/4ths of the way down the page and centered.
GridBagConstraints c = new GridBagConstraints();
c.anchor = GridBagConstraints.NORTH;
c.insets = new Insets(10, 0, 0, 0);
c.weighty = 1;
c.gridy = 0;
panel.add(image,c);
c.gridy = 1;
panel.add(title, c);

c.weighty = 1;
c.gridy = 0;
panel.add(image,c);
c.gridy = 1;
panel.add(title, c);
You don't reset the "weighty" constraint so it is used for both components. Therefore, the "extra" space in the frame is allocated equally to each component. So you see the extra space between the two components.
Add a Border to each component and you will see the actual size of each component.
The solution is to assign set the "weighty" constraint to only the second component so the first component is displayed at its preferred size.
//c.weighty = 1;
c.gridy = 0;
panel.add(image,c);
c.gridy = 1;
c.weighty = 1;
panel.add(title, c);

Related

Java GridBadLayout positioning

I would be grateful for any help/suggestion regarding my problem. I attached the image of my simple program which shows that the positioning of the components seems a bit off. My question is - why the ComboBox From... as well as TextField Enter value here... start so far off of the left corner? I've given gridx=0 so it positions the component on the very edge of the window, but components start some pixels off from the edge. How can I fix it?
Also, what do I need to do/consider to remove dependency of the rows on each other? I mean how to position components anywhere I want in one row without effecting the position of other components in another row. Thank you!
Piece of Code:
JPanel container = new JPanel();
container.setLayout(new GridBagLayout());
getContentPane().add(container, BorderLayout.NORTH);
TitledBorder outputCenter;
GridBagConstraints c = new GridBagConstraints();
label = new JLabel("Choose measure system to convert");
label.setFont(new Font("Times New Roman", Font.PLAIN, 20));
c.gridx = 1;
c.gridy = 0;
c.gridwidth = 2;
c.insets = new Insets(10, 0, 20, 0);
container.add(label, c);
fromList = new JComboBox<String>(convertFrom);
c.gridx = 0;
c.gridy = 1;
c.gridwidth =1;
c.ipadx = 20;
c.anchor = GridBagConstraints.LINE_START;
container.add(fromList, c);
toList = new JComboBox<String>(convertTo);
c.gridx = 1;
c.gridy = 1;
c.gridwidth = 1;
c.ipadx = 20;
container.add(toList, c);
//Field where user enters the value to be converted
input = new JTextField("Enter value here...");
input.setPreferredSize(new Dimension(150,30));;
input.setEditable(true);
input.setBackground(Color.WHITE);
input.setBorder(BorderFactory.createLineBorder(Color.BLACK));
input.addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e){
input.setText("");}});
c.gridx = 0;
c.gridy = 2;
c.gridwidth = 1;
c.ipady = 20;
container.add(input, c);
//The area where the output/result is shown
output = new JTextArea(10,30);
output.setEditable(false);
output.setFont(new Font("Serif", Font.BOLD, 12));
output.setBackground(Color.WHITE);
outputCenter = BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.BLACK), "Output");
outputCenter.setTitleJustification(TitledBorder.CENTER);
output.setBorder(outputCenter);
c.gridx = 1;
c.gridy = 2;
c.insets = new Insets(50,5,10,10);
c.gridwidth = 3;
container.add(output, c);
//Convert button
convert = new JButton("Convert");
c.gridx = 0;
c.gridy = 3;
c.ipadx = 50;
container.add(convert, c);
}
Output:
Remember, GridBagLayout is a "flexible grid" layout manager. It still relies on the concept of rows and columns, but each row and column has it's own size, based on the requirements of the components and the constraints applied to them.
This means, that you combo box is been aligned to the left position because of a combination of c.anchor = GridBagConstraints.LINE_START and the space requirements of the JTextField sharing the same column.
You "could" change c.anchor = GridBagConstraints.LINE_START to c.anchor = GridBagConstraints.LINE_END, while will (in your case) align the combo box to the right edge of the column, for example...
Another solution would be to use a combination of containers to reduce the overall complexity of the layout. For example, you could add both the combo boxes to their own container, managing the layout requirements for them in an isolated manner and then layout that container within the large scheme of things

Does GridBagLayout require placeholder panels for empty cells?

I made a simple GridBagLayout which adds buttons in the cells (0,0), (1,0), and (0,1).
JPanel panelMain = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
panelMain.add(new JButton("0,0"),c);
c.gridx = 1;
c.gridy = 0;
panelMain.add(new JButton("1,0"),c);
c.gridx = 0;
c.gridy = 1;
panelMain.add(new JButton("0,1"),c);
I was happy to see the resultant UI:
I want to add a JButton in a cell that is not connected to the existing cells. I want it to be separated by an empty space. When I try this, the new JButton is lumped in next to the others. Here is the addition:
JPanel panelMain = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
panelMain.add(new JButton("0,0"),c);
c.gridx = 1;
c.gridy = 0;
panelMain.add(new JButton("1,0"),c);
c.gridx = 0;
c.gridy = 1;
panelMain.add(new JButton("0,1"),c);
c.gridx = 3;
c.gridy = 0;
panelMain.add(new JButton("3,0"),c);
The output:
The JButton("3,0") is displaying at the cell (2,0). Do I need to use an empty JPanel as a place holder in the cell (2,0)? More importantly, why is this happening?
The layout does not know what should be the width to be left at 2,0 unless there is a component placed in the gridx = 2. By the time you complete the UI, if any component gets placed, it should look fine. For e.g.:
In other case you may add empty JPanel with background color matching to the background color of the container.
Do I need to use an empty JPanel as a place holder in the cell (2,0)?
You can use an "insets" grid bag constraint to give space between components. Read the Swing tutorial on How to Use GridBagLayout for more information on the inset constraint.
Or, if you want to have a place holder then you can use a Box.createHorizontalStrut(...) to easily specify the width.
More importantly, why is this happening?
Cells don't have a size unless there is a component in the cell. Each cell is independent of one another so what size would you expect cell (2,0) to be?

Placing JLabel in the top left corner of a GridBagLayout

I'm using GridBagLayout and I want to position my JLabel and textfield on the top left corner of my JPanel. I know this question might probably be a duplicate but I couldn't find one that could explain why my code ended up centered.
JLabel user = new JLabel(ss[0]);
JLabel av = new JLabel(ss[1]);
JTextField ufield = new JTextField("");
user.setBorder(BorderFactory.createLineBorder(Color.black));
av.setBorder(BorderFactory.createLineBorder(Color.black));
ufield.setBorder(BorderFactory.createLineBorder(Color.black));
//User Label
c.anchor = GridBagConstraints.NORTHWEST;
c.gridx = 0;
c.gridy = 0;
c.weightx = 1;
c.insets = new Insets(2, 0, 0, 2);
p.add(user, c);
//User TextField
c.fill = GridBagConstraints.BOTH;
c.gridx = 1;
c.gridy = 0;
c.gridwidth = 5;
c.gridheight = 1;
c.weightx = 2;
c.insets = new Insets(5, 1, 1, 5);
p.add(ufield, c);
//Available Label
c.fill = GridBagConstraints.NORTHWEST;
c.gridx = 0;
c.gridy = 1;
c.gridwidth = 1;
c.gridheight = 1;
c.weightx = 1;
c.insets = new Insets(5, 1, 1, 5);
p.add(av, c);
f.repaint();
f.revalidate();
This ends up looking like this :
I want it to be near the top instead of at the center
The JLabel and textfield are in fact aligned at the top left of the JPanel, however, the JPanel is not at the top left of the JFrame (which I'm guessing is the variable f), therefore overall it appears centered rather than on the top left.
You have to control the layout of the JFrame when you add the JPanel to it. You could do it using a BorderLayout like:
f.getContentPane().setLayout(new BorderLayout());
f.add(p, BorderLayout.PAGE_START);

Components overlapping whilst using GridBagLayout

whilst positioning my JLabels I found a problem which till now I could not resolve. The JLabels were overlapping.
This is a snippet from the code regarding the gridbaglayout:
c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 3;
c.fill = GridBagConstraints.HORIZONTAL;
c.ipady = 20;
c.weightx = 3;
c.weighty = 1;
c.insets = new Insets(0,5,5,5);
all.add(header, c);
c.gridx = 0;
c.gridy = 1;
c.weightx = 2;
c.weighty = 4;
c.insets = new Insets(5,5,5,5);
all.add(sts, c); //this label overlapped
c.gridx = 1;
c.gridy = 1;
c.weightx = 1;
c.weighty = 5;
c.insets = new Insets(5,5,5,5);
all.add(cl, c); //this label overlapped
Thanks in advance
Having a gridwidth of 3 means the component will take up 3 places across the x grid, please read the grid bag layout tutorial
http://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
You have the first component at x0 this will extend 3 columns to x2 hence the next avail grid location is x3

How to set gaps for ALL Components in the GridBagLayout?

When you are using group layout you set all the gaps with:
setAutoCreateGaps(true);
setAutoCreateContainerGaps(true);
Is there a same function for GridBagLayout?
In GridBagLayout, using GridBagConstraints you can set gaps with the below properties;
GridBagConstraints.ipadx,GridBagConstraints.ipady:
Specifies the component's internal padding within the layout.
GridBagConstraints.insets:
Specifies the component's external padding.
GridBagConstraints.weightx,GridBagConstraints.weighty:
Used to determine how to distribute space.
For Example:
pane.setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
c.fill = GridBagConstraints.HORIZONTAL;
c.ipady = 40; //make this component tall
c.ipadx = 10; //make this component wide
c.anchor = GridBagConstraints.PAGE_END; //bottom of space
c.insets = new Insets(10,0,0,0); //top padding
c.gridx = 1; //first column
c.gridy = 2; //third row
c.gridwidth = 2; //2 columns wide
c.weightx = 0.5; //increase horizontal space
c.weighty = 1.0; //increase vertical space
Setting Gap Sizes in a GridBadLayout
good description
use EmptyBorders
use invisible JComponents

Categories