2015-04-20 2 views
0

У меня есть приложение JavaFX, которое использует веб-службы через API-интерфейс Jersey Client, каждый раз, когда часть приложения (экранов) блокируется при выполнении вызова веб-службы.JavaFX UI зависает при вызове веб-службы

Нет темы, которую я использовал для совершения вызовов веб-службы.

Ниже приводится Джерси Клиент Код:

import com.sun.jersey.api.client.Client; 
import com.sun.jersey.api.client.ClientResponse; 
import com.sun.jersey.api.client.WebResource; 
import com.sun.jersey.api.client.config.ClientConfig; 
import com.sun.jersey.api.client.config.DefaultClientConfig; 
import com.sun.jersey.api.json.JSONConfiguration; 
    public class WSClient{ 
     WebResource webResource; 
     ClientResponse response; 

     protected Client getWSClient() { 

      ClientConfig clientConfig = new DefaultClientConfig(); 

      clientConfig.getFeatures().put(
        JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE); 

      Client wsClient = Client.create(clientConfig); 
      return wsClient; 
     } 

     public ArrayList<String> getNames(){ 
      ArrayList<String> names= new ArrayList<>(); 

      try{ 
       webResource = getWSClient().resource("http://localhost:8080/names"); 
       response = webResource.type("application/json").accept("application/json").get(ClientResponse.class); 

      }catch(Exception ex){ 
       log.error("Failed : " + ex.getMessage()); 
       return null; 
      } 
      if(response.getStatus() != 200){ 
       return null; 
      } 
      String output = response.getEntity(String.class); 
      names= getGson().fromJson(output, 
        new TypeToken<ArrayList<String>>() { 
        }.getType()); 



      return names; 
     } 
    } 

Ниже приводится JavaFX класс контроллера:

private ComboBox<String> cmbNames = new ComboBox<>(); 

cmbNames.setItems(FXCollections.observableList(new WSClient().getNames())); 

ваша помощь очень ценится!

+0

Конечно, он замерзает, он выполняет работу в потоке графического интерфейса. – meskobalazs

+0

Это означает, что мне нужно написать поток, который выполняет каждый вызов веб-службы? –

+0

Вы можете использовать 'javafx.concurrent.Task'. Вы действительно не должны писать свои собственные потоки, использовать то, что JavaFX предоставляет вам. – meskobalazs

ответ

2

Получение данных с сервера является, по крайней мере, потенциально возможным, долговременной. Вы не должны выполнять такие операции в потоке приложения FX, так как пользовательский интерфейс будет не отвечать на запросы во время работы.

Создать Task для выполнения операции, и выполнить его в фоновом потоке:

Task<List<String>> getNamesTask = new Task<List<String>>() { 
    @Override 
    public List<String> call() { 
     return new WSClient().getNames(); 
    } 
}; 

getNamesTask.setOnSucceeded(e -> 
    cmbNames.getItems().setAll(getNamesTask.getValue())); 

Для выполнения этой задачи в фоновом потоке, вы можете сделать это «вручную»:

Thread thread = new Thread(getNamesTask); 
thread.setDaemon(true); 
thread.start(); 

Или (лучше), использовать Executor, который будет управлять пул потоков для вас:

// declared at class level: 
private final Executor exec = Executors.newCachedThreadPool(runnable -> { 
    Thread t = new Thread(runnable); 
    t.setDaemon(true); 
    return t ; 
}); 

// ... 

exec.execute(getNamesTask); 

Дополнительные стратегии по интеграции взаимодействия клиент-сервер с JavaFX см. На странице Adam Bien's excellent article.

+0

Интересно, что вы определили 'onSucceeded' как лямбда, но задача как внутренний класс, почему бы и нет, как лямбда? – Vogel612

+1

Вы не можете, потому что 'Задача' не является интерфейсом. (Было бы неплохо, если бы «Задача» определила удобный заводский метод с использованием «Callable», что-то вроде «public static Task ofCallable (Callable callable)», что позволило бы «Задача t = Task.ofCallable (() - > ...); '.) –

+0

вы действительно должны иметь возможность, потому что задача имеет только один абстрактный метод и, следовательно, подчиняется контракту' @ FunctionalInterface'. ты пробовал? – Vogel612

Смежные вопросы