Я создаю базовое приложение Tic-Tac-Toe в Java Swing, и для этой цели я начал исследовать рисование. Однако я столкнулся с проблемой, когда подкласс JPanel
содержит более одного экземпляра подкласса JLabel
, который переопределяет метод paintComponent(Graphic)
, в формате массива GridLayout
, встроенного в него самого. Проблема в том, что закрашивается только первый элемент в этом массиве.
Пример для настроенного подкласса JLabel
:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JLabel;
@SuppressWarnings("serial")
public class DrawLabel extends JLabel {
private boolean hasPaint;
public DrawLabel() {
super();
this.hasPaint = false;
}
public void draw() {
hasPaint = true;
repaint();
}
public void clear() {
hasPaint = false;
repaint();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
if (hasPaint) {
g2.drawOval(getX(), getY(), getWidth(), getHeight());
} else {
g2.clearRect(getX(), getY(), getWidth(), getHeight());
}
}
}
Пример для настроенного подкласса JPanel
:
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class DrawPanel extends JPanel {
private Dimension size;
private DrawLabel[][] fields;
public DrawPanel(Dimension d) {
super();
this.size = d;
this.fields = new DrawLabel[size.height][size.width];
this.setLayout(new GridLayout(size.height, size.width));
for (int i = 0; i < size.height; i++) {
for (int j = 0; j < size.width; j++) {
this.fields[i][j] = new DrawLabel();
this.add(fields[i][j]);
}
}
}
public void draw(int row, int col) {
fields[row][col].draw();
}
public void clear() {
for (int i = 0; i < size.height; i++) {
for (int j = 0; j < size.width; j++) {
fields[i][j].clear();
}
}
}
}
Пример сценария, вызывающего проблему:
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
public class Driver {
public static void main(String[] args) {
DrawPanel board = new DrawPanel(new Dimension(2, 1));
JFrame canvas = new JFrame();
canvas.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
canvas.add(board, BorderLayout.CENTER);
canvas.pack();
canvas.setLocationRelativeTo(null);
canvas.setVisible(true);
board.draw(0, 0); // This gets painted.
board.draw(0, 1); // This does not get painted!
}
}
Любопытно, что если DrawPanel.draw(int, int)
изменить, чтобы установить текст элемента, а не использовать его, обновится только второй элемент, а первый нет, что является полной противоположностью исходной проблеме.
Я пытался найти другие проблемы и вопросы, связанные с отрисовкой подкомпонентов, но мне еще предстоит найти проблему, подобную этой, где кажется, что каждый экземпляр после первого в GridLayout
не рисуется одинаково. Что может быть не так?
Спасибо за ваше время и усилия!