在一些快速重复的操作事件调用后,JLabel文本无法正确显示 [英] JLabel text not being displayed correctly after some quickly repeated action event calls
本文介绍了在一些快速重复的操作事件调用后,JLabel文本无法正确显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在为我的Tic Tac Toe项目编写一个图形用户界面,我很享受下面这个小视觉效果的乐趣。每次用户设置CPU播放器并单击完成按钮而忘记设置CPU强度级别时,我都会像下面的代码示例一样显示一条小警告消息。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
public class TestingStuff implements ActionListener {
JLabel myLabel;
JFrame myFrame;
JButton myButton;
JPanel myPanel;
public TestingStuff() {
myFrame = new JFrame("Hello");
myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
myPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
myPanel.setBackground(Color.DARK_GRAY);
myFrame.add(myPanel, BorderLayout.CENTER);
myLabel = new JLabel("Hi dear stackoverflow coders!");
myLabel.setFont(new Font("MV Boli", Font.BOLD, 15));
myLabel.setForeground(Color.GREEN);
myPanel.add(myLabel);
myButton = new JButton("Click me like there's no tomorrow!");
myButton.addActionListener(this);
myFrame.add(myButton, BorderLayout.SOUTH);
myFrame.pack();
myFrame.setLocationRelativeTo(null);
myFrame.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
int timerDelay = 1;
Timer blinkTimer = new Timer(timerDelay, new ActionListener() {
private int count = 0;
private int maxTime = 30;
private String hello = myLabel.getText();
private int len = hello.length();
private String s;
public void actionPerformed(ActionEvent e) {
if (count * timerDelay >= maxTime) {
((Timer) e.getSource()).stop();
} else {
myLabel.setVisible(true);
if (count < len) {
s = hello.substring(0, count + 1);
myLabel.setText(s);
}
count++;
}
}
});
blinkTimer.start();
}
public static void main(String[] args) {
TestingStuff foo = new TestingStuff();
}
}
尝试重复单击该按钮。
至少在我的机器上。由于用户没有理由重复单击Done按钮,我并不太担心,但仍然...我想我最终会禁用用户在短小的动画过程中可以点击的每个按钮,以避免意外行为。 我的问题是:有人能解释一下发生了什么吗?为什么我能在7-8次快速点击后看到截短的文本?
推荐答案
更新之间的延迟设置为1
毫秒(幸运地获得了准确的😉),因此整个动画大约在30毫秒内完成。
相反,尝试将其设置为30毫秒(~1秒的运行时间)
我还想取消maxTime
的概念,您只想继续循环,直到获得所有文本,否则就有点没有意义(IMHO)
可能类似于...
int timerDelay = 30;
Timer blinkTimer = new Timer(timerDelay, new ActionListener() {
private int count = 0;
private String hello = myLabel.getText();
private String s;
public void actionPerformed(ActionEvent e) {
if (count >= hello.length()) {
System.out.println("Done");
((Timer) e.getSource()).stop();
} else {
System.out.println("Hello");
myLabel.setVisible(true);
s = hello.substring(0, count + 1);
myLabel.setText(s);
count++;
}
}
});
blinkTimer.start();
基于时间的动画
现在,如果您喜欢基于时间的动画,它可能如下所示。
设置为运行1秒,并将使用进度计算来确定应显示多少文本
Timer blinkTimer = new Timer(5, new ActionListener() {
private String title = myLabel.getText();
private Duration runtime = Duration.ofSeconds(1);
private Instant startTime;
public void actionPerformed(ActionEvent e) {
if (startTime == null) {
startTime = Instant.now();
}
Duration between = Duration.between(startTime, Instant.now());
double progress = between.toMillis() / (double)runtime.toMillis();
if (progress >= 1.0) {
((Timer) e.getSource()).stop();
// Just make sure the text is up-to-date
myLabel.setText(title);
} else {
int count = (int)(title.length() * progress);
String text = title.substring(0, count);
myLabel.setText(text);
}
}
});
blinkTimer.start();
&qot;顺便说一句,尝试使用您的代码并反复点击按钮:我仍然得到相同的结果&
您不断地创建新的Timer
,它们将相互完成。相反,可以禁用该按钮或停止当前运行的Timer
,例如...禁用按钮...
@Override
public void actionPerformed(ActionEvent e) {
myButton.setEnabled(false);
Timer blinkTimer = new Timer(5, new ActionListener() {
private String title = myLabel.getText();
private Duration runtime = Duration.ofSeconds(1);
private Instant startTime;
public void actionPerformed(ActionEvent e) {
if (startTime == null) {
startTime = Instant.now();
}
Duration between = Duration.between(startTime, Instant.now());
double progress = between.toMillis() / (double) runtime.toMillis();
if (progress >= 1.0) {
((Timer) e.getSource()).stop();
// Just make sure the text is up-to-date
myLabel.setText(title);
myButton.setEnabled(true);
} else {
int count = (int) (title.length() * progress);
String text = title.substring(0, count);
myLabel.setText(text);
}
}
});
blinkTimer.start();
}
取消活动计时器
private Timer blinkTimer;
@Override
public void actionPerformed(ActionEvent e) {
if (blinkTimer != null) {
blinkTimer.stop();
blinkTimer = null;
}
blinkTimer = new Timer(5, new ActionListener() {
private String title = myLabel.getText();
private Duration runtime = Duration.ofSeconds(1);
private Instant startTime;
public void actionPerformed(ActionEvent e) {
if (startTime == null) {
startTime = Instant.now();
}
Duration between = Duration.between(startTime, Instant.now());
double progress = between.toMillis() / (double) runtime.toMillis();
if (progress >= 1.0) {
((Timer) e.getSource()).stop();
// Just make sure the text is up-to-date
myLabel.setText(title);
myButton.setEnabled(true);
} else {
int count = (int) (title.length() * progress);
String text = title.substring(0, count);
myLabel.setText(text);
}
}
});
blinkTimer.start();
}
和...
哦🤦♂️-不要使用标签文本作为标签显示的初始文本-使用您可以控制的内容,否则您会将不完整的文本重新播种到动画中
private String greetingText = "Hi dear stackoverflow coders!";
private Timer blinkTimer;
@Override
public void actionPerformed(ActionEvent e) {
if (blinkTimer != null) {
blinkTimer.stop();
blinkTimer = null;
}
blinkTimer = new Timer(5, new ActionListener() {
private String title = greetingText;
private Duration runtime = Duration.ofSeconds(5);
private Instant startTime;
public void actionPerformed(ActionEvent e) {
if (startTime == null) {
startTime = Instant.now();
}
Duration between = Duration.between(startTime, Instant.now());
double progress = between.toMillis() / (double) runtime.toMillis();
System.out.println(hashCode() + " " + progress);
if (progress >= 1.0) {
((Timer) e.getSource()).stop();
// Just make sure the text is up-to-date
myLabel.setText(title);
myButton.setEnabled(true);
} else {
int count = (int) (title.length() * progress);
String text = title.substring(0, count);
myLabel.setText(text);
}
}
});
blinkTimer.start();
}
这篇关于在一些快速重复的操作事件调用后,JLabel文本无法正确显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文