I can't get GridBagLayout to work as I'd like. I'm trying to get 2 radio buttons to align next to each other. The best I can get is inches apart. I've played with weights to no avail. Currently I have my labels spanned over 2 cells. I have my radio buttons using 1 cell each with a 2 cell label. The last row is a 2 cell label and 2 cell date control. Maybe GridBagLayout is not the correct manager.
public class GridBagLayoutTest extends JFrame {
private final JPanel addScorePanel;
private final JTextField txtScore;
private final JRadioButton rb9;
private final JRadioButton rb18;
private final JDateChooser dateChooserDate;
public GridBagLayoutTest() {
setLayout(new BorderLayout());
addScorePanel = new JPanel();
addScorePanel.setLayout(new GridBagLayout());
txtScore = new JTextField(3);
rb9 = new JRadioButton("9");
rb9.setActionCommand("9");
rb18 = new JRadioButton("18");
rb18.setActionCommand("18");
rb18.setSelected(true);
ButtonGroup bgHoles = new ButtonGroup();
bgHoles.add(rb9);
bgHoles.add(rb18);
dateChooserDate = new JDateChooser();
layoutControls();
add(addScorePanel, BorderLayout.NORTH);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600, 430); // Juggle for best look
setMinimumSize(new Dimension(400, 375));
setLocationRelativeTo(null);
setVisible(true);
}
private void layoutControls() {
Border titleBorder = BorderFactory.
createTitledBorder("Handicap Add Score");
int space = 15;
Border spaceBorder = BorderFactory.createEmptyBorder(space, space,
space, space);
addScorePanel.setBorder(BorderFactory.createCompoundBorder(spaceBorder,
titleBorder));
// setBorder(BorderFactory.createLineBorder(Color.BLACK));
GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.NONE; // Controls preferred size,
////////// Score row //////////
gc.gridy = 0;
gc.gridx = 0;
gc.weightx = 1.0;
gc.weighty = 1.0;
gc.gridwidth = 2; // Label 2 cells
gc.anchor = GridBagConstraints.FIRST_LINE_END;
gc.insets = new Insets(15, 0, 0, 15);
addScorePanel.add(new JLabel("Score: "), gc);
gc.gridy = 0;
gc.gridx = 2; // Skip over 2nd label cell
gc.gridwidth = 1;
gc.anchor = GridBagConstraints.FIRST_LINE_START;
gc.insets = new Insets(15, 0, 0, 15);
addScorePanel.add(txtScore, gc);
////////// Holes row //////////
gc.gridy ;
gc.gridx = 0;
// gc.weightx = 0.1;
// gc.weighty = 1.0;
gc.gridwidth = 2; // Label 2 cells
gc.insets = new Insets(15, 0, 0, 15);
gc.anchor = GridBagConstraints.FIRST_LINE_END;
addScorePanel.add(new JLabel("Holes Played:"), gc);
gc.gridx = 2; // Skip over 2nd label cell
// gc.weightx = 0.1;
gc.gridwidth = 1;
gc.insets = new Insets(15, 0, 0, 0);
gc.anchor = GridBagConstraints.FIRST_LINE_START;
addScorePanel.add(rb9, gc);
gc.gridx ; // Next cell
// gc.weightx = 1.0;
gc.gridwidth = 1;
gc.insets = new Insets(15, 0, 0, 0);
gc.anchor = GridBagConstraints.FIRST_LINE_START;
addScorePanel.add(rb18, gc);
////////// Date row //////////
gc.gridy ;
gc.gridx = 0;
// gc.weightx = 1.0;
// gc.weighty = 1.0;
gc.gridwidth = 2; // Label 2 cells
gc.insets = new Insets(15, 0, 0, 15);
gc.anchor = GridBagConstraints.FIRST_LINE_END;
addScorePanel.add(new JLabel("Date: "), gc);
gc.gridx = 2; // Skip over 2nd label cell
gc.gridwidth = 2; // Date 2 cells
gc.anchor = GridBagConstraints.FIRST_LINE_START;
addScorePanel.add(dateChooserDate, gc);
}
This is what I am trying to do:
EDIT based on @camickr:
////////// Score row //////////
gc.gridy = 0;
gc.gridx = 0;
gc.weightx = 1.0;
gc.weighty = 1.0;
gc.gridwidth = 1; // <----- // Label 2 cells
gc.anchor = GridBagConstraints.FIRST_LINE_END;
gc.insets = new Insets(15, 0, 0, 15);
addScorePanel.add(new JLabel("Score: "), gc);
gc.gridy = 0;
gc.gridx = 1; // <----- // Skip over 2nd label cell
gc.gridwidth = 2; // <-----
gc.anchor = GridBagConstraints.FIRST_LINE_START;
gc.insets = new Insets(15, 0, 0, 15);
addScorePanel.add(txtScore, gc);
////////// Holes row //////////
gc.gridy ;
gc.gridx = 0;
// gc.weightx = 0.1;
// gc.weighty = 1.0;
gc.gridwidth = 1; // <----- // Label 2 cells
gc.insets = new Insets(15, 0, 0, 15);
gc.anchor = GridBagConstraints.FIRST_LINE_END;
addScorePanel.add(new JLabel("Holes Played:"), gc);
gc.gridx = 1; // <----- // Skip over 2nd label cell
// gc.weightx = 0.1;
gc.gridwidth = 1;
gc.insets = new Insets(15, 0, 0, 0);
gc.anchor = GridBagConstraints.FIRST_LINE_START;
addScorePanel.add(rb9, gc);
gc.gridx = 2; // <----- // Next cell
// gc.weightx = 1.0;
gc.gridwidth = 1;
gc.insets = new Insets(15, 0, 0, 0);
gc.anchor = GridBagConstraints.FIRST_LINE_START;
addScorePanel.add(rb18, gc);
////////// Date row //////////
gc.gridy ;
gc.gridx = 0;
// gc.weightx = 1.0;
// gc.weighty = 1.0;
gc.gridwidth = 1; // <----- // Label 2 cells
gc.insets = new Insets(15, 0, 0, 15);
gc.anchor = GridBagConstraints.FIRST_LINE_END;
addScorePanel.add(new JLabel("Date: "), gc);
gc.gridx = 1; // Skip over 2nd label cell
gc.gridwidth = 2; // Date 2 cells
gc.anchor = GridBagConstraints.FIRST_LINE_START;
addScorePanel.add(dateChooserDate, gc);
Looks pretty much the same. I think I marked my changes correctly.
CodePudding user response:
Oracle has a helpful tutorial,
All Swing applications must start with a call to the SwingUtilities
invokeLater
method. This method ensures that the Swing components are created and executed on the Event Dispatch Thread.
I used a JFrame
. The only reason you would extend a Swing component, or any Java class, is if you want to override one or more of the class methods.
I put the JRadioButtons
inside a JPanel
with a FlowLayout
.
I simplified the main JPanel
using a GridBagLayout
. It's unusual to right justify the JLabels
, but I showed you how to do so.
You probably want to add a JButton
to trigger an ActionListener
to read the input fields.
Here's the complete runnable code.
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
public class GridBagLayoutTest implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new GridBagLayoutTest());
}
private JTextField txtScore;
private JRadioButton rb9;
private JRadioButton rb18;
private JTextField dateChooserDate;
@Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createMainPanel() {
JPanel panel = new JPanel(new GridBagLayout());
Border titleBorder = BorderFactory
.createTitledBorder("Handicap Add Score");
int space = 15;
Border spaceBorder = BorderFactory.createEmptyBorder(space, space,
space, space);
panel.setBorder(
BorderFactory.createCompoundBorder(spaceBorder, titleBorder));
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.LINE_START;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.insets = new Insets(15, 0, 0, 15);
gbc.gridx = 0;
gbc.gridy = 0;
panel.add(createJLabel("Score:"), gbc);
gbc.gridx ;
txtScore = new JTextField(10);
panel.add(txtScore, gbc);
gbc.gridx = 0;
gbc.gridy ;
panel.add(createJLabel("Holes Played:"), gbc);
gbc.gridx ;
panel.add(createRadioPanel(), gbc);
gbc.gridx = 0;
gbc.gridy ;
panel.add(createJLabel("Date:"), gbc);
gbc.gridx ;
dateChooserDate = new JTextField(10);
panel.add(dateChooserDate, gbc);
return panel;
}
private JLabel createJLabel(String text) {
JLabel label = new JLabel(text);
label.setHorizontalAlignment(JLabel.TRAILING);
return label;
}
private JPanel createRadioPanel() {
JPanel panel = new JPanel(new FlowLayout());
rb9 = new JRadioButton("9");
rb9.setActionCommand("9");
panel.add(rb9);
rb18 = new JRadioButton("18");
rb18.setActionCommand("18");
panel.add(rb18);
ButtonGroup bgHoles = new ButtonGroup();
bgHoles.add(rb9);
bgHoles.add(rb18);
return panel;
}
}