Създавам основно приложение 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
не може да се рисува по същия начин. Какво може да не е наред?
Благодаря ви за отделеното време и усилия!