GridBagLayout with buttons - java

I am trying to draw a panel with buttons, that looks something like this:
I create the "buttonPanel" like this:
buttonPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 0;
gbc.weighty = 0;
gbc.gridx = 0; gbc.gridy = 0;
gbc.gridwidth = 1; gbc.gridheight = 2;
buttonPanel.add(new JButton("A0"), gbc);
gbc.gridx = 1; gbc.gridy = 0;
gbc.gridwidth = 1; gbc.gridheight = 2;
buttonPanel.add(new JButton("A1"), gbc);
gbc.gridx = 2; gbc.gridy = 0;
gbc.gridwidth = 2; gbc.gridheight = 2;
buttonPanel.add(new JButton("A2"), gbc);
gbc.gridx = 0; gbc.gridy = 2;
gbc.gridwidth = 3; gbc.gridheight = 2;
buttonPanel.add(new JButton("A3"), gbc);
gbc.gridx = 3; gbc.gridy = 2;
gbc.gridwidth = 1; gbc.gridheight = 2;
buttonPanel.add(new JButton("A4"), gbc);
But the result looks like this:
As button "A3" has a gridwidth=3, it should reach the middle of button "A2"?
Any help?
Edit1:
Increasing the panel size, or setting a longer text on the buttons, does not change anything:
Edit2:
Setting the weightx=1 for button "A2" and "A3" helps:
This is acceptable for me, although it would be nice if button "A4" would have the same width as button "A0" and "A1"

Set for A2 and A3 the weightx to 1.0.

although it would be nice if button "A4" would have the same width as button "A0" and "A1"
You can't have a cell take up a partial space of another cell.
So you need to "fake" it by creating 4 (invisible) dummy components. This allows you to define a grid of 4 columns.
Then A2 would have a gridwidth of "2" and A3 a gridwidth of "3". The others would have a gridwidth of 1. So now each row has a total cell widths of 4 to match the dummy cells.
Check out: Why does this GridBagLayout not appear as planned? for an example of this approach.
Or an easier option is to use the Relative Layout. It allows you to give components a relative size. So you would need two panels. In the first the components would have relative sizes of 1, 1, 2 and the second 3, 1.

Related

How to align JLabel next to a JTextField in a GridBagLayout

My form is very simple I just want to have labels next to text fields. The labels are default centering and it makes the form look weird. I want to the labels exactly next to the textfield. I have played with the horizontal alignment of the labels and textfields but it did not change anything.
Here is my code:
JPanel root = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets= new Insets(0,0,0,0);
newVehicleRecord.setLayout(new BorderLayout());
newVehicleRecord.add(root,BorderLayout.PAGE_START);
JLabel title = new JLabel("New Vehicle Record - Customer ID:" + customerIDInfo.getText());
title.setFont(fontTitle);
gbc.weightx = 0;
gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth= 2;
root.add(title,gbc);
gbc.gridx = 0; gbc.gridy = 0; gbc.gridwidth= 1;
root.add(Box.createVerticalStrut(15),gbc);
gbc.gridx = 0; gbc.gridy = 2;
JLabel classificationLabel = new JLabel("Classification:");
classificationLabel.setHorizontalAlignment(JLabel.RIGHT);
root.add(classificationLabel,gbc);
gbc.gridx = 1; gbc.gridy = 2;
JTextField classificationTextField = new JTextField(10);
classificationTextField.setHorizontalAlignment(JTextField.LEFT);
root.add(classificationTextField,gbc);
gbc.gridx = 0; gbc.gridy = 3;
JLabel modelLabel = new JLabel("Model:");
root.add(modelLabel,gbc);
gbc.gridx = 1; gbc.gridy = 3;
JTextField modelTextField = new JTextField(10);
root.add(modelTextField,gbc);
gbc.gridx = 0; gbc.gridy = 4;
JLabel makeLabel = new JLabel("Make:");
root.add(makeLabel,gbc);
gbc.gridx = 1; gbc.gridy = 4;
JTextField makeTextField = new JTextField(10);
root.add(makeTextField,gbc);
I get the following display: http://prntscr.com/6j3iki
As you can see there is a lot of empty space between the label and the textfield which I don't want.
I want to the labels exactly next to the textfield.
You need to play with the anchor constraint:
gbc.anchor = GridBagConstraints.LINE_END;
panel.add(label, gbc);
gbc.anchor = GridBagConstraints.LINE_START;
panel.add(textField, gbc);
Also you would probably want something like:
gbc.insets = new Insets(5, 10, 5, 10);
so the right edge of the label has some space between the left edge of the text field.
Read the section from the Swing tutorial on How to Use GridBagLayout for more information on all the constraints.
Something like this:
gbc.gridx = 0; gbc.gridy = 3;
gbc.anchor = GridBagConstraints.EAST;
JLabel modelLabel = new JLabel("Model:");
root.add(modelLabel,gbc);
So you need to add the line
gbc.anchor = GridBagConstraints.EAST;
to each your label.
Another possibility:
gbc.gridx = 0; gbc.gridy = 3;
gbc.fill = GridBagConstraints.HORIZONTAL;
JLabel modelLabel = new JLabel("Model:");
modelLabel.setHorizontalAlignment(SwingConstants.RIGHT);
root.add(modelLabel,gbc);

Java Swing JPanel that doesn't stretch the width

Okay so I have a JPanel that is going to have two JLabels inside it, I can't seem to figure out a Layout or a way to make it so both the labels are aligned to the left and only take up the space needed for the content, most layouts I try only show one of the objects or show both space out evenly across the entire width, any help would be appreciated!
I've tried setting a max and preferred size on the panel with no luck =/ Both labels are on the same "row"
..so both the labels are aligned to the left
Put it in a panel with layout:
new FlowLayout(FlowLayout.LEFT)
Or (localized)
new FlowLayout(FlowLayout.LEADING)
You could use a GridBagLayout, for example...
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.WEST;
add(shrished, gbc);
gbc.gridx++;
gbc.weightx = 1;
add(shrishing, gbc);
"Wow", you say, "that looks complicated, why would I want to do that when other methods look easier"...good question, you could also do this...
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.NORTHWEST;
add(shrished, gbc);
gbc.gridx++;
gbc.weightx = 1;
gbc.weighty = 1;
add(shrishing, gbc);
or this...
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.SOUTHWEST;
add(shrished, gbc);
gbc.gridx++;
gbc.weightx = 1;
gbc.weighty = 1;
add(shrishing, gbc);
With flexibility comes complexity, but it really comes down to exactly what you want to achieve...

Trouble With GridBagLayout

I am having trouble with GridBagLayout.
A user selects a file, and if that file is bigger than the JTextArea that I display it in, all the Swing components in the shared GridBagLayout go haywire. If it is able to fit in the JTextField, all the Swing components are fine.
Here is a screenshot of the JFrame layout I desire:
And here is the JFrame layout I get when the JTextArea containing the file path is bigger than its allotted size.
All the other JTextFields are affected as well as the buttons below. I don't care if the text in the JTextArea is bigger than its size, I just want all the swing components to stay the same.
Here is the code where I add the Swing components into the File info panel:
//Setup layout.
gbc = new GridBagConstraints();
//File info panel.
gbc.insets = new Insets(3, 10, 3, 10);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.fill = GridBagConstraints.HORIZONTAL;
info_panel.add(first_name_jta, gbc);
gbc.gridx = 1;
gbc.gridy = 0;
info_panel.add(first_name_tf, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
info_panel.add(last_name_jta, gbc);
gbc.gridx = 1;
gbc.gridy = 1;
info_panel.add(last_name_tf, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
info_panel.add(frame_type_jta, gbc);
gbc.gridx = 1;
gbc.gridy = 2;
info_panel.add(frame_type_cb, gbc);
gbc.gridx = 0;
gbc.gridy = 3;
info_panel.add(eye_size_jta, gbc);
gbc.gridx = 1;
gbc.gridy = 3;
info_panel.add(eye_size_tf, gbc);
//Frame panel.
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.BOTH;
frame_panel.add(file_path_tf, gbc);
gbc.gridy = 1;
frame_panel.add(info_panel, gbc);
gbc.gridy = 2;
gbc.insets = new Insets(10, 60, 10, 60);
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.WEST;
frame_panel.add(save_button, gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.anchor = GridBagConstraints.EAST;
frame_panel.add(cancel_button, gbc);
Any ideas?
Okay, that took a bit of effort.
Basically, when you build the frame_panel, you use gridwidth = 2 for the file_path_tf and info_panel, which is all fine an good, but you never reset the attribute when you add the buttons.
This means that save_button can occupy columns 0 and 1 and cancel_button can occupy 1 and 2
Reset the gridwidth attribute after you've added the info_pane and before you add the buttons
gbc.gridwidth = 1;
Also, I think you'll find JLabels much easier to deal with then JTextAreas for labeling fields, but that's just me.

Setting JButton below TextArea using GridBagLayout

I have a TabbedPane inside of which there are Panels.
I am dealing now with the first panel.
Inside this panel there should be another small panel on the left(I just placed a textfield instead for reference) a textarea in the center and below it a row of buttons. But the buttons are placed far too low below from the textarea. Besides, if I resize the frame, the textarea just goes away, vanishes. The textfield is set ok, top left, the textarea more or less yes in the center, but it should not go away when resizing (it would make a weird effect for the user).
I have tried all variants south, west, whatever, no changes or it goes up too far anyways.
I have read somewhat similar questions but I dont see how their answers solve my case.
So, here is the code:
super("Proyecto");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(1200, 800);
/* 1. CREATE PANEL*/
/*MAIN PANEL BOOK READER*/
JPanel panelbookreader = new JPanel();
/*CREATE TEXTAREA*/
JTextArea areatextobookreader = new JTextArea(20, 80);
/* 2. ADD THAT COMPONENT TO ITS PARENT*/
panelbookreader.add(areatextobookreader);
/* 3. SET A LAYOUT FOR THE PANEL THAT WILL ORGANIZE COMPONENTS INSIDE*/
panelbookreader.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
JTextField hold = new JTextField(20);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
panelbookreader.add(hold, gbc);
//TEXT AREA
gbc.gridx = 1;
gbc.gridy = 1;
gbc.gridwidth = 0;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.CENTER;
gbc.weightx = 1.0;
gbc.weighty = 1.0;
panelbookreader.add(areatextobookreader, gbc);
//BUTTONS
gbc.gridx = 1;
gbc.gridy = 2;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.SOUTH;
gbc.weightx = 0.0;
gbc.weighty = 0.0;
panelbookreader.add(openbook, gbc);
/*ADD THE PARENT TO ITS PARENT OR TO GRANPARENT OF COMPONENT*/
JTabbedPane tabulado = new JTabbedPane();
tabulado.addTab("BOOK READER",panelbookreader);
Your weightx for JTextArea is 1.0 which is fine.
But when you specify weighty also as 1.0, then there is no space for JButton. Make some changes in weighty of textarea and also specify weighty for jbutton.

JTextArea in GridBagLayout stealing too much space

I have a GridBagLayout, and for some reason my JTextArea has decided that it doesn't want to listen to gridbag's ratio for with, and when create the panel which contains the layout my textbox grows till it takes up 1/2 of the screen. Heres some code:
tp = new JTabbedPane();
tp.setFont(Main.f);
//Adds tabs with several buttosn to my tabbed pane
for(Menu menu : FileManager.menus){
JPanel tmp = new JPanel();
int s = (int) Math.ceil(Math.sqrt(menu.products.size()));
tmp.setLayout(new GridLayout(s,s));
for(Product p : menu.products){//Act as
p.setFont(Main.f);
p.addActionListener(this);
tmp.add(p);
}
tp.addTab(menu.name,null,tmp,null);
}
receipt.setBorder(BorderFactory.createEtchedBorder());
//starting up with GridBag
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.ipadx = 0;
gbc.ipady = 0;
//sets up and adds the JTabbedPane
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.weightx = 0.8;
gbc.weighty = 0.8;
add(tp,gbc);
//sets up and adds receipt - The one that takes up half the screen
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 1;
gbc.gridy = 0;
gbc.weightx = 0.2;
receipt.setEditable(false);
receipt.setText("Ticket number: 0\n" +
"Transaction number: 0\n");
receipt.setLineWrap(true);
add(receipt,gbc);
//sets up and adds a JPanel that has a bunch of buttons on it(Uses gridlayout)
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 2;
gbc.gridheight = 1;
gbc.weightx = 1;
gbc.weighty = 0.2;
add(buttons,gbc);
buttons.setLayout(new GridLayout(1,8));
createButton(newtable);
createButton(remove);
for(JButton a : quicks)
createButton(a);
createButton(pay);
createButton(exit);
revalidate();
repaint();
When I change the TextArea to a blank JButton it doesn't take up much space at all. Basically the space is filled by the object on the right. How do I tell gridbag that I want my left object to span 4/5ths of the screen, and the right object to span the last 1/5th? In this version I attempt to do so using weighting, in my original version I attempted to do so using cells, so the left object was at gridx=0 gridwidth = 4, and the right object was gridx = 4 gridwidth = 1
Neither way worked. I am also open to alternate ideas(like better layouts, or a JTable?)
Thanks for your help,
Chase
What it's doing
Dimensions for what it should do
If you are not fixed on precisely 4/5 and 1/5 ratio, you can use BorderLayout and place buttons to the center and text area to the East.
Border layout will display the text area as wide as you supply - specify preferred size (width, you can set height to whatever number you want, border layout will ignore it). The rest of the space is then taken up by buttons panel.
You can learn more about border layout here: http://docs.oracle.com/javase/tutorial/uiswing/layout/border.html

Categories