CJpere
CJpere

Reputation: 1

How to automatically run a code from javafx new Scene

I am completely new to Java and I am learning it while developing an app for a school project.

Image Link

I want to code the above program. In it ,

  1. The user will click Ready button in screen 1.
  2. Then screen two will appear and an image of a butterfly will be shown in a order given by me[Preset using a CSV file] Like shown in screen 2 and 3.
  3. Finally, a button set will appear in the grid and user has to select the buttons in the order of the butterfly appearance.

I am stuck in finding a way to start screen 2 and automatically play the butterfly sequence.

I tried putting the image.setimage() on the initialize() block in my screen 2 controller with a delay in-between each setimage() . but it dosent work.

Anyone can suggest me a way to handle this kind of task? Thank a lot in advance.

Upvotes: 0

Views: 769

Answers (2)

fabian
fabian

Reputation: 82461

The issues often seen with this kind of code for beginners are doing sleep or some other long-running operation on the application thread to do some animation. However blocking the javafx application thread results in the scene not being updated resulting in a freeze of the gui.

You either need to move the long-running parts of this animation to a background thread and use Platform.runLater for any GUI updates or use something designed for this exact purpose. There are multiple classes that could be useful in the javafx.animation package, but the most convenient of them seems to be Timeline:

Store the sequence of movements in a suitable data structure and use the Timeline to trigger an event handler in regular intervals to update the gui:

List<FieldIndices> fieldIndices = ...
final Iterator<FieldIndices> iterator = fieldIndices.iterator();

final Timeline timeline = new Timeline();
timeline.getKeyFrames().add(new KeyFrame(Duration.seconds(1), evt -> {
    if (iterator.hasNext()) {
        moveButterfly(iterator.next());
    } else {
        removeButterfly();
        timeline.stop();
    }
}));
timeline.setCycleCount(Animation.INDEFINITE); // repeat until stop is called
timeline.play();

Now all that's left for you to implement is reading the data to a list and implementing the logic of moving the butterfly to a new position.

Note that I do not actually recommend using more than 2 scenes: The user will expect the same position for the buttons and the "fields" showing the butterfly. If you design 2 fxmls any adjustment to one of the scene would require you to do the same adjustments to the other scene. This makes the layout hard to maintain. The alternative requires you to create the scene in java code, but the repetitive nature of the scenes makes this a good idea anyways. (The alternative is injecting 16 fields to the controller and collecting them into a suitable data structure; This is error prone and any change of one of the buttons would probably require 16 changes in the fxml. Use a nested for loop and you need to write the logic for creating a button only once storing the buttons in e.g. a nested array can be done at the same time...)

Upvotes: 1

Iske
Iske

Reputation: 1200

As I understand, you wanna play butterfly sequence once 2nd stage is shown...To achieve that, you could try something like:

List positions = new ArrayList(); //places to show butterfly (e.g. table cells)
secondStage.setOnShown(windowEvent -> {
    // update UI with Pltform.runLater()
    // moveButerflyTo() is your method to place butterfly on given place
    positions.forEach(position -> Platform.runLater(() -> moveButerflyTo(position)));
});

I didn't try this but it do the job...

Upvotes: 0

Related Questions