Никогда не рисовать прямо на JFrame, как вы пытаетесь сделать. Это сопряжено с существенным риском, если вы не знаете, что делаете (например, вы не называете метод краски супер, и таким образом небрежно разрушаете цепочку рисования), и образы не будут отображаться, как они будут быть охвачены непрозрачной панелью содержимого.
Если вам нужно нарисовать, сделайте это в JPanel, который будет отображаться внутри JFrame, но опять же, как в моем примере ниже, нет необходимости рисовать, если все, что вам нужно, это черные прямые линии в сетке.
Используйте GridLayout и установите некоторые пробелы в свой макет. Поймите, что третий и четвертый параметры конструктора GridLayout дадут вам пробелы. Затем дайте базовый фон JPanel Color.BLACK, и там вы идете: линии! Например, с JTextFields:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
public class SudokuMCVE extends JPanel {
private static final int CLUSTER = 3;
private static final int MAX_ROWS = 9;
private static final float FIELD_PTS = 32f;
private static final int GAP = 3;
private static final Color BG = Color.BLACK;
private static final Color SOLVED_BG = Color.LIGHT_GRAY;
public static final int TIMER_DELAY = 2 * 1000;
private JTextField[][] fieldGrid = new JTextField[MAX_ROWS][MAX_ROWS];
public SudokuMCVE() {
JPanel mainPanel = new JPanel(new GridLayout(CLUSTER, CLUSTER));
mainPanel.setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
mainPanel.setBackground(BG);
JPanel[][] panels = new JPanel[CLUSTER][CLUSTER];
for (int i = 0; i < panels.length; i++) {
for (int j = 0; j < panels[i].length; j++) {
panels[i][j] = new JPanel(new GridLayout(CLUSTER, CLUSTER, 1, 1));
panels[i][j].setBackground(BG);
panels[i][j].setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
mainPanel.add(panels[i][j]);
}
}
for (int row = 0; row < fieldGrid.length; row++) {
for (int col = 0; col < fieldGrid[row].length; col++) {
fieldGrid[row][col] = createField(row, col);
int i = row/3;
int j = col/3;
panels[i][j].add(fieldGrid[row][col]);
}
}
setLayout(new BorderLayout());
add(mainPanel, BorderLayout.CENTER);
add(new JButton(new SolveAction("Solve")), BorderLayout.PAGE_END);
}
private JTextField createField(int row, int col) {
JTextField field = new JTextField(2);
field.setHorizontalAlignment(JTextField.CENTER);
field.setFont(field.getFont().deriveFont(Font.BOLD, FIELD_PTS));
return field;
}
private class SolveAction extends AbstractAction {
public SolveAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
new Timer(TIMER_DELAY, new ActionListener() {
private int i = 0;
private int j = 0;
@Override
public void actionPerformed(ActionEvent e) {
// MAX_ROWS is 9
if (i == MAX_ROWS) {
((Timer) e.getSource()).stop();
}
if (j == MAX_ROWS) {
i++;
j = 0;
}
int number = (int) (MAX_ROWS * Math.random()) + 1;
fieldGrid[i][j].setBackground(SOLVED_BG);
fieldGrid[i][j].setText(String.valueOf(number));
j++;
}
}).start();
}
}
private static void createAndShowGui() {
SudokuMCVE mainPanel = new SudokuMCVE();
JFrame frame = new JFrame("SudokuMCVE");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
Который показывает, как:
Или с JButtons:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;
@SuppressWarnings("serial")
public class JPanelGrid extends JPanel {
private static final int SML_SIDE = 3;
private static final int SIDE = SML_SIDE * SML_SIDE;
private static final int GAP = 3;
private static final Color BG = Color.BLACK;
private static final Dimension BTN_PREF_SIZE = new Dimension(80, 80);
private JButton[][] buttons = new JButton[SIDE][SIDE];
public JPanelGrid() {
setBackground(BG);
setLayout(new GridLayout(SML_SIDE, SML_SIDE, GAP, GAP));
setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
JPanel[][] smallPanels = new JPanel[SML_SIDE][SML_SIDE];
for (int i = 0; i < smallPanels.length; i++) {
for (int j = 0; j < smallPanels[i].length; j++) {
smallPanels[i][j] = new JPanel(new GridLayout(SML_SIDE, SML_SIDE));
add(smallPanels[i][j]);
}
}
for (int i = 0; i < buttons.length; i++) {
int panelI = i/SML_SIDE;
for (int j = 0; j < buttons[i].length; j++) {
int panelJ = j/SML_SIDE;
String text = String.format("[%d, %d]", j, i);
buttons[i][j] = new JButton(text);
buttons[i][j].setPreferredSize(BTN_PREF_SIZE);
smallPanels[panelI][panelJ].add(buttons[i][j]);
}
}
}
private static void createAndShowGui() {
JPanelGrid mainPanel = new JPanelGrid();
JFrame frame = new JFrame("JPanelGrid");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
который отображает:
Большое спасибо за объяснение, теперь я понимаю. – xZeasy