Reputation: 483
The following code allows to switch between two scenes.
import javafx.application.*;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.control.*;
public class EventHandlersExample extends Application {
Stage window;
Scene scene1, scene2;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
window = primaryStage;
//Button 1
Label label1 = new Label("Welcome to the first scene!");
Button button1 = new Button("Go to scene 2");
button1.setOnAction(e -> window.setScene(scene2));
//Textfield
TextField tf1 = new TextField();
//Layout 1 - children laid out in vertical column
VBox layout1 = new VBox(20);
layout1.getChildren().addAll(label1, button1);
scene1 = new Scene(layout1, 200, 200);
//Button 2
Button button2 = new Button("Go back to scene 1");
button2.setOnAction(e -> window.setScene(scene1));
//Layout 2
StackPane layout2 = new StackPane();
layout2.getChildren().add(button2);
scene2 = new Scene(layout2, 600, 300);
//Display scene 1 at first
window.setScene(scene1);
window.show();
}
}
However, I'd rather see my EventHandler in a separate class, like this:
import javafx.application.*;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.control.*;
public class EventHandlersExample extends Application {
Stage window;
Scene scene1, scene2;
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
window = primaryStage;
//Button 1
Label label1 = new Label("Welcome to the first scene!");
Button button1 = new Button("Go to scene 2");
//button1.setOnAction(e -> window.setScene(scene2));
Button1Handler button1handler = new Button1Handler();
button1.setOnAction(button1handler);
//Textfield
TextField tf1 = new TextField();
//Layout 1 - children laid out in vertical column
VBox layout1 = new VBox(20);
layout1.getChildren().addAll(label1, button1);
scene1 = new Scene(layout1, 200, 200);
//Button 2
Button button2 = new Button("Go back to scene 1");
button2.setOnAction(e -> window.setScene(scene1));
//Layout 2
StackPane layout2 = new StackPane();
layout2.getChildren().add(button2);
scene2 = new Scene(layout2, 600, 300);
//Display scene 1 at first
window.setScene(scene1);
window.show();
}
}
class Button1Handler implements EventHandler<ActionEvent> {
@Override
public void handle (ActionEvent e) {
System.out.println("OK button clicked");
window.setScene(scene2);
}
}
Yet, the reference to window in the EventHandlersExample
-Class does not work.
The same problem occurs (of course) when I try to textfield.getText()
from a textfield in the EventHandlersExample
-Class.
How can I fix this?---Help is greatly appreciated.
Upvotes: 0
Views: 1169
Reputation: 7956
If you're encapsulating the event-handling logic in a separate class, you need to somehow pass references of the parent window and the scene to the handler. A convenient way to do this is to inject the dependencies through the constructor:
class Button1Handler implements EventHandler<ActionEvent> {
private final Stage window;
private final Scene scene;
public Button1Handler (Stage window, Scene scene) {
this.window = window;
this.scene = scene;
}
@Override
public void handle (ActionEvent e) {
System.out.println("OK button clicked");
window.setScene(scene);
}
}
You'd then create the handler with new Button1Handler(window, scene2)
.
Upvotes: 1