2016-03-22 1 views
-2

J'ai une méthode d'interface qui est censée renvoyer un objet Future.Comment utiliser FutureTask <V>, en attente de l'événement?

Future<Result> doSomething() 

La mise en œuvre de cette méthode montre un certain ui (javafx). Un des éléments ui a un écouteur, qui doit être appelé pour recevoir le résultat réel dont j'ai besoin.

Comment puis-je y parvenir? Y a-t-il une meilleure solution?

Voici un exemple d'action que je dois attendre:

// this is some framework method I cannot change 
@Override 
public Data execute(Data data) { 
    Future<Data> dataFuture = handler.doSomething(data); 
    // this should basically wait until the user clicked a button 
    return dataFuture.get(); 
} 

// handler implementation 
public Future<Data> doSomething(Data data) { 
    // the question is how to implement this part, to be able to 
    // return a future object 
    Button button = new Button("Wait until click"); 
    // create thread that waits for the button click ?!???? 
    // modify incoming data object when the button was clicked 
    // somehow create the Future object that's bound to the button click 
    return future; 
} 

C'est ce que je veux atteindre:

  1. ma méthode doSomething montre une nouvelle scène (ui) avec un bouton sur elle
  2. et retourne immedeately l'objet futur
  3. de Future.get() attend jusqu'à ce que l'utilisateur a appuyé sur le bouton

limitations: il doit être fait sans bibliothèque supplémentaire et> = java7

+0

Voir aussi http://stackoverflow.com/questions/13796595/return-result-from-javafx-platform-runlater –

+0

Où est-ce que cette méthode est appelée? (Le thread d'application FX ou un thread d'arrière-plan?) Pourquoi avez-vous besoin de faire les choses de cette façon (par exemple, pourquoi ne pas utiliser les mécanismes habituels pilotés par les événements pour "faire quelque chose quand on appuie sur un bouton")? Où le bouton va-t-il être montré? Dans un dialogue? Dans une étape existante? Vous devez probablement fournir * beaucoup * plus de détails, ou de préférence un exemple exécutable complet, pour clarifier ce que vous essayez de faire. –

Répondre

0

Utilisez un javafx.concurrent.Task. Il dérive de FutureTask. Il existe de nombreux exemples dans le javadoc lié sur l'utilisation des tâches.

Oracle fournit également un tutoriel qui traite de l'utilisation des tâches:

Je pense que c'est ce que vous voulez, mais je peux avoir compris la question, le cas échéant, s'il vous plaît modifier la question un peu pour clarifier les exigences (peut-être avec un mcve). Le peu qui me rend un peu incertain est la partie dans votre titre "en attente de l'événement de l'ui?", Je ne suis pas tout à fait sûr de ce que cela signifie dans ce contexte.

+0

J'espère que l'exemple est mieux maintenant. – andre

+0

Malheureusement, il est encore un peu difficile pour moi, il manque encore beaucoup de votre exemple. Les constructions de simultanéité telles que FutureTask n'ont de sens que si vous avez réellement un travail concurrent (l'application est multithread), mais votre exemple ne crée pas de threads. Je me demande donc si vous avez réellement besoin d'une FutureTask ou si vous essayez juste d'obtenir un callback asynchrone (que vous avez déjà dans le gestionnaire d'évènement de votre bouton). Si vous fournissez un programme complet que quelqu'un pourrait copier et coller, il sera peut-être plus facile à comprendre. – jewelsea

+0

mis à jour l'exemple avec un peu plus de code – andre

-1

C'est une solution que je cherchais. Ce n'est pas très agréable, puisque Thread.sleep ne me convainc pas.

mais maintenant vous propably une idée de ce que je veux réaliser

// make sure this is not called on the ui thread 
public Future<Data> doSomething(Data data) { 
    WaitingFuture future = new WaitingFuture(data); 
    Platform.runLater(() -> { 
       Button button = new Button("Wait until click"); 
       button.setOnAction(future); 
       // show button on ui... 
      }); 
    favouriteExecutorService.submit(future); 
    return future; 
} 

static class WaitingFuture extends Task<Data> implements EventHandler<ActionEvent> { 
    private Data data; 

    WaitingFuture(Data originalData) { 
     this.data = originalData; 
    } 

    private Data waitingData; 

    @Override 
    public void handle(ActionEvent event) { 
     waitingData = data.modify(); 
    } 

    @Override 
    protected Data call() throws Exception { 
     while (waitingData == null) { 
      Thread.sleep(100); 
     } 
     return waitingData; 
    } 
}