为什么repaint()不总是调用paintComponent,以及为什么它在被调用时并不总是表现正确

为什么repaint()不总是调用paintComponent,以及为什么它在被调用时并不总是表现正确

我正在用Java开发一个俄罗斯方块的克隆体,一切似乎都很正常,直到我想要清除整行并删除上面的所有内容。尽管我的所有数据都正确地表示了转换,但我的paintComponent方法似乎只清除了行,但将上面显示的所有内容都保留为调用repaint()之前的样子。新的一块将通过幻影块落下,并落在底部一排看不见的块上,上面的块就会掉在那里。

下面是我的paint组件方法:

代码语言:javascript复制public void paintComponent(Graphics page)

{

super.paintComponent(page);

Graphics2D page2D = (Graphics2D) page;

for (int c = 0; c < 10; c++)

{

for (int r = 0; r < 18; r++)

{

if (well[c][r] != null) //Well is a 2D array of Block objects that have Rectangle object, coordinates and color

{

page2D.setColor(well[c][r].getColor());

page2D.fill(well[c][r].getSquare());

page2D.setColor(Color.gray);

page2D.draw(well[c][r].getSquare());

}

}

}

for (int i = 0; i < 4; i++) //tetro = the player's tetris piece

{

page2D.setColor(tetro.getColor());

page2D.fill(tetro.getBlock(i).getSquare());

page2D.setColor(Color.GRAY);

page2D.draw(tetro.getBlock(i).getSquare());

}

}这是我的计时器侦听器中actionPerformed方法的一部分,用于检测/清除块并调用repaint方法。

代码语言:javascript复制 int count = 0; //Number of occupied cells in well

int clears = 0; //number of rows to be clear

int lowestClear = -1; //Lowest row that was cleared, -1 if none

for (int row = 0; row < 18; row++)

{

for (int col = 0; col < 10; col++)

{

if (well[col][row] != null)

{

count++;

}

}

if (count == 10)

{

clears++;

if (lowestClear < 0)

{

lowestClear = row;

}

for (int col = 0; col < 10; col++)

{

well[col][row] = null;

}

}

count = 0;

}

if (clears > 0)

{

repaint(); //Doesn't call paintComponent()

for (int i = 1; i <= clears; i++)

{

for (int r = 16; r >= 0; r--)

{

if (r > lowestClear)

{

break;

}

for (int c = 0; c < 10; c++)

{

if (well[c][r] != null)

{

well[c][r+1] = well[c][r];

well[c][r] = null;

}

}

}

}

repaint(); //Does not call paintComponent()

}

tetro.fall();

repaint(); //DOES call paint component在调用第一个repaint()方法时,well数组正确地显示整行现在完全为空。我希望repaint()方法更新面板以显示这个空行,但似乎没有调用paintComponent()。第二个repaint()方法也是如此,我希望它在清空一行并将块拖放到新位置后更新帧,以显示新位置的块。同样,不会调用paintComponent()。然而,对于最后一次repaint()调用,我只想更新坠落的碎片的位置,而不管它之前可能需要或不需要进行任何更新,repaint()确实调用了paintComponent()。所以:第一个问题是,为什么paintComponent()只在repaint()调用的这个实例中调用。

但是,当调用paintComponent()并到达方法的末尾时,我会在调试模式下跟踪它,以查看面板在哪一行反映了更改。一旦它到达:"Repaintmanager.paintDirtyRegions(Map< Component,Rectangle >)“行:856,它就清除了该行并显示新的下降块,但具有不可见的块和幻块。

所以,我的第二个问题是,为什么paintComponent()会这样。显然,我需要对Repaintmanager和Java绘画做一些一般性的阅读,但如果有人能给我解释一下,我会非常感激。

如果重要,下面是main方法:

代码语言:javascript复制import javax.swing.JFrame;

public class TetrisDriver

{

public static void main(String[] args)

{

JFrame frame = new JFrame("Tetris");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.getContentPane().add(new Matrix()); //Matrix = jPanel class

frame.pack();

frame.setVisible(true);

}}

如果这篇文章太长了,我很抱歉。

相关内容

海鲈鱼应该怎么去腥
365上怎么买比分

海鲈鱼应该怎么去腥

⌛ 02-18 👁️ 7303
不是评测、只是建议——对比MDAC和MD11解码器
365上怎么买比分

不是评测、只是建议——对比MDAC和MD11解码器

⌛ 09-18 👁️ 9297
在Windows中修复硬盘只读模式的4种巧妙办法!
bst365大陆投注

在Windows中修复硬盘只读模式的4种巧妙办法!

⌛ 10-24 👁️ 4589
中国矿业大学主页平台系统 鲍宇
365名品汇推荐码多少

中国矿业大学主页平台系统 鲍宇

⌛ 01-21 👁️ 1540
OCP NVME SSD规范解读-13.Self-test自检要求
365名品汇推荐码多少

OCP NVME SSD规范解读-13.Self-test自检要求

⌛ 06-15 👁️ 279
随身wifi流量来源揭秘:信号覆盖与运营商合作机制
365上怎么买比分

随身wifi流量来源揭秘:信号覆盖与运营商合作机制

⌛ 08-31 👁️ 9129
使用安全中心,保护手机安全
365上怎么买比分

使用安全中心,保护手机安全

⌛ 09-13 👁️ 9736
健康保险购买多长时间生效
365名品汇推荐码多少

健康保险购买多长时间生效

⌛ 11-12 👁️ 6106