java 在 JPanel 上重新绘制/刷新 JLabel

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5522336/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 11:31:31  来源:igfitidea点击:

Repainting/refreshing JLabels on a JPanel

javaswingjpanelrepaintpaintcomponent

提问by thomas

I'm having trouble getting my JLabels in a 2D array to update during runtime.

我无法在运行时更新二维数组中的 JLabel。

The program I'm working on is a variant of Connect Four. I create a 2D array of JLabels, which all default to an ImageIcon containing an image of a blank slot. Players 1 and 2 choose their colors, and on a player's turn, he can click to drop a piece into a column (gravity causes the piece to fall to the bottom or until it lands atop another piece).

我正在开发的程序是 Connect Four 的变体。我创建了一个 JLabel 的 2D 数组,它们都默认为包含空白插槽图像的 ImageIcon。玩家 1 和 2 选择他们的颜色,在轮到玩家时,他可以点击将一个棋子放入一列(重力导致棋子落到底部或直到它落在另一个棋子上)。

I'm pretty positive that my addToColumn method is working fine. My only problem is that I can't seem to get any of the JLabels to update. Here's the method I'm working on:

我非常肯定我的 addToColumn 方法工作正常。我唯一的问题是我似乎无法更新任何 JLabel。这是我正在研究的方法:

p1, p2, and current are Player objects. grid[][] is a 2D array of integers set to 0, 1, or 2 to more easily track who owns which tiles. tiles[][] is my 2D array of JLabels.

p1、p2 和 current 是 Player 对象。grid[][] 是一个 2D 整数数组,设置为 0、1 或 2,以便更轻松地跟踪谁拥有哪些图块。tiles[][] 是我的 JLabel 的二维数组。

public void addToColumn(int column) { // drop a tile in the specified column
int i = 0;
while (grid[column][5-i] != 0) i++; // move upward through the 6 rows of tiles
                                    // until we find an empty one
if (current == p1) grid[column][5-i] = 1; // update to the current player's value
else grid[column][5-i] = 2;

tiles[column][5-i] = new JLabel(findColorIcon(current.getColor()));

tiles[column][5-i].setIcon(findColorIcon(current.getColor()));

repaint();

now with those last two lines changing the JLabel in tiles[][], obviously I don't need both, not sure which way is better... that's just some of what I've tried, to no avail. (my getColor() method returns a Color, and findColorIcon(Color c) returns the corresponding JLabel with that color of tile).

现在最后两行更改了tile [] []中的JLabel,显然我不需要两者,不确定哪种方式更好......这只是我尝试过的一些方法,但无济于事。(我的 getColor() 方法返回一个颜色,而 findColorIcon(Color c) 返回具有该瓷砖颜色的相应 JLabel)。

and yes, I have added in my paintComponent method too:

是的,我也添加了我的paintComponent方法:

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
}

I've been stuck on this for a while now, and I feel like I'm missing something obvious. any suggestions?

我已经坚持了一段时间了,我觉得我错过了一些明显的东西。有什么建议?

回答by trashgod

I don't see that your paintComponent()method does anything. In particular, replacing a JLabelrequires that you validate()the container. As an alternative, you might like to see how this simple gameuses the Model–View–Controller pattern and draws colored icons.

我看不出你的paintComponent()方法有什么作用。特别是,替换 aJLabel需要您validate()的容器。作为替代方案,您可能想看看这个简单的游戏如何使用模型-视图-控制器模式并绘制彩色图标。

Addendum: This related exampledescribes how to replace just the Icon, rather than the entire JLabel. In contrast, this exampleshows how to validate()a container after replacing components.

附录:此相关示例描述了如何仅替换Icon. 而不是整个JLabel. 相比之下,这个例子展示了如何validate()在替换组件后创建一个容器。