【发布时间】:2014-12-04 12:49:17
【问题描述】:
我正在用 Java Swing 创建一个基本的井字游戏应用程序,为此,我开始研究绘图。但是,当JPanel 的子类包含多个JLabel 子类的实例时,我遇到了一个问题,该实例以嵌入在自身中的GridLayout 数组格式覆盖paintComponent(Graphic) 方法。问题在于仅绘制了此数组中的第一个元素。
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 中第一个以外的每个实例都无法在同样的方法。有什么问题?
感谢您的时间和精力!
【问题讨论】:
-
MarkLabel 缺少 repaint()
-
@mKorbel 绘画预计会发生在 MarkLabel.drawMark(Mark),其中还包含对 repaint() 的调用。
-
"..我以后一定会这样做的!"那么我必须确保我以后注意你的问题..当然,现在可以edit this question。
-
@AndrewThompson 我的道歉。我在保持相同分隔的同时最小化了问题实例的显示范围。还有什么我可以做的吗?
标签: java swing jlabel paintcomponent repaint