我一直在尝试使用带有scenebuilder的JavaFX创建一个计时器,但是我在创建线程时遇到了一些问题。每当我点击开始按钮时,应用程序都会滞后,从不真正更新文本。我一直试图使用public class SecondClass extends Activity {
EditText name,age;
TextView text_name,text_age;
String namer,ager;
private String savedName,savedAge;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity_layout);
name=(EditText) findViewById(R.id.name);
age=(EditText) findViewById(R.id.age);
text_name=(TextView) findViewById(R.id.name_edit);
text_age=(TextView) findViewById(R.id.name_age);
if (savedInstanceState!=null)
{
savedInstanceState.get(savedName);
name.setText(savedName);
savedInstanceState.get(savedAge);
age.setText(savedAge);
}
if (savedInstanceState==null)
{
Intent i=getIntent();
Bundle bundle=i.getExtras();
namer=bundle.getString("UName");
name.setText(namer);
ager=bundle.getString("UAge");
age.setText(ager);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(savedName,namer);
outState.putString(savedAge,ager);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState!=null)
{
savedInstanceState.get(savedName);
name.setText(savedName);
savedInstanceState.get(savedAge);
age.setText(savedAge);
}
if (savedInstanceState==null)
{
Intent i=getIntent();
Bundle bundle=i.getExtras();
namer=bundle.getString("UName");
name.setText(namer);
ager=bundle.getString("UAge");
age.setText(ager);
}
}
}
,但如上所述,一切都落后了,结果就是如此。
以下是控制计时器的方法,链接到FXML文件上的特定按钮:
Platform.runLater()
这是StopWatch.java类:
@FXML
private void startTimer(){
System.out.println("started");
stopWatch.startTimer();
}
@FXML
private void pauseTimer(){
stopWatch.pauseTimer();
}
@FXML
private void stopTimer(){
System.out.println("stopped");
stopWatch.stopTimer();
}
@FXML
public void updateTimer(long dT){
//System.out.println(((dT/6000)%1000)+":"+String.valueOf((dT/1000)%1000)+","+String.valueOf((dT)%1000));
Platform.runLater(() ->{
timer.setText(String.valueOf(dT/1000) );
});
}
感谢任何帮助。
答案 0 :(得分:0)
您不限制线程的更新频率。通过这种方式,您可以发布这么多Runable
的应用程序线程来执行,没有时间进行事件处理和布局,这使得您的应用程序以这种方式运行。
此外,您不会同步对布尔标志的访问,也不会使它们volatile
,这意味着值更改不一定对其他线程可见。
相反,您应该确保在最后Runnable
开始之前不再发布更新:
private final Object updaterLock = new Object();
private final boolean updating = false;
private final long value;
public void updateTimer(long dT) {
synchronized (updaterLock) {
value = dT;
if (!updating) {
updating = true;
Platform.runLater(() -> {
synchronized (updaterLock) {
updating = false;
timer.setText(Long.toString(value/1000));
}
});
}
}
}
public class StopWatch implements Runnable{
...
public volatile boolean running = false;
public volatile boolean paused = false;
但请考虑使用the AnimationTimer
class进行更新。此课程的更新频率有限。