I only started using Java Swing yesterday, so pardon me if this isn't a valid question. I've been trying to create a simple UI with a grid and a panel that allows the user to specify the size of dimensions of the grid.
I have two classes extending JPanel: GridSizePanel
and GridBoxPanel
. GridSizePanel
specifies the title, border, labels and fields involved in designing the panel that allows the user to alter dimensions. GridBoxPanel
displays the actual grid (adopted from here). GridSizePanel
uses the GroupLayout as its LayoutManager and GridBoxPanel
uses GridBagLayout. The parent JFrame class(MazeSolverInterface
) which orchestrates these sub-panels uses GroupLayout as it's LayoutManager.
The problem is, if I only add the GridSizePanel
to the MazeSolverInterface
's GroupLayout, when I resize the window manually, I can see the GridSizePanel
resizing automatically. All good.
But when I add the GridBoxPanel
to the MazeSolverInterface
, now when I resize the window manually, only the GridBoxPanel
seems to resize. The GridSizePanel
doesn't change dimension at all!
Here's my code so far:
GridSizePanel:
public class GridSizePanel extends JPanel implements PropertyChangeListener {
public GridSizePanel() throws ParseException {
// set the border properties
TitledBorder title = BorderFactory.createTitledBorder("Grid Size");
title.setTitleColor(Color.BLACK);
title.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED,
Color.DARK_GRAY, Color.GRAY));
this.setBorder(title);
// wire up the group layout and panel to
// each other
GroupLayout gl = new GroupLayout(this);
this.setLayout(gl);
// Turn on automatically adding gaps between components
gl.setAutoCreateGaps(true);
// Turn on automatically creating gaps between components that touch
// the edge of the container and the container.
gl.setAutoCreateContainerGaps(true);
JLabel numRowsLabel = new JLabel("rows");
JLabel numColsLabel = new JLabel("columns");
MaskFormatter textMask = new MaskFormatter("##");
textMask.setPlaceholder("16");
JFormattedTextField rowsText = new JFormattedTextField(textMask);
JFormattedTextField colsText = new JFormattedTextField(textMask);
// configure the text fields
rowsText.setColumns(50);
colsText.setColumns(50);
rowsText.addPropertyChangeListener("value", this);
colsText.addPropertyChangeListener("value", this);
GroupLayout.SequentialGroup horGroup = gl.createSequentialGroup();
horGroup.addGroup(gl.createParallelGroup().addComponent(numRowsLabel).addComponent(numColsLabel))
.addGroup(gl.createParallelGroup().addComponent(rowsText).addComponent(colsText));
gl.setHorizontalGroup(horGroup);
GroupLayout.SequentialGroup verGroup = gl.createSequentialGroup();
verGroup.addGroup(gl.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(numRowsLabel).addComponent(rowsText))
.addGroup(gl.createParallelGroup(GroupLayout.Alignment.BASELINE).addComponent(numColsLabel).addComponent(colsText));
gl.setVerticalGroup(verGroup);
}
//public GridSize getSize() {
// return new GridSize()
//}
@Override
public void propertyChange(PropertyChangeEvent propertyChangeEvent) {
// TODO: fill this with logic to relay grid dimensions to the model
}
}
GridBoxPanel:
public class GridBoxPanel extends JPanel {
public GridBoxPanel() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
for (int row = 0; row < 32; row++) {
for (int col = 0; col < 32; col++) {
gbc.gridx = col;
gbc.gridy = row;
GridCell gridCell = new GridCell();
Border border = null;
if (row < 4) {
if (col < 4) {
border = new MatteBorder(1, 1, 0, 0, Color.GRAY);
} else {
border = new MatteBorder(1, 1, 0, 1, Color.GRAY);
}
} else {
if (col < 4) {
border = new MatteBorder(1, 1, 1, 0, Color.GRAY);
} else {
border = new MatteBorder(1, 1, 1, 1, Color.GRAY);
}
}
gridCell.setBorder(border);
add(gridCell, gbc);
}
}
}
}
MazeSolverInterface:
public class MazeSolverInterface extends JFrame {
public MazeSolverInterface(String[] args) throws ParseException {
checkArgs(args);
initMaze(args);
}
public void initMaze(String[] args) throws ParseException {
Container pane = getContentPane();
GroupLayout gl = new GroupLayout(pane);
pane.setLayout(gl);
gl.setAutoCreateContainerGaps(true);
// create required panels to integrate
GridSizePanel gridSizeComponent = new GridSizePanel();
GridBoxPanel gridDrawComponent = new GridBoxPanel();
gl.setHorizontalGroup(gl.createSequentialGroup().addComponent(gridDrawComponent).addGap(50).addComponent(gridSizeComponent));
gl.setVerticalGroup(gl.createParallelGroup().addComponent(gridDrawComponent).addGap(50).addComponent(gridSizeComponent));
pack();
setTitle("v0.0.1");
setSize(700, 700); // TODO: change to something configurable
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public void checkArgs(String[] args) {
// TODO: fill with logic to check valid arguments (initial window dimensions)
}
}
Main:
public class Main {
public static void main(final String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MazeSolverInterface ex = null;
try {
ex = new MazeSolverInterface(args);
} catch (ParseException e) {
e.printStackTrace();
}
ex.setVisible(true);
}
});
}
}
Here's how the UI looks before adding GridBoxLabel to the MazeSolverInterface:
...and after adding GridBoxLabel to the MazeSolverInterface:
Any/all help is appreciated. Thank you!
EDIT:
As you can see above, GridBoxPanel
uses the GridCell
class. I forgot to add that to this post, so here it is. Hope this helps!
GridCell:
public class GridCell extends JPanel {
private Color defaultBackground;
public GridCell() {
addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
defaultBackground = getBackground();
setBackground(Color.BLUE);
}
@Override
public void mouseExited(MouseEvent e) {
setBackground(defaultBackground);
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(50, 50);
}
}