In the class that extends JFrame, I have the following code:
public Frame() {
setTitle("WORDLE");
// creates all containers
Container mainContainer = getContentPane();
JPanel gridContainer = new JPanel();
JPanel optionsContainer = new JPanel();
// sets size of main frame
setSize(WIDTH, 900);
// sets background size and background colors of all containers
gridContainer.setBackground(GameTheme.BACKGROUND); // TODO: add message label inside of gridContainer below grid JPanel
gridContainer.setPreferredSize(new Dimension(WIDTH - 150, 500));
gridContainer.setMaximumSize(new Dimension(WIDTH - 150, 500));
gridContainer.setLayout(new BorderLayout(10, 0));
optionsContainer.setBackground(GameTheme.BACKGROUND);
optionsContainer.setPreferredSize(new Dimension(WIDTH, 100));
// creates grid with boxes for letter
grid = new JPanel();
grid.setLayout(new GridLayout(6, 5, 5, 5));
grid.setPreferredSize(new Dimension(WIDTH - 150, 400));
grid.setMaximumSize(new Dimension(WIDTH - 150, 400));
grid.setBackground(GameTheme.BACKGROUND);
createBoxes();
// JLabel for messages
JLabel alertLabel = new JLabel("test");
alertLabel.setOpaque(true);
alertLabel.setForeground(GameTheme.WHITE);
alertLabel.setBackground(GameTheme.BACKGROUND);
// listens for presses in the JFrame, with the Game class implementing the method for the keypress event
addKeyListener(new Game(boxes));
// lays out all containers and their sub-containers
// title label at top, grid container at center, options container at bottom
mainContainer.setLayout(new BorderLayout());
mainContainer.add(createTitle(), BorderLayout.NORTH); // createTitle returns a JLabel
mainContainer.add(gridContainer, BorderLayout.CENTER);
mainContainer.add(optionsContainer, BorderLayout.SOUTH);
gridContainer.add(grid, BorderLayout.NORTH);
gridContainer.add(alertLabel, BorderLayout.SOUTH);
// boilerplate frame configuration
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setLocationRelativeTo(null);
pack();
setVisible(true);
}
public void createBoxes() {
// initializes 2d array for letter boxes
boxes = new LetterBox[6][5];
// populates 2d array and adds boxes to the grid container
for (int r = 0; r < 6; r++) {
for (int c = 0; c < 5; c++) {
LetterBox letterBox = new LetterBox(r, c);
boxes[r][c] = letterBox;
grid.add(letterBox.getBox());
}
}
}
I have set a maximum size on all of the components within gridContainer, and even on the gridContainer itself, yet the JLabels are still stretching to take up the size of the GUI. Can someone help me figure out why this is happening, and how I can fix it?
To make the problem clear, here are some images that show what I want vs what I am getting:
I tried to describe as clearly as possible please comment and let me know if there is anything I need to clarify.


Don't keep playing with the preferred/minimum/maximum sizes of parent panels and the frame. Each panel should be able to calculate its preferred size based on the preferred size of the components added to the panel. So you add components to a panel and the panels to the frame, then you pack the frame and everything will be displayed at the proper size.
So in your case you can use a
GridLayoutfor your "gridContainer". Then you add your JLabels to the gridContainer. For your LetterBox component you should use a "monospaced" Font so all characters will take the same space. Then you can initialize your label with a default value of " " to give the label a size.This size will be too small so you will then also want to add an
EmptyBorderto theLetterBox. So in the constructor you can add something like:Now the LeterBox can calculates its preferred size correctly and the "gridContainer" will be able to calculate its preferred size correctly.
However, when you add the panel the the CENTER of the BorderLayout, the BorderLayout will attempt to resize each component to fill the space available in the frame. To prevent this you can use a "wrapper" panel:
Now if the frame is resized the extra space will go to the wrapper panel NOT the gridContainer.