You could us a JSeparator or, break each group of 3x3 fields into there own separate panes and use a LineBorder.
So long as you've setup you fields properly, you should be able to get the compound panels/LineBorder
to work
UPDATE
Sorry, it should have been MatteBorder
:P
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridx = 0;
gbc.gridy = 0;
for (int row = 0; row < 4; row++) {
gbc.gridx = 0;
add(buildGroup(0, 0, 1, 1), gbc);
gbc.gridx++;
add(buildGroup(0, 0, 1, 1), gbc);
gbc.gridx++;
add(buildGroup(0, 0, 1, 1), gbc);
gbc.gridx++;
add(buildGroup(0, 0, 1, 0), gbc);
gbc.gridy++;
}
public JPanel buildGroup(int top, int left, int bottom, int right) {
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(new MatteBorder(top, left, bottom, right, Color.RED));
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(2, 2, 2, 2);
gbc.fill = GridBagConstraints.HORIZONTAL;
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
JTextField field = new JTextField(8);
gbc.gridx = col;
gbc.gridy = row;
panel.add(field, gbc);
}
}
return panel;
}
Now, obviously, you need to figure out how you'd seed your fields, but basically, I'd just pass in the fields you want to be used (such as 2D array for example).
Or with separators :P
for (int row = 0; row < 9; row++) {
gbc.gridwidth = 1;
gbc.weightx = 0;
int verSplit = 0;
for (int col = 0; col < 12; col++) {
gbc.gridx++;
add(new JTextField(8), gbc);
verSplit++;
if (verSplit == 3) {
verSplit = 0;
gbc.gridx++;
if (horSplit % 3 == 0) {
gbc.gridheight = 3;
gbc.fill = GridBagConstraints.VERTICAL;
add(new JSeparator(JSeparator.VERTICAL), gbc);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridheight = 1;
}
}
}
horSplit++;
gbc.gridx = 0;
if (horSplit == 3) {
horSplit = 0;
gbc.gridy++;
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
add(new JSeparator(JSeparator.HORIZONTAL), gbc);
}
gbc.gridy++;
}
Or variations on the same theme
UPDATED with field management
// Build the array of fields, I used a col by row matrix
JTextField fields[][] = new JTextField[12][12];
for (int col = 0; col < 12; col++) {
for (int row = 0; row < 12; row++) {
fields[col][row] = new JTextField(col + "x" + row, 8);
}
}
// Build the groups...
for (int row = 0; row < 12; row++) {
gbc.gridx = 0;
int col = 0;
add(buildGroup(fields, col, row, 0, 0, 1, 1), gbc);
col += 3;
gbc.gridx++;
add(buildGroup(fields, col, row, 0, 0, 1, 1), gbc);
col += 3;
gbc.gridx++;
add(buildGroup(fields, col, row, 0, 0, 1, 1), gbc);
col += 3;
gbc.gridx++;
add(buildGroup(fields, col, row, 0, 0, 1, 0), gbc);
gbc.gridy++;
row += 2; // This is important, don't miss this ;)
}
public JPanel buildGroup(JTextField[][] fields, int startCol, int startRow, int top, int left, int bottom, int right) {
JPanel panel = new JPanel(new GridBagLayout());
panel.setBorder(new MatteBorder(top, left, bottom, right, Color.RED));
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(2, 2, 2, 2);
gbc.fill = GridBagConstraints.HORIZONTAL;
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
// Get the field to use for this cell
JTextField field = fields[col + startCol][row + startRow];
gbc.gridx = col;
gbc.gridy = row;
panel.add(field, gbc);
}
}
return panel;
}