-2

I have an interface method which is supposed to return a Future object.

Future<Result> doSomething()

The implementation of this method shows some ui (javafx). One of the ui elements has a listener, that needs to be called in order to receive the actual result, I need.

How do I achieve this? Is there a better solution?

Here an example action I need to wait for:

// 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;
}

This is what I want to achieve:

  1. my method doSomething shows a new scene(ui) with a button on it
  2. and returns immedeately the future object
  3. future.get() waits until the user pressed the button

limitations: it has to be done with no extra library and on >=Java7

andre
  • 1,618
  • 2
  • 19
  • 38
  • Also see http://stackoverflow.com/questions/13796595/return-result-from-javafx-platform-runlater – James_D Mar 22 '16 at 21:35
  • Where is this method being called from? (The FX Application Thread or a background thread?) Why do you need to do things this way (i.e. why not just use the usual event-driven mechanisms for "doing something when a button is pressed")? Where is the button going to be shown? In a dialog? In an existing stage? You probably need to provide *many* more details, or preferably a complete executable example, to clarify what you are try8ing to do. – James_D Mar 22 '16 at 22:29

2 Answers2

0

Use a javafx.concurrent.Task. It derives from FutureTask. There are extensive examples in the linked javadoc on Task usage.

Oracle also provide a tutorial which discusses Task usage:

I think this is what you want, but I may have understood the question, if so, please edit the question a bit to clarify requirements (perhaps with an mcve). The bit that makes me a little unsure is the part in your title "waiting for ui event?", I'm not quite sure what that means in this context.

Community
  • 1
  • 1
jewelsea
  • 150,031
  • 14
  • 366
  • 406
  • I hope the example is better now. – andre Mar 22 '16 at 21:46
  • Unfortunately it is still a bit unclear to me, there is a still a lot missing from your example. Concurrency constructs such as FutureTask only make sense when you actually have concurrent work occurring (the application is multi-threaded), but your example doesn't create any threads. So I'm left wondering if you really need a FutureTask at all or if you are just trying to get an async callback (which you already have in the action event handler for your button). If you supply a complete program somebody could copy and paste to run, it may be easier to understand. – jewelsea Mar 22 '16 at 21:56
-1

This is a solution I was searching for. It's not very nice, since the Thread.sleep doesn't convince me.

but now you propably get an idea of what I want to achieve

// 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;
    }
}
andre
  • 1,618
  • 2
  • 19
  • 38