package testing;
import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ToolBar;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import layout.PhysLayout;
import physics.Box2DSpringSimulation;
/**
* An abstract template for example applications. This class creates the basic
* prerequisites (layout and simulation) along with a GUI to start, stop and
* reset the simulation.
*
* @author Christoph Burschka <christoph@burschka.de>
*/
public abstract class Example extends Application {
public static final int WIDTH = 1024;
public static final int HEIGHT = 768;
private Box2DSpringSimulation simulation;
final PhysLayout layout;
Pane canvas;
BorderPane root;
ToolBar menu;
Stage primaryStage;
private final Button startStop, reset, step;
/**
* Super-constructor for all examples.
*/
public Example() {
root = new BorderPane();
menu = new ToolBar();
canvas = new Pane();
layout = new PhysLayout(canvas);
root.setCenter(canvas);
root.setTop(menu);
reset = new Button("Reset");
startStop = new Button("Start");
step = new Button("Step");
Button exit = new Button("Exit");
menu.getItems().addAll(startStop, step, reset, exit);
startStop.setMinWidth(startStop.getWidth() + 50);
exit.setOnAction((event) -> {
primaryStage.close();
});
setSimulation(new Box2DSpringSimulation(layout));
}
protected Box2DSpringSimulation getSimulation() {
return simulation;
}
/**
* Replace the example applications main simulator. The new simulator will
* be attached to the button controls.
*
* @param simulation
*/
protected final void setSimulation(Box2DSpringSimulation simulation) {
this.simulation = simulation;
simulation.getRunning().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> {
startStop.setText(newValue ? "Stop" : "Start");
});
startStop.setOnAction((ActionEvent event) -> {
if (simulation.isRunning()) {
simulation.stopSimulation();
} else {
simulation.startSimulation();
}
});
step.setOnAction((ActionEvent event) -> {
if (!simulation.isRunning()) {
simulation.updateModel();
simulation.step();
simulation.updateView();
}
});
step.disableProperty().bind(simulation.getRunning());
}
/**
* Sets up the application. This is called internally; the proper method to
* start the application is launch().
*
* @param primaryStage
*/
@Override
public final void start(Stage primaryStage) {
reset.setOnAction((ActionEvent event) -> {
simulation.stopSimulation();
reset();
});
reset();
this.primaryStage = primaryStage;
Scene scene = new Scene(root, WIDTH, HEIGHT);
primaryStage.setScene(scene);
primaryStage.setTitle(getTitle());
primaryStage.show();
}
/**
* Reset the simulation. This is called once during the setup, and whenever
* the reset button is pressed.
*/
public abstract void reset();
/**
* Get the window title.
*
* @return the string that the title will be set to.
*/
public abstract String getTitle();
}