简体   繁体   English

如何在不使用Timer的情况下实现平稳下降的JLabel,而是使用线程

[英]How to implement a smoothly falling JLabel without using Timer, but Threads instead

Alright, so I have a null layout JPanel with a single JLabel in it. 好吧,所以我有一个带有单个JLabel的空布局JPanel The JLabel is positioned at (0,0). JLabel位于(0,0)。 What I'm trying to do is use a while loop in a new Thread to sleep the new Thread and then shift the JLabel 10px down by using SwingUtilities.invokeLater . 我想做的是在新Thread使用while循环休眠新Thread ,然后使用SwingUtilities.invokeLaterJLabel下移10px。 The problem is that the UI gets updated in a laggy sort of way. 问题在于,UI的更新方式有些滞后。 It doesn't update every time it should, but skips lots of updates and shifts in big chunks. 它不会每次都更新,但是会跳过很多更新并大块转移。 I know I can easily do it with Timer , but the point is understanding Threads better. 我知道我可以使用Timer轻松地做到这一点,但重点是要更好地理解Threads Thanks in advance! 提前致谢!

Code: 码:

private void start(){
    Updater up = new Updater();
    up.start();
}
public void updatePosition(){
    int y = label1.getLocation.y;
    label.setBounds(0,y+10, 10,10);
}
private class Updater extends Thread{
    public void run(){
        while(!shouldQuit){
            try{
                Updater.sleep(100);
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                       updatePosition(); 
                    }
                }); 
            }catch(Exception e){
                System.out.println(e);
            }      
        }   
    }
}

EDIT: I got it to work by replacing the while loop with a call to a new Thread instance in the updatePosition() method, to settle things down a bit. 编辑:我通过将while循环替换为对updatePosition()方法中的新Thread实例的调用来工作,以解决问题。 And also, it wasn't only the Thread that was causing the problem, so I had to force the panel to re-layout it's subviews by calling revalidate() on it. 而且,不仅是导致问题的线程,所以我不得不通过调用revalidate()来迫使面板重新布局其子视图。 Here's how it looks (the fully working one): 这是它的外观(完全有效的外观):

private void start(){
    new Updater().start();
}
public void updatePosition(){
    int y = label1.getLocation.y;
    label.setBounds(0,y+10, 10,10);
    panel.revalidate();
    if(!shouldQuit) new Updater().start();
}
private class Updater extends Thread{
    public void run(){
        try{
            Updater.sleep(100);
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    updatePosition(); 
                }
            }); 
        }catch(Exception e){
            System.out.println(e);
        }   
    }
}

You should try to use visibility and GridLayout to maximize movement. 您应该尝试使用可见性和GridLayout来最大化移动。 You can use a int var to count threads and reciprocate that to the label. 您可以使用int var来计数线程并将其往复到标签上。 As well, you should be using your ability o create Updaters, more and smoother. 同样,您应该利用自己的能力来创建更新程序,并且更加流畅。 Just do the start() mwthod while trolling for threads :-) 只需在拖曳线程时执行start()mwthod :-)

You could have something besides an infinity call to start. 除了无限调用外,您还可以进行其他操作。 I think you've lost the inheritance from the class, itself. 我认为您已经失去了从类本身的继承。 The object label1 must ave been lost in tbe fray. label1必须在丢失时丢失。 If that's not it, then I'm pretty sure I'm not really able to answer this one. 如果不是那样,那么我很确定我真的不能回答这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM