如何在不使用 Timer 而是使用 Threads 的情况下实现平滑下降的 JLabel
Posted
技术标签:
【中文标题】如何在不使用 Timer 而是使用 Threads 的情况下实现平滑下降的 JLabel【英文标题】:How to implement a smoothly falling JLabel without using Timer, but Threads instead 【发布时间】:2016-01-08 16:24:30 【问题描述】:好的,所以我有一个空布局JPanel
,其中有一个JLabel
。 JLabel
位于 (0,0)。我要做的是在新的Thread
中使用while 循环来休眠新的Thread
,然后使用SwingUtilities.invokeLater
将JLabel
向下移动10px。问题是 UI 以一种滞后的方式更新。它不会每次都更新,但会跳过大量更新和大块转移。我知道我可以使用Timer
轻松做到这一点,但重点是更好地理解Threads
。提前致谢!
代码:
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);
编辑:
我通过在 updatePosition()
方法中调用一个新的 Thread 实例来替换 while 循环来让它工作,以便稍微解决问题。而且,导致问题的不仅仅是线程,所以我不得不通过调用revalidate()
来强制面板重新布局它的子视图。
这是它的外观(完整的工作):
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);
【问题讨论】:
"如何在不使用 Timer 的情况下实现平滑下降的 JLabel,但使用 Threads" 为什么“不使用计时器”?为什么不在自定义绘制的面板中执行此操作,而不是尝试动态定位组件? 定时器是基于线程的,所以我认为应该有办法做到这一点,这只是一个我不知道解决方案的问题,所以值得解决。你会建议我如何在自定义涂漆面板中进行操作? “您建议我如何在自定义的绘制面板中进行此操作?” 很像 this animation,但绘制的是字符串而不是形状。实际上(检查)使用BufferedImage
而不是自定义面板。但是一旦你有一个 Graphics
实例,它就是相同的主体。
非常感谢,我会调查的。但是,我只是不明白为什么 JLabel 不会在每次 updatePosition() 调用时更新......我觉得我错过了一些重要的东西......
旁注:最好将 try/catch 放在 while
循环周围,而不是在其中。如果其他代码向您的线程发送中断,则意味着您被要求停止正在执行的操作。将循环放在 try/catch 中是正确响应的最简单方法。
【参考方案1】:
您应该尝试使用可见性和 GridLayout 来最大化移动。您可以使用 int var 来计算线程并将其返回到标签。同样,您应该使用您的能力来创建更新程序,更多更顺畅。只需在拖钓线程时执行 start() mwthod :-)
除了无限调用之外,您还可以进行其他操作。我认为你已经失去了类本身的继承。对象label1
一定是在战斗中丢失了。如果不是这样,那么我很确定我真的无法回答这个问题。
【讨论】:
以上是关于如何在不使用 Timer 而是使用 Threads 的情况下实现平滑下降的 JLabel的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C# 中创建计时器而不使用 System.Timers.Timer 或 System.Threading.Timer
如何在不同步的情况下使用多个线程(2、4、8、16 个线程)循环打印字符串(10,100、1000 个循环)?
使用 Boost.Threads 的读写锁(如何转换这个简单的类)