2013-12-19 73 views
0

我有一个按钮可以激活与服务器的通信。每分钟都会从远程服务器获取一些数据。但是当我点击按钮时,即使使用时间轴,我的应用程序也会冻结几秒钟。JavaFX时间轴:按下按钮后,应用程序冻结一段时间

private Timeline timer; 

@Override 
public void handle(ActionEvent actionEvent) { 
    //Data initialization like read textfields' content 

    view.getConnectButton().setText("Reconnect"); 

    setCounters(); 

    if(timer != null) { 
     timer.stop(); 
    } 
    initTimer(); 
    timer.play(); 
} 

private void setCounters() { 
    String dataFromServer = model.getCybergameViwers(); //Retrieve data from server 
    //make something with received data 
} 

/** 
* Updates counters every 60 seconds 
*/ 
private void initTimer() { 
    timer = new Timeline(new KeyFrame(Duration.seconds(60), new EventHandler<ActionEvent>() { 
     @Override 
     public void handle(ActionEvent actionEvent) { 
      setCounters(); 
     } 
    })); 
    timer.setCycleCount(Animation.INDEFINITE); 
} 

据此,计时器在后台运行并每隔一分钟向服务器发送一次请求。但在第一次按下按钮后,应用程序会冻结。我怀疑setCounters()handle(),但没有它,字段初始化将发生在60秒。

如何修复第一个按钮按下应用程序冻结?

回答

0

您的服务器调用在您的JavaFX应用程序线程中不在后台线程中,它只是应用程序线程中的一个定期调用。

当调用setCounters()时,您的服务器正在处理请求,所以如果需要时间,它会锁定您的UI。

如果您想在后台线程中定期执行任务,并且可能在Application Thread中有回调,那么您应该查看随JavaFX 8提供的ScheduledService,如果您想继续使用JavaFX,可以在代码中执行它的实现2也是。

有一个问题,与你相似:Periodically refresh data

+0

在时间轴“来到现场”之前的一次发射不是太复杂吗? – Dragon

+0

@Dragon setCounters()如果您不想冻结UI,则不能从应用程序线程中调用setCounters()。要定义对您的服务器的第一个调用,而不是在您的FXML侦听器句柄()中调用它,可以使用服务中的任务来执行该任务,然后使用具有回调的ScheduleService进行定期更新。这是并发编程,是的,它有点复杂,但我没有看到一个简单的方法来实现这一点。 – zenbeni

+0

我认为最好在单独的线程中运行句柄。我发现我也连接到数据库,这也可能导致“冻结”。如果它运行在一个单独的线程中(并且定时器也在其中运行),我将摆脱冻结。 – Dragon

0

此等待响应来。使用单独的线程来调用这个函数,你不会面临这个问题

相关问题