Reputation: 473
I've been having trouble with my Java Swing GUI. First of all, I created a panel with the GridBagLayout on it and added all my labels to it. However, I also created a panel to the right of the other JPanel that adds in a button and 2 sliders which are suppose to like match with the labels.
The problem is that the JLabels are smaller than the components from the right of the other panel which, makes it look like this....
ex. water option -- JSLIDER (the jslider looks a lot bigger)
I tried to make the components larger by adding ipadx
to a bigger value and also I've tried to set the grid width for the labels panel bigger, but nothing seems to work. It just doesn't respond.
Here is the code:
package gui;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
public class Options extends JFrame{
//water option (button changes text on or off)
//make a button listener
JSlider renderDistance;
JSlider grassDensity;
JButton waterToggleButton;
JLabel rdTitle;
JLabel gdTitle;
JLabel wtTitle;
JButton buttonClose;
static final int RD_MIN_VALUE = 0;
static final int RD_MAX_VALUE = 1000;
static final int RD_INIT_VALUE = 500;
static final int GD_MIN_VALUE = 0;
static final int GD_MAX_VALUE = 1000;
static final int GD_INIT_VALUE = 500;
public Options() {
this.setTitle("Settings");
this.setSize(getMaximumSize());
this.setLocationRelativeTo(null);
createView();
this.setVisible(true);
}
private void createView() {
//Making panels and adding them to window*
JPanel pOptions = new JPanel();
this.add(pOptions);
//These are for the labels that I added so people know which option they are using
JPanel pOptionLabels = new JPanel(new GridBagLayout());
pOptions.add(pOptionLabels);
//These are for the middle columns, the objects like button and slider
JPanel pOptionObjects = new JPanel(new GridBagLayout());
pOptions.add(pOptionObjects);
//Making panels and adding them to window*
//Initializing Objects*
GridBagConstraints gbcLabels = new GridBagConstraints();
GridBagConstraints gbcObjects = new GridBagConstraints();
renderDistance = new JSlider(RD_MIN_VALUE, RD_MAX_VALUE, RD_INIT_VALUE);
grassDensity = new JSlider(GD_MIN_VALUE, GD_MAX_VALUE, GD_INIT_VALUE);
waterToggleButton = new JButton("On");
rdTitle = new JLabel("Render Distance");
gdTitle = new JLabel("Grass Density");
wtTitle = new JLabel("Water Terrain Visibility");
//Initializing Objects*
//Giving objects some attributes using methods*
renderDistance.setMinorTickSpacing(100);
renderDistance.setMajorTickSpacing(500);
renderDistance.setPaintTicks(true);
renderDistance.setPaintLabels(true);
grassDensity.setMinorTickSpacing(100);
grassDensity.setMajorTickSpacing(500);
grassDensity.setPaintTicks(true);
grassDensity.setPaintLabels(true);
gbcLabels.gridx = 0;
gbcLabels.gridy = 0;
gbcLabels.anchor = GridBagConstraints.LINE_START;
gbcObjects.gridx = 0;
gbcObjects.gridy = 0;
waterToggleButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(waterToggleButton.getText().equals("Off")) {
waterToggleButton.setText("On");
}else {
waterToggleButton.setText("Off");
}
}
});
//Giving objects some attributes using methods*
//Add things to panel ex. p.add();
pOptionLabels.add(rdTitle, gbcLabels);
gbcLabels.gridy++;
pOptionLabels.add(gdTitle, gbcLabels);
gbcLabels.gridy++;
pOptionLabels.add(wtTitle, gbcLabels);
gbcObjects.gridx++;
pOptionObjects.add(renderDistance, gbcObjects);
gbcObjects.gridy++;
pOptionObjects.add(grassDensity, gbcObjects);
gbcObjects.gridy++;
pOptionObjects.add(waterToggleButton, gbcObjects);
}
public static void main(String[] args) {
new Options();
}
}
Upvotes: 1
Views: 1619
Reputation: 559
What you are experiencing is technically correct since you have two JPanels with two separate instances of the GridBagLayout manager so the rows (and columns) in one layout manager have no information about the rows in the other.
A single GridBagLayout is the way to go if you plan to use JComponents inside them and create a table like appearance. You can later add others JPanels (with different layout managers or with more GridBagLayouts!) but INSIDE your main GridBagLayout JPanel.
GridBagLayout is a really powerful layout, I would recommend sticking with is and master it since it will help you layout things nicely (and fast) in the long run.
This is a great resource to learn more about the GridBagLayout:
https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html
One small comment: IMO the GridBagLayout is not the best layout manager to use as the "root" layout container. I would instead recommend creating a "root" JPanel with a BorderLayout() and add your GridBagLayout JPanel to the center of the BorderLayout panel add(yourGridPanel, BorderLayout.CENTER) since the BorderLayout usually gives for free the ability for things to fill horizontally/vertically and will let you pack your window nicely at the center (with the possibility of adding more things later to the NORTH/SOUTH/EAST/WEST sides).
Good luck!
Upvotes: 2
Reputation: 347184
Change the way you are thinking. Instead of trying to layout all the labels and all the "other" components in separate containers, consider putting them all in the same container.
This way, when they are laid out, the layout calculations are made in relationship to all the components in a single context.
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
public class Options extends JFrame {
//water option (button changes text on or off)
//make a button listener
JSlider renderDistance;
JSlider grassDensity;
JButton waterToggleButton;
JLabel rdTitle;
JLabel gdTitle;
JLabel wtTitle;
JButton buttonClose;
static final int RD_MIN_VALUE = 0;
static final int RD_MAX_VALUE = 1000;
static final int RD_INIT_VALUE = 500;
static final int GD_MIN_VALUE = 0;
static final int GD_MAX_VALUE = 1000;
static final int GD_INIT_VALUE = 500;
public Options() {
this.setTitle("Settings");
createView();
pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
private void createView() {
//Making panels and adding them to window*
JPanel pOptions = new JPanel();
this.add(pOptions);
//These are for the labels that I added so people know which option they are using
JPanel pOptionLabels = new JPanel(new GridBagLayout());
pOptions.add(pOptionLabels);
GridBagConstraints gbc = new GridBagConstraints();
renderDistance = new JSlider(RD_MIN_VALUE, RD_MAX_VALUE, RD_INIT_VALUE);
grassDensity = new JSlider(GD_MIN_VALUE, GD_MAX_VALUE, GD_INIT_VALUE);
waterToggleButton = new JButton("On");
rdTitle = new JLabel("Render Distance");
gdTitle = new JLabel("Grass Density");
wtTitle = new JLabel("Water Terrain Visibility");
//Initializing Objects*
//Giving objects some attributes using methods*
renderDistance.setMinorTickSpacing(100);
renderDistance.setMajorTickSpacing(500);
renderDistance.setPaintTicks(true);
renderDistance.setPaintLabels(true);
grassDensity.setMinorTickSpacing(100);
grassDensity.setMajorTickSpacing(500);
grassDensity.setPaintTicks(true);
grassDensity.setPaintLabels(true);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.anchor = GridBagConstraints.LINE_START;
gbc.insets = new Insets(2, 2, 2, 2);
waterToggleButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (waterToggleButton.getText().equals("Off")) {
waterToggleButton.setText("On");
} else {
waterToggleButton.setText("Off");
}
}
});
//Giving objects some attributes using methods*
//Add things to panel ex. p.add();
pOptionLabels.add(rdTitle, gbc);
gbc.gridy++;
pOptionLabels.add(gdTitle, gbc);
gbc.gridy++;
pOptionLabels.add(wtTitle, gbc);
gbc.gridx++;
gbc.gridy = 0;
pOptionLabels.add(renderDistance, gbc);
gbc.gridy++;
pOptionLabels.add(grassDensity, gbc);
gbc.gridy++;
pOptionLabels.add(waterToggleButton, gbc);
}
public static void main(String[] args) {
new Options();
}
}
Upvotes: 3