Java 移动组件后重新绘制

Java 移动组件后重新绘制,java,swing,components,repaint,Java,Swing,Components,Repaint,一开始我想强调的是,我对Java非常陌生,我总是试图自己找到问题的答案,但有时我会走到死胡同,这就是为什么我想问你,你对此有什么想法 我试着做一个纸牌游戏。我想做一件非常简单的事情(在我看来),就是将一个带有卡的图像的JLabel从一个点移动到它的父JPanel内的另一个点,以一系列延迟40毫秒的移动来创建一个处理卡的“动画” 然而,当我尝试这样做时,尽管我刷新了父JPanel,我还是得到了卡的副本。我一直在寻找一个答案如何做到这一点很长一段时间,直到现在,没有任何工作为我。我试图用卡本身刷新J

一开始我想强调的是,我对Java非常陌生,我总是试图自己找到问题的答案,但有时我会走到死胡同,这就是为什么我想问你,你对此有什么想法

我试着做一个纸牌游戏。我想做一件非常简单的事情(在我看来),就是将一个带有卡的图像的JLabel从一个点移动到它的父JPanel内的另一个点,以一系列延迟40毫秒的移动来创建一个处理卡的“动画”

然而,当我尝试这样做时,尽管我刷新了父JPanel,我还是得到了卡的副本。我一直在寻找一个答案如何做到这一点很长一段时间,直到现在,没有任何工作为我。我试图用卡本身刷新JLabel,它的父JPanel也是,但没有任何效果

唯一的部分解决方案是重新绘制JPanel,即使用JLabel的JPanel的父级,但它导致整个GUI闪烁,这是不可接受的。只有在那时,我在这里附上的图片中才没有类似的复制品

注意:我使用绝对布局,但我知道这是多么不专业。这只是因为我不知道如何使用另一个管理器来遵守我的布局的其余部分

如果您能为我提供任何提示或解决方案,我将不胜感激

展示我想要实现的目标的图像

呈现现状的图像


Swing GUI和
线程。sleep
不要混合使用。这就是我们的目的。看一看,然后。这可能有用。而且,正如@TNT建议的那样,将
Thread.Sleep
放在那里不是一个好主意。不要使用getGraphics()。不要直接调用任何绘制方法(即绘制组件)。setLocation()应该使组件在新位置重新绘制自身。
我使用绝对布局,
-需要一个空布局(可能您的IDE称之为绝对布局)来设置卡片移动的动画。但是,您可能需要考虑使用布局管理器来设计主GUI。然后,要处理一张卡,您可以使用玻璃窗格,并让卡在玻璃窗格上从卡牌组的位置移动到其最终位置。@TNT非常感谢您。现在我使用的是Swing定时器,它工作得很好,但现在的问题是,我希望程序在定时器完成工作后继续运行,但现在它似乎在同时做所有事情。如何使事件调度线程等待计时器完成?Swing GUI和
线程。sleep
不要混合使用。这就是我们的目的。看一看,然后。这可能有用。而且,正如@TNT建议的那样,将
Thread.Sleep
放在那里不是一个好主意。不要使用getGraphics()。不要直接调用任何绘制方法(即绘制组件)。setLocation()应该使组件在新位置重新绘制自身。
我使用绝对布局,
-需要一个空布局(可能您的IDE称之为绝对布局)来设置卡片移动的动画。但是,您可能需要考虑使用布局管理器来设计主GUI。然后,要处理一张卡,您可以使用玻璃窗格,并让卡在玻璃窗格上从卡牌组的位置移动到其最终位置。@TNT非常感谢您。现在我使用的是Swing定时器,它工作得很好,但现在的问题是,我希望程序在定时器完成工作后继续运行,但现在它似乎在同时做所有事情。如何使事件调度线程等待计时器完成?
public void moveCard() 
{
// move the card to x = 0 (its destination) inside the parent panel 
while (movedCard.getX() != 0)
    {
    // try to reach x = 0
    // as the starting x cannot be divided through 20 it must subtract 21 once at the end
    if (movedCard.getX() == 21)
        {
        movedCard.setLocation(movedCard.getX() - 21, movedCard.getY());
        }
        else
        {
        movedCard.setLocation(movedCard.getX() - 20, movedCard.getY());
        }
        // repaint the panel that the card is drawn on
        movedCard.getParent().paintComponents(movedCard.getParent().getGraphics());

        // wait until the card is moved for the next time  
        try
            {
                Thread.sleep(40);
            }
            catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
        // set the location of the card to default
        movedCard.setLocation(341, movedCard.getY());
    }
}