I have a JPanel which uses the FlowLayout, and a Box which has components arranged vertically.
What I want, is to set the same width size of the other components to button "Remove Column".
I've tried to change the size with line
removeColumnButton.setPreferredSize(new Dimension(130, 25));
but I can only change size of the height, not width.
Below is screenshot of the panel and code:
JPanel eastPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
Box eastPanelBox = Box.createVerticalBox();
addNewColumnButton = new JButton("Add New Column");
addNewColumnButton.setAlignmentX(Box.CENTER_ALIGNMENT);
eastPanelBox.add(addNewColumnButton);
eastPanelBox.add(Box.createVerticalStrut(5));
removeColumnButton = new JButton("Remove Column");
removeColumnButton.setAlignmentX(Box.CENTER_ALIGNMENT);
removeColumnButton.setPreferredSize(new Dimension(130, 25));
eastPanelBox.add(removeColumnButton);
eastPanelBox.add(Box.createVerticalStrut(5));
columnField = new JTextField();
columnField.setAlignmentX(Box.CENTER_ALIGNMENT);
columnField.setPreferredSize(new Dimension(130, 25));
eastPanelBox.add(columnField);
eastPanelBox.add(Box.createVerticalStrut(5));
columnListCB = new JComboBox(cBoxModel);
columnListCB.setAlignmentX(Box.CENTER_ALIGNMENT);
eastPanelBox.add(columnListCB);
eastPanelBox.add(Box.createVerticalStrut(5));
calculateColumnButton = new JButton("Calculate Column");
calculateColumnButton.setAlignmentX(Box.CENTER_ALIGNMENT);
eastPanelBox.add(calculateColumnButton);
eastPanel.add(eastPanelBox);
Use a GridLayout for the container holding the column of components. Initialize it with
int vGap = 5;
new GridLayout(0, 1, 0, vGap)
which stands for 1 column, variable number of rows. The vGap parameter must be an int that represents the vertical gap between components.
Related
The problem
I have a JPanel with the GridBagLayout as a layout manager. I want the columns of the layout to have certain widths. Sometimes the width of a column might be lower than the preferred width of a component inside. In this case, the column should force a component to take only the available space of the column.
But, for now, a component inside a cell doesn't shrink if the column width constraint is less than the component's preferred width.
Example
Below is the demo with 4x4 grid. I want the JLabel in the top-left corner to shrink in accordance with the min widths I have set when initialized GridBagLayout (10 px)
As I run the example below, the following result is obtained:
The cell in the top-left takes more space than it was allowed initially by the GridBagLayout
public class ResizeDemo extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
ResizeDemo resizeDemo = new ResizeDemo();
resizeDemo.pack();
resizeDemo.setDefaultCloseOperation(EXIT_ON_CLOSE);
resizeDemo.setVisible(true);
});
}
public ResizeDemo() {
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[]{0, 0};
gridBagLayout.rowHeights = new int[]{0, 0};
gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE};
gridBagLayout.rowWeights = new double[]{1.0, Double.MIN_VALUE};
getContentPane().setLayout(gridBagLayout);
JPanel panel = new JPanel();
GridBagConstraints gbc_panel = new GridBagConstraints();
gbc_panel.fill = GridBagConstraints.BOTH;
gbc_panel.gridx = 0;
gbc_panel.gridy = 0;
getContentPane().add(panel, gbc_panel);
GridBagLayout gbl_panel = new GridBagLayout();
// ============ Set the column widths here ============
// Note that the width of the first column is 10 px
gbl_panel.columnWidths = new int[] {10, 150, 0};
// =====================================================
gbl_panel.rowHeights = new int[]{0, 0, 0};
gbl_panel.columnWeights = new double[]{0.0, 0.0, 0.0};
gbl_panel.rowWeights = new double[]{0.0, 0.0, Double.MIN_VALUE};
panel.setLayout(gbl_panel);
JLabel label1 = new JLabel("A very long string here");
label1.setHorizontalAlignment(SwingConstants.CENTER);
GridBagConstraints gbc_label1 = new GridBagConstraints();
gbc_label1.fill = GridBagConstraints.HORIZONTAL;
gbc_label1.gridx = 0;
gbc_label1.gridy = 0;
panel.add(label1, gbc_label1);
JLabel label2 = new JLabel("Label");
GridBagConstraints gbc_label2 = new GridBagConstraints();
gbc_label2.gridx = 1;
gbc_label2.gridy = 0;
panel.add(label2, gbc_label2);
JLabel label3 = new JLabel("Label");
GridBagConstraints gbc_label3 = new GridBagConstraints();
gbc_label3.fill = GridBagConstraints.HORIZONTAL;
gbc_label3.gridx = 0;
gbc_label3.gridy = 1;
panel.add(label3, gbc_label3);
JLabel label4 = new JLabel("Label");
GridBagConstraints gbc_label4 = new GridBagConstraints();
gbc_label4.gridx = 1;
gbc_label4.gridy = 1;
panel.add(label4, gbc_label4);
}
}
Question:
How can I force the JLabel inside a GridBagLayout cell to shrink itself?
The GridBagLayout sizes each column based on the largest "preferred size" of any component added to the column.
The "columnWidths" is used to set the minimum value for any column. This is used when you resize the frame. If there is not enough space to display the component at it preferred size and you have set a resize weight for the component, then the component will shrink in size from its preferred size to its minimum size.
How can I force the JLabel inside a GridBagLayout cell to shrink itself?
One possibility is to wrap the label in a panel using a BoxLayout. The BoxLayout will respect the maximum size of size of the component. The basic logic would be:
//panel.add(label1, gbc_label1);
Dimension max = label1.getPreferredSize();
max.width = 10;
label1.setMaximumSize(max);
Box wrapper = Box.createHorizontalBox();
wrapper.add(label1);
panel.add(wrapper, gbc_label1);
Don't know what your real application is, but if you are only using labels, then maybe you can use a JTable. With a JTable you can control the actual column width.
This is the piece in your code that is setting the widths. Lack of setting the column width defaults shrinking to fit the enclosed component.
gbl_panel.columnWidths = new int[] {10, 150, 0};
I have a GUI with one main JPanel and inside of it multiple rows, each row being another JPanel. Every row (of type JPanel) consists of 4 smaller JPanels and every panel out of those 4 has a component inside of it. The end result is a grid like interface.
Main panel has a BoxLayout and panels that are parts of a row have FlowLayout.
When I update height of some component (from row) using some listener, entire row becomes taller, which works as expected. But what happens is that not only height is changed, but also width of components (inside a row) is changed. I understand that BoxLayout is trying to layout the components using maxSize and minSize that I can set to be the same value and that worked, but then when I resize the window, other rows expand and the row with same minSize and maxSize doesn't and the grid structure becomes messed up.
What I want to achieve, is that I update only the height of the row. And when I resize the window, entire row expands, and the structure of grid is still the grid. Here is the Short, Self Contained, Correct (Compilable), Example:
Main class:
public class Main {
public static void main(String args[]) {
SwingUtilities.invokeLater(() -> {
new MainFrame(450,150);
});
}
}
MainFrame class:
public class MainFrame extends JFrame{
public MainFrame(int width, int height) {
super("Title");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(width, height);
setVisible(true);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
JScrollPane scrollPane = new JScrollPane(mainPanel);
add(scrollPane);
for(int i=0; i<50; i++) {
JPanel panel1 = new JPanel();
panel1.setLayout(new FlowLayout(FlowLayout.LEFT));
panel1.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 1, Color.black));
panel1.setPreferredSize(new Dimension(70,35));
JPanel panel2 = new JPanel();
panel2.setLayout(new FlowLayout(FlowLayout.LEFT));
panel2.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.black));
panel2.setPreferredSize(new Dimension(70,35));
JPanel panel3 = new JPanel();
panel3.setLayout(new FlowLayout(FlowLayout.LEFT));
panel3.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.black));
panel3.setPreferredSize(new Dimension(70,35));
JTextArea area1 = new JTextArea("hello " + i);
area1.setPreferredSize(new Dimension(70,25));
panel1.add(area1);
JTextArea area2 = new JTextArea("hello " + i);
area2.setPreferredSize(new Dimension(70,25));
panel2.add(area2);
JTextArea area3 = new JTextArea("hello " + i);
area3.setPreferredSize(new Dimension(70,25));
panel3.add(area3);
JPanel row = new JPanel();
row.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, Color.black));
row.setLayout(new BoxLayout(row, BoxLayout.X_AXIS));
row.add(panel1);
row.add(panel2);
row.add(panel3);
JButton button = new JButton("Click me");
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
buttonPanel.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, Color.black));
buttonPanel.setPreferredSize(new Dimension(70,35));
buttonPanel.add(button);
button.addActionListener(event -> {
panel1.setPreferredSize(new Dimension(panel1.getWidth(), panel1.getHeight() + 30));
area1.setPreferredSize(new Dimension(area1.getWidth(), area1.getHeight() + 30));
area1.updateUI();
});
row.add(buttonPanel);
mainPanel.add(row);
}
}
}
If you run this code and press button it will update not only row's height, but also row's width and grid is not aligned well anymore.
You are setting the "preferred size" based on the "size" of the component. The two can be different.
Your code should be something like:
//panel1.setPreferredSize(new Dimension(panel1.getWidth(), panel1.getHeight() + 30));
Dimension d = panel1.getPreferredSize();
panel1.setPreferredSize(new Dimension(d.width, d.height + 30));
Also, you should not be using updateUI(). That is a method used internally by Swing on a LAF change.
Instead, when you want to invoke the layout manager you invoke revalidate() on the top level component that was changed:
//area1.updateUI();
panel1.revalidate();
I am just learning Java GUIs, and about layout managers and am looking to create a GUI with the following layout. What would be the best way to approach this? (JFrame is 1000w x 800h)
Here is what I've thought of doing with some success, and a messy solution that doesn't match the wanted layout exactly
JFrame myFrame (GridLayout(2,1))
- JPanel topPanel (BorderLayout)
- JPanel topLeftPanel (GridLayout(9,2) & setSize 666,400)
- JLabel buyingAnInvestment - Jlabel empty1
- JLabel type - JComboBox typeSelect
- JLabel symbol - JTextField symbolField
- JLabel empty2 - JLabel empty3
- JLabel name - JTextField nameField
- JLabel empty4 - JLabel empty5
- JLabel quantity - JTextField quantityField
- JLabel empty6 - JLabel epty7
- JLabel price - JTextField price
- JPanel topRightPanel (GridLayout(2,1) & setSize 333,400)
- JButton reset
- JButton buy
- JPanel bottomPanel (What should I do for this?)
- JLabel messages
- JTextArea & JScrollArea
How would you layout the components and JPanel containers to get the expected result? Any direction would be greatly appreciated.
If the GUI can have Buying an investment & Messages as a TitledBorder, I'd lay it out as follows:
Outer layout - BorderLayout
Buying an investment using a two column GridBagLayout of labels and fields. Put it in the CENTER of the border layout.
Reset / Buy buttons in a single column GridLayout with an ample EmptyBorder and vertical layout padding. Put that panel in the LINE_END of the border layout.
The text area insinde a panel / constraint that will stretch it to full width & height E.G. using another GridLayout in the PAGE_END of the border layout.
(JFrame is 1000w x 800h)
Don't try to guess the size the GUI needs. Layout all the components, then pack() the frame. The GUI will become the smallest size it needs in order to display everything it contains.
This is mostly an elaboration of #AndrewThompson's answer.
The changes and simplifications as compared to your original approach are:
No explicit setSize calls. Instead let the layout-managers choose
the sizes when pack() is called on the JFrame
and when the user resizes it.
There are only 3 panels (as CENTER, EAST and SOUTH part
in a BorderLayout).
The headings "Buy an investment" and "Messages" are implemented as
TitledBorder, not as JLabel.
Using GridBagLayoutinstead of GridLayout, because then you
have much better control by using proper GridBagConstraints
(especially fill, anchor, weightx, weighty, insets).
The above layout was produced by following code:
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(Main::initGUI);
}
private static void initGUI() {
JFrame myFrame = new JFrame("Investment Portfolio");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myFrame.setLayout(new BorderLayout());
JPanel topLeftPanel = new JPanel(new GridBagLayout());
myFrame.add(topLeftPanel, BorderLayout.CENTER);
topLeftPanel.setBorder(BorderFactory.createTitledBorder("Buying an investment"));
GridBagConstraints labelConstraints = new GridBagConstraints();
labelConstraints.anchor = GridBagConstraints.WEST;
labelConstraints.gridx = 0;
labelConstraints.gridy = 0;
labelConstraints.weightx = 0.5;
labelConstraints.weighty = 1;
labelConstraints.insets = new Insets(5, 10, 5, 10);
GridBagConstraints fieldConstraints = new GridBagConstraints();
fieldConstraints.anchor = GridBagConstraints.WEST;
fieldConstraints.gridx = 1;
fieldConstraints.gridy = 0;
fieldConstraints.weightx = 0.5;
fieldConstraints.weighty = 1;
fieldConstraints.insets = new Insets(5, 10, 5, 10);
topLeftPanel.add(new JLabel("Type"), labelConstraints);
JComboBox<String> typeSelect = new JComboBox<>(new String[] { "stock", "aaaaaaaa" });
topLeftPanel.add(typeSelect, fieldConstraints);
labelConstraints.gridy++;
topLeftPanel.add(new JLabel("Symbol"), labelConstraints);
JTextField symbolField = new JTextField(10);
fieldConstraints.gridy++;
topLeftPanel.add(symbolField, fieldConstraints);
labelConstraints.gridy++;
topLeftPanel.add(new JLabel("Name"), labelConstraints);
JTextField nameField = new JTextField(20);
fieldConstraints.gridy++;
topLeftPanel.add(nameField, fieldConstraints);
labelConstraints.gridy++;
topLeftPanel.add(new JLabel("Quantity"), labelConstraints);
JTextField quantityField = new JTextField(6);
fieldConstraints.gridy++;
topLeftPanel.add(quantityField, fieldConstraints);
labelConstraints.gridy++;
topLeftPanel.add(new JLabel("Price"), labelConstraints);
JTextField priceField = new JTextField(6);
fieldConstraints.gridy++;
topLeftPanel.add(priceField, fieldConstraints);
JPanel topRightPanel = new JPanel(new GridBagLayout());
topRightPanel.setBorder(BorderFactory.createEmptyBorder());
myFrame.add(topRightPanel, BorderLayout.EAST);
GridBagConstraints buttonConstraints = new GridBagConstraints();
buttonConstraints.fill = GridBagConstraints.HORIZONTAL;
buttonConstraints.insets = new Insets(10, 10, 10, 10);
buttonConstraints.weighty = 1;
buttonConstraints.gridy = 0;
JButton reset = new JButton("Reset");
topRightPanel.add(reset, buttonConstraints);
JButton buy = new JButton("Buy");
buttonConstraints.gridy++;
topRightPanel.add(buy, buttonConstraints);
JPanel bottomPanel = new JPanel(new BorderLayout());
myFrame.add(bottomPanel, BorderLayout.SOUTH);
bottomPanel.setBorder(BorderFactory.createTitledBorder("Messages"));
JTextArea messagesArea = new JTextArea(6, 30);
bottomPanel.add(new JScrollPane(messagesArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS), BorderLayout.CENTER);
myFrame.pack();
myFrame.setVisible(true);
}
}
I've implemented a JPanel using a GridBagLayout as follows:
fileSelectionDetails = new JPanel();
fileSelectionGridBagLayout = new GridBagLayout();
fileSelectionDetails.setLayout(fileSelectionGridBagLayout);
JLabel lblFile1 = new JLabel("File 1:");
JTextField txtFile1Path = new JTextField();
JButton btnBrowseFile1 = new JButton("Browse...");
addComponentToFileSelectionGrid(lblFile1, 0, 0, 1, 1, 20, 100, GridBagConstraints.NONE, GridBagConstraints.WEST);
addComponentToFileSelectionGrid(txtFile1Path, 1, 0, 3, 1, 60, 100, GridBagConstraints.HORIZONTAL, GridBagConstraints.WEST);
addComponentToFileSelectionGrid(btnBrowseFile1, 2, 0, 1, 1, 20, 100, GridBagConstraints.HORIZONTAL, GridBagConstraints.WEST);
private void addComponentToFileSelectionGrid(Component component, int gridX, int gridY,
int gridWidth, int gridHeight, int weightX,
int weightY, int fill, int anchor) {
GridBagConstraints constraint = new GridBagConstraints();
constraint.gridx = gridX;
constraint.gridy = gridY;
constraint.gridwidth = gridWidth;
constraint.gridheight = gridHeight;
constraint.weightx = weightX;
constraint.weighty = weightY;
constraint.fill = fill;
constraint.anchor = anchor;
fileSelectionGridBagLayout.setConstraints(component, constraint);
fileSelectionDetails.add(component);
}
I want to see my components laid out as follows:
However, what I'm actually seeing is:
i.e. the 'Browse...' button is missing! Why is this?
From your drawing, I’m guessing you don’t want relative widths at all. It appears you want the label and button to be their preferred sizes, and the JTextField to stretch to take up all of the width not used by the label and button.
As camickr suggested, you should give the JTextField a meaningful preferred size by initializing it with a column count, like new JTextField(20).
You can then take advantage of some useful aspects of GridBagLayout and GridBagConstraints:
The default value of gridx and gridy is RELATIVE, which means each component you add is placed to the right of the last one added. Which just happens to be exactly what you want. Therefore, you should not set gridx or gridy at all.
The default value of gridwidth and gridheight is 1. This is what you want. GridBagLayout cells are flexible, so setting one component’s gridwidth to 3 does not make it three times wider than a component whose gridwidth is 1. The width of a cell, or span of cells, depends entirely on what it contains.
When you add a component to a GridBagLayout, the GridBagConstraints object is cloned inside the GridBagLayout. This means you can safely reuse the same GridBagConstraints object over and over, changing just the fields that need to change.
With this knowledge, your code can be simplified to:
fileSelectionDetails = new JPanel(new GridBagLayout());
JLabel lblFile1 = new JLabel("File 1:");
JTextField txtFile1Path = new JTextField(20);
JButton btnBrowseFile1 = new JButton("Browse\u2026");
txtFile1Path.setMinimumSize(txtFile1Path.getPreferredSize());
GridBagConstraints constraints = new GridBagConstraints();
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.weight = 0;
fileSelectionDetails.add(lblFile1, constraints);
constraints.weight = 1;
fileSelectionDetails.add(txtFile1Path, constraints);
constraints.weight = 0;
fileSelectionDetails.add(btnBrowseFile1, constraints);
You define gridWidth=3 for txtFile1Path but add btnBrowseFile1 at gridX=2. You must set addComponentToFileSelectionGrid(btnBrowseFile1, 4 ...etc.
I'm new to JAVA and GUI. I'm making a GUI screen for my project.
I made a GridLayout with 2 rows. First row has a FlowLayout and 2nd row has a BoxLayout. The panel with the FlowLayout will be constant throughout the program, whereas the panel with BoxLayout might vary. I've enclosed another panel inside the BoxLayout panel with a GridBagLayout. Whenever I'm adding another panel to the BoxLayout, the space between the 1st row and the 2nd row of the GridLayout is increasing.
Can anyone tell me what should I do to stop this from happening?
Is there any way such that the radioButton can be placed in the centre of the panel?
Here is the code:
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
/**
*
* #author arindamchowdhury
*/
public class ScreenTwo {
JRadioButton[] radioButton;
public ScreenTwo() {
start();
}
private void start() {
JFrame frame = new JFrame();
JPanel panel1 = new JPanel();
frame.getContentPane().add(panel1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// Added a panel to the frame with GridLayout. It has 2 rows, and 1 column.
panel1.setLayout(new GridLayout(2, 1, 1, 1));
Font font = new Font("Times New Roman", Font.PLAIN, 25);
JPanel panel2 = new JPanel();
panel2.setLayout(new FlowLayout(FlowLayout.CENTER, 50, 1));
// *** Making a header section using FlowLayout *** //
panel2.add(new JLabel("Flight ID"));
panel2.add(new JLabel("Departure"));
panel2.add(new JLabel("Arrival"));
panel2.add(new JLabel("Total Duration "));
changeFont(panel2, font);
panel1.add(panel2);
// Making the 2nd row of GridLayout, a BoxLayout, so that components are added vertically.
JPanel panel3 = new JPanel();
panel3.setLayout(new BoxLayout(panel3, BoxLayout.Y_AXIS));
panel3.setBorder(BorderFactory.createLineBorder(Color.BLACK));
GridBagConstraints c = new GridBagConstraints();
// When I increase comboSize, the space increases
int comboSize = 1, i;
JPanel panelCombo[] = new JPanel[comboSize];
ButtonGroup group = new ButtonGroup();
radioButton = new JRadioButton[comboSize];
for(i=0; i<comboSize; i++) {
panelCombo[i] = new JPanel();
panelCombo[i].setLayout(new GridBagLayout());
c.gridx = 0;
c.gridy = 0;
c.insets = new Insets(0, 0, 0, 100);
panelCombo[i].add(new JLabel("Hi"), c);
c.gridx++;
panelCombo[i].add(new JLabel("Hi"), c);
c.gridx++;
panelCombo[i].add(new JLabel("Hi"), c);
c.gridx++;
c.gridheight = 4;
panelCombo[i].add(new JLabel("Hi"), c);
// *** Added a RadioButton *** //
c.gridx++;
radioButton[i] = new JRadioButton();
panelCombo[i].add(radioButton[i]);
group.add(radioButton[i]);
c.gridheight = 1;
c.gridx = 1;
c.gridy++;
panelCombo[i].add(new JLabel("Hi"), c);
c.gridx++;
panelCombo[i].add(new JLabel("Hi"), c);
c.gridx = 0;
c.gridy++;
panelCombo[i].add(new JLabel("Hi"), c);
c.gridx++;
panelCombo[i].add(new JLabel("Hi"), c);
c.gridx++;
panelCombo[i].add(new JLabel("Hi"), c);
c.gridx = 1;
c.gridy++;
panelCombo[i].add(new JLabel("Hi"), c);
c.gridx++;
panelCombo[i].add(new JLabel("Hi"), c);
panel3.add(panelCombo[i]);
changeFont(panelCombo[i], font);
panelCombo[i].setBorder(BorderFactory.createLineBorder(Color.BLACK));
}
panel1.add(panel3);
frame.pack();
frame.setVisible(true);
}
// *** A function to change the font of all components of a container *** //
private void changeFont ( Component component, Font font ) {
component.setFont ( font );
if ( component instanceof Container )
{
for ( Component child : ( ( Container ) component ).getComponents () )
{
changeFont ( child, font );
}
}
}
public static void main(String[] args)
{
ScreenTwo sc = new ScreenTwo();
}
}
This is what's happening:
When comboSize is equal to 1:
Whenever I'm adding another panel to the BoxLayout, the space between the 1st row and the 2nd row of the GridLayout is increasing.
The GridLayout of the top level panel spaces components evenly. That means that the top panel with FlowLayout will always have the same space as the bottom panel with BoxLayout, which is the combined space of all the GridBagLayout panels you put in.
Visually, vertical space of red panel = vertical space of blue + green + yellow panels:
As you can see, it's not the space between the 1st and 2nd row that's increasing (that space is 1px and you can actually see it), it's the space of the top panel.
If you want the space of the top panel to remain constant, you would need to add the GridBagLayout panels directly to the top level GridLayout panel without the need for the bottom BoxLayout panel:
gridPanel.setLayout(new GridLayout(0, 1, 1, 1));
// ...
gridPanel.add(topFlowPanel);
// ...
for (...) {
// ...
gridPanel.add(panelCombo[i]);
// ...
}
Note that the vertical gap of 1px is added between all rows now.
Is there any way such that the radioButton can be placed in the CENTRE of the panel?
If you mean center it vertically then you just forgot to add the GridBagConstraints when adding it to the panel:
panelCombo[i].add(radioButton[i], c);
^