Java JPanel的平滑运动,同时更新JLabel
如何为JPanel平滑移动并同时更新JLabel 我想在JFrame上显示当前时间,所以我创建了一个新的java.util.Timer,并每秒钟更新一次标签 我还创建了另一个Java线程来移动面板组件 但当移动面板并在框架上显示更新时间时,面板将刷新以形成原始位置 所以我在谷歌搜索这个问题,却找不到解决办法Java JPanel的平滑运动,同时更新JLabel,java,multithreading,swing,animation,Java,Multithreading,Swing,Animation,如何为JPanel平滑移动并同时更新JLabel 我想在JFrame上显示当前时间,所以我创建了一个新的java.util.Timer,并每秒钟更新一次标签 我还创建了另一个Java线程来移动面板组件 但当移动面板并在框架上显示更新时间时,面板将刷新以形成原始位置 所以我在谷歌搜索这个问题,却找不到解决办法 //Code to move jPanel smoothly Thread t = new Thread(){ int i = 0 ;
//Code to move jPanel smoothly
Thread t = new Thread(){
int i = 0 ;
public void run(){
while(i<150){
i++;
jPanel2.setLocation(i, jPanel2.getY());
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
}
}
}
};
t.start();
// Code to show Time
Timer t = new javax.swing.Timer(1, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
jLabel1.setText(new Date()+"");
}
});
t.start();
下面是一个小示例,介绍如何为组件提供动画和更新
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.WindowConstants;
/**
* <code>MovedClock</code>.
*/
public class MovedClock {
private final JLabel clock = new JLabel();
private final DateTimeFormatter format = DateTimeFormatter.ofPattern("HH:mm:ss");
private void startUI() {
JFrame frame = new JFrame("Moved clock");
frame.setLayout(null); // usually it's a bad idea, but for animation we need this.
clock.setBounds(0, 50, 50, 20);
frame.add(clock);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setSize(500, 200);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
updateClock();
Timer clockTimer = new Timer(1000, e -> updateClock());
clockTimer.start();
// 15 milliseconds for about 60fps
Timer moveTimer = new Timer(15, new ActionListener() {
private int count = 1;
private int increment = 1;
@Override
public void actionPerformed(ActionEvent e) {
if (count == 435 || count == 0) {
increment = -increment;
}
Point loc = clock.getLocation();
loc.x += increment;
clock.setLocation(loc);
count += increment;
}
});
moveTimer.start();
}
private void updateClock() {
clock.setText(LocalTime.now().format(format));
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new MovedClock()::startUI);
}
}
1切勿从其他线程更新Swing组件。始终使用javax.swing.Timer 2 1表示计时器为1毫秒,而不是1秒。3请提供一个小的可运行类,以便我们可以重现您的问题。因此,我需要更改线程而不是javax.swing.timer,以便顺利移动jPanel?您需要2个javax.swing.timer对象。一个用于更新时钟标签,另一个用于移动。在第二个计时器中,您还需要重新绘制已移动组件的父级。但它仍然无法正常工作:这是你的问题,而不是要求!请阅读由@SergiyMedvynskyy链接的页面,因为上面的不可编译代码段不是MCVE。但如何在jLabel到达末尾后停止actionPerform事件JFrame@JianShangQuan替换行increment=-increment;使用语句Timer e.getSource.stop;。在这种情况下,当标签位于行的末尾时,移动将停止。