0

Would it be possible to wrap an entire JavaFX application into a while loop to trigger automatic events? For example in a auction house simulator:

package main;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {
// Standard JavaFX boilerplate
        primaryStage.show();
       while(true){
          // Get price of this item
          // Update table of listings

        }
}

public static void main(String[] args) {
    launch(args);
}

I know that the loop would block the main thread for the GUI so I was thinking of using the system time + a few seconds in the while loop instead:

double systemTime = systemTime;
double executeTime = systemTime + 5;
while(systemTime != executeTime){
//Do things
executeTime = systemTime + 5;
}

At any rate I know what I need, I just don't know what it's called or implemented.

Morteza Jalambadani
  • 2,190
  • 6
  • 21
  • 35
  • 2
    It's called *"The wrong way to approach the problem"* ;) Joking aside in most cases you'd simply react to changes done by the user to the GUI or information coming from a other source, e.g. a connection to a server. In case you really need to create a "loop", rewriting it as a periodic background task is the easiest way to handle this: https://stackoverflow.com/questions/9966136/javafx-periodic-background-task – fabian Feb 23 '19 at 09:54
  • Consider listening to the values and responding when they change (for example by using `SimpleDoubleproperty`). – c0der Feb 23 '19 at 12:12
  • @c0der I'm familiar with listeners, I need a way to change the values to begin with – Xhajk Jokjo Feb 23 '19 at 18:46
  • @fabian :) first part of your comments made me giggle. Second part is useful, 3rd part is extremely useful, thank you :) – Xhajk Jokjo Feb 23 '19 at 18:48

1 Answers1

0

Well you were right this would most likely block the JavaFX thread, but so would your second statement. As its still looping blocking the thread. What you could do is use the ScheduledExecutorService to run a Runnable or thread to periodically refresh the gui and update it with what ever information. But you should make sure to wrap the parts which change the GUI within the JavaFX Thread which you can simply do so by using Platform.runLater method. Or for more heavy duty background tasks, use the Task class for JavaFX.

I will use the runLater method for simplicity sakes.

Example:

import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.lang.management.PlatformManagedObject;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

public class Example extends Application {
private  Scene myscene;
private TextArea exampleText;
public static void main(String[] args) {
    launch(args);
}

@Override
public void start(Stage primaryStage) throws Exception {
    //JavaFX boilerplate
    VBox rootVBox =  new VBox();
    exampleText = new TextArea();
    VBox.setVgrow(exampleText, Priority.ALWAYS);
    myscene = new Scene(rootVBox);
    rootVBox.getChildren().add(exampleText);
    //End of JavaFX boilerplate

    // Scheduler to update gui periodically
    ScheduledExecutorService executor =
            Executors.newSingleThreadScheduledExecutor();

    Random r = new Random();


    Runnable addNewNumber = () -> {
        Platform.runLater(()->{
            System.out.println("I Just updated!!!");
            String newNumber = Integer.toString(r.nextInt(100));
            System.out.println("adding "+ newNumber +"  to textfield ");
        exampleText.appendText(newNumber+"\n");
        });
    };



    executor.scheduleAtFixedRate(addNewNumber, 0, 500, TimeUnit.MILLISECONDS);
    primaryStage.setScene(myscene);
    primaryStage.show();

}

}

Jesse_mw
  • 105
  • 2
  • 11