JavaFX 将一个节点放在一个单独的 class 文件中
JavaFX Put a node in a separated class file
如何将名为“sellingPane”的 GridPane 放在单独的 class 文件中,但仍在此 class 中使用它?我希望能够更改场景中不同 GridPane 的 GridPane。我想了解如何将节点放在不同的 class 文件中并将它们放在一起以创建场景。
我试图将 sellingPane 放在不同的 class 中,并使用“return sellingPane”到 return,GridPane 到 MainWindowView.java,但我不知道如何制作按钮setOnAction 函数起作用。
一个小程序作为例子会很有帮助。
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import nl.inholland.cinemamarkkea.controllers.MovieController;
import nl.inholland.cinemamarkkea.models.Movie;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
public class MainWindowView extends HBox {
private ObservableList<Movie> room1Movies;
private ObservableList<Movie> room2Movies;
private Movie movie;
public MainWindowView(MovieController movieController){
Label title = new Label("Purchase tickets");
title.setFont(new Font("Arial", 24));
title.setTextFill(Color.web("#286DA3"));
room1Movies = movieController.getRoom1Movies();
room2Movies = movieController.getRoom2Movies();
//Tableview for the room1Movies
Label room1Label = new Label("Room 1");
room1Label.setFont(new Font("Arial", 12));
TableView<Movie> room1TableView = new TableView<>();
room1TableView.setMinWidth(450);
TableColumn<Movie, LocalDateTime> start1Column = new TableColumn<>("Start");
start1Column.setCellValueFactory(Movie -> {
SimpleObjectProperty startLabel= new SimpleObjectProperty();
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
startLabel.setValue(Movie.getValue().getStartDateTime().format(format));
return startLabel;
});
TableColumn<Movie, LocalDateTime> end1Column = new TableColumn<>("End");
end1Column.setCellValueFactory(Movie -> {
SimpleObjectProperty endLabel= new SimpleObjectProperty();
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
endLabel.setValue(Movie.getValue().getEndDateTime().format(format));
return endLabel;
});
TableColumn<Movie, String> title1Column = new TableColumn<>("Title");
title1Column.setCellValueFactory(new PropertyValueFactory<>("title"));
TableColumn<Movie, Integer> seats1Column = new TableColumn<>("Seats");
seats1Column.setCellValueFactory(new PropertyValueFactory<>("seats"));
TableColumn<Movie, Double> price1Column = new TableColumn<>("Price");
price1Column.setCellValueFactory(new PropertyValueFactory<>("price"));
room1TableView.getColumns().addAll(start1Column, end1Column, title1Column, seats1Column, price1Column);
room1TableView.setItems(room1Movies);
//Tableview for the room2Movies
Label room2Label = new Label("Room 2");
room2Label.setFont(new Font("Arial", 12));
TableView<Movie> room2TableView = new TableView<>();
room2TableView.setMinWidth(450);
TableColumn<Movie, LocalDateTime> start2Column = new TableColumn<>("Start");
start2Column.setCellValueFactory(Movie -> {
SimpleObjectProperty startLabel= new SimpleObjectProperty();
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
startLabel.setValue(Movie.getValue().getStartDateTime().format(format));
return startLabel;
});
TableColumn<Movie, LocalDateTime> end2Column = new TableColumn<>("End");
end2Column.setCellValueFactory(Movie -> {
SimpleObjectProperty endLabel= new SimpleObjectProperty();
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
endLabel.setValue(Movie.getValue().getEndDateTime().format(format));
return endLabel;
});
TableColumn<Movie, String> title2Column = new TableColumn<>("Title");
title2Column.setCellValueFactory(new PropertyValueFactory<>("title"));
TableColumn<Movie, Integer> seats2Column = new TableColumn<>("Seats");
seats2Column.setCellValueFactory(new PropertyValueFactory<>("seats"));
TableColumn<Movie, Double> price2Column = new TableColumn<>("Price");
price2Column.setCellValueFactory(new PropertyValueFactory<>("price"));
room2TableView.getColumns().addAll(start2Column, end2Column, title2Column, seats2Column, price2Column);
room2TableView.setItems(room2Movies);
Label roomLabel = new Label("Room");
Label roomNameLabel = new Label("");
Label movieLabel = new Label("Movie title");
Label movieNameLabel = new Label();
Label startLabel = new Label("Start");
Label startTimeLabel = new Label();
Label seatsLabel = new Label("No. of seats");
ComboBox<Integer> seatsBox = new ComboBox<Integer>();
seatsBox.getItems().add(0);
seatsBox.getItems().add(1);
seatsBox.getItems().add(2);
Button purchaseButton = new Button("Purchase");
Label endLabel = new Label("End");
Label endTimeLabel = new Label();
Label nameLabel = new Label("Name");
TextField nameInput = new TextField();
nameInput.setMaxWidth(150);
Button clearButton = new Button("Clear");
//selling tickets pane
GridPane sellingPane = new GridPane();
sellingPane.add(roomLabel, 0, 0, 1, 1);
sellingPane.add(roomNameLabel, 1, 0, 1, 1);
sellingPane.add(movieLabel, 2, 0, 1, 1);
sellingPane.add(movieNameLabel, 3, 0, 1, 1);
sellingPane.add(startLabel, 0, 1, 1, 1);
sellingPane.add(startTimeLabel, 1, 1, 1, 1);
sellingPane.add(seatsLabel, 2, 1, 1, 1);
sellingPane.add(seatsBox, 3, 1, 1, 1);
sellingPane.add(purchaseButton, 4, 1, 1, 1);
sellingPane.add(endLabel, 0, 2, 1, 1);
sellingPane.add(endTimeLabel, 1, 2, 1, 1);
sellingPane.add(nameLabel, 2, 2, 1, 1);
sellingPane.add(nameInput, 3, 2, 1, 1);
sellingPane.add(clearButton, 4,2,1,1);
//hide pane when no movie is selected
sellingPane.setVisible(false);
sellingPane.setVgap(10);
sellingPane.setHgap(40);
sellingPane.setStyle("-fx-padding: 10;" + "-fx-border-width: 2;");
room1TableView.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) ->{
movie = newSelection;
if (newSelection != null){
sellingPane.setVisible(true);
roomNameLabel.setText("Room 1");
movieNameLabel.setText(newSelection.getTitle());
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
startTimeLabel.setText(newSelection.getStartDateTime().format(format));
endTimeLabel.setText(newSelection.getEndDateTime().format(format));
}
});
room2TableView.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) ->{
movie = newSelection;
if (newSelection != null){
sellingPane.setVisible(true);
roomNameLabel.setText("Room 2");
movieNameLabel.setText(newSelection.getTitle());
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
startTimeLabel.setText(newSelection.getStartDateTime().format(format));
endTimeLabel.setText(newSelection.getEndDateTime().format(format));
}
});
Label errorLabel = new Label();
clearButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
//hide form
sellingPane.setVisible(false);
//clear combobox
seatsBox.valueProperty().set(null);
//clear name input field
nameInput.clear();
//clear error message
errorLabel.setText("");
//unselect row in table
room1TableView.getSelectionModel().select(null);
room2TableView.getSelectionModel().select(null);
//clear movie
movie = null;
}
});
purchaseButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
Integer selectedSeats = seatsBox.getValue();
String name = nameInput.getText();
if (selectedSeats == null || selectedSeats == 0){
errorLabel.setText("The minimum number of tickets you need to buy 1.");
} else if (name == null) {
errorLabel.setText("Please fill in your name.");
} else if (movie.getSeats() == 0) {
errorLabel.setText("There are no seats left for this movie, please try different room.");
} else {
//clear error message from possible previous attempt
errorLabel.setText("");
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setTitle("Confirm payment");
alert.setHeaderText("Please confirm payment");
alert.setContentText("Do you want to buy tickets for this movie?");
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK){
movieController.purchaseTicket(movie, selectedSeats, name, roomNameLabel.getText());
room1TableView.refresh();
room2TableView.refresh();
//clear and hide form
clearButton.fire();
}
}
}
});
VBox mainPane = new VBox();
//rooms together
HBox roomsPane = new HBox();
//rooms
VBox room1Pane = new VBox();
VBox room2Pane = new VBox();
roomsPane.setStyle("-fx-padding: 10;" +
"-fx-border-style: solid inside;" +
"-fx-border-width: 2;" +
"-fx-border-color: #8398AE;");
roomsPane.setSpacing(10);
room2Pane.getChildren().addAll(room2Label, room2TableView);
room1Pane.getChildren().addAll(room1Label, room1TableView);
roomsPane.getChildren().addAll(room1Pane, room2Pane);
mainPane.getChildren().addAll(title, roomsPane, sellingPane, errorLabel);
this.getChildren().addAll(mainPane);
}
}
您需要努力将视图与控制器分开。本质上,您需要处理模型视图控制器 (MVC)。您的控制器应该处理事件等。例如,这里不使用匿名 class
purchaseButton.setOnAction(new EventHandler<ActionEvent>() {
在您的控制器中创建一个方法class。
public class SellingPaneController{
Node sellingPane;
Button purchaseButton;
ComboBox<Integer> seatsBox;
public SellingPaneController(){
sellingPane = ...;
purchaseButton = ...;
purchaseButton.setOnAction(this::purchaseButtonAction);
}
public void purchaseButtonAction( ActionEvent actionEvent ){
//All of you local GUI classes here should be part of the grid view.
}
public Node getSellingPane(){ return sellingPane;}
}
当您创建控制器时,它将构建 GUI 元素并附加侦听器。
注意:这是 FXML 的优势,它会为您构建 gui 组件并附加监听器。您只需声明所有字段并编写事件处理程序。
这是一项相当大的工作量,因为您已将所有内容捆绑在一起。例如 room1Movies
是 MovieController 的一部分。您可能会做一些事情,例如让您的 SellingPaneController 构造函数将 MovieController 作为参数,然后它可以保留引用。
如何将名为“sellingPane”的 GridPane 放在单独的 class 文件中,但仍在此 class 中使用它?我希望能够更改场景中不同 GridPane 的 GridPane。我想了解如何将节点放在不同的 class 文件中并将它们放在一起以创建场景。 我试图将 sellingPane 放在不同的 class 中,并使用“return sellingPane”到 return,GridPane 到 MainWindowView.java,但我不知道如何制作按钮setOnAction 函数起作用。 一个小程序作为例子会很有帮助。
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import nl.inholland.cinemamarkkea.controllers.MovieController;
import nl.inholland.cinemamarkkea.models.Movie;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Optional;
public class MainWindowView extends HBox {
private ObservableList<Movie> room1Movies;
private ObservableList<Movie> room2Movies;
private Movie movie;
public MainWindowView(MovieController movieController){
Label title = new Label("Purchase tickets");
title.setFont(new Font("Arial", 24));
title.setTextFill(Color.web("#286DA3"));
room1Movies = movieController.getRoom1Movies();
room2Movies = movieController.getRoom2Movies();
//Tableview for the room1Movies
Label room1Label = new Label("Room 1");
room1Label.setFont(new Font("Arial", 12));
TableView<Movie> room1TableView = new TableView<>();
room1TableView.setMinWidth(450);
TableColumn<Movie, LocalDateTime> start1Column = new TableColumn<>("Start");
start1Column.setCellValueFactory(Movie -> {
SimpleObjectProperty startLabel= new SimpleObjectProperty();
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
startLabel.setValue(Movie.getValue().getStartDateTime().format(format));
return startLabel;
});
TableColumn<Movie, LocalDateTime> end1Column = new TableColumn<>("End");
end1Column.setCellValueFactory(Movie -> {
SimpleObjectProperty endLabel= new SimpleObjectProperty();
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
endLabel.setValue(Movie.getValue().getEndDateTime().format(format));
return endLabel;
});
TableColumn<Movie, String> title1Column = new TableColumn<>("Title");
title1Column.setCellValueFactory(new PropertyValueFactory<>("title"));
TableColumn<Movie, Integer> seats1Column = new TableColumn<>("Seats");
seats1Column.setCellValueFactory(new PropertyValueFactory<>("seats"));
TableColumn<Movie, Double> price1Column = new TableColumn<>("Price");
price1Column.setCellValueFactory(new PropertyValueFactory<>("price"));
room1TableView.getColumns().addAll(start1Column, end1Column, title1Column, seats1Column, price1Column);
room1TableView.setItems(room1Movies);
//Tableview for the room2Movies
Label room2Label = new Label("Room 2");
room2Label.setFont(new Font("Arial", 12));
TableView<Movie> room2TableView = new TableView<>();
room2TableView.setMinWidth(450);
TableColumn<Movie, LocalDateTime> start2Column = new TableColumn<>("Start");
start2Column.setCellValueFactory(Movie -> {
SimpleObjectProperty startLabel= new SimpleObjectProperty();
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
startLabel.setValue(Movie.getValue().getStartDateTime().format(format));
return startLabel;
});
TableColumn<Movie, LocalDateTime> end2Column = new TableColumn<>("End");
end2Column.setCellValueFactory(Movie -> {
SimpleObjectProperty endLabel= new SimpleObjectProperty();
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
endLabel.setValue(Movie.getValue().getEndDateTime().format(format));
return endLabel;
});
TableColumn<Movie, String> title2Column = new TableColumn<>("Title");
title2Column.setCellValueFactory(new PropertyValueFactory<>("title"));
TableColumn<Movie, Integer> seats2Column = new TableColumn<>("Seats");
seats2Column.setCellValueFactory(new PropertyValueFactory<>("seats"));
TableColumn<Movie, Double> price2Column = new TableColumn<>("Price");
price2Column.setCellValueFactory(new PropertyValueFactory<>("price"));
room2TableView.getColumns().addAll(start2Column, end2Column, title2Column, seats2Column, price2Column);
room2TableView.setItems(room2Movies);
Label roomLabel = new Label("Room");
Label roomNameLabel = new Label("");
Label movieLabel = new Label("Movie title");
Label movieNameLabel = new Label();
Label startLabel = new Label("Start");
Label startTimeLabel = new Label();
Label seatsLabel = new Label("No. of seats");
ComboBox<Integer> seatsBox = new ComboBox<Integer>();
seatsBox.getItems().add(0);
seatsBox.getItems().add(1);
seatsBox.getItems().add(2);
Button purchaseButton = new Button("Purchase");
Label endLabel = new Label("End");
Label endTimeLabel = new Label();
Label nameLabel = new Label("Name");
TextField nameInput = new TextField();
nameInput.setMaxWidth(150);
Button clearButton = new Button("Clear");
//selling tickets pane
GridPane sellingPane = new GridPane();
sellingPane.add(roomLabel, 0, 0, 1, 1);
sellingPane.add(roomNameLabel, 1, 0, 1, 1);
sellingPane.add(movieLabel, 2, 0, 1, 1);
sellingPane.add(movieNameLabel, 3, 0, 1, 1);
sellingPane.add(startLabel, 0, 1, 1, 1);
sellingPane.add(startTimeLabel, 1, 1, 1, 1);
sellingPane.add(seatsLabel, 2, 1, 1, 1);
sellingPane.add(seatsBox, 3, 1, 1, 1);
sellingPane.add(purchaseButton, 4, 1, 1, 1);
sellingPane.add(endLabel, 0, 2, 1, 1);
sellingPane.add(endTimeLabel, 1, 2, 1, 1);
sellingPane.add(nameLabel, 2, 2, 1, 1);
sellingPane.add(nameInput, 3, 2, 1, 1);
sellingPane.add(clearButton, 4,2,1,1);
//hide pane when no movie is selected
sellingPane.setVisible(false);
sellingPane.setVgap(10);
sellingPane.setHgap(40);
sellingPane.setStyle("-fx-padding: 10;" + "-fx-border-width: 2;");
room1TableView.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) ->{
movie = newSelection;
if (newSelection != null){
sellingPane.setVisible(true);
roomNameLabel.setText("Room 1");
movieNameLabel.setText(newSelection.getTitle());
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
startTimeLabel.setText(newSelection.getStartDateTime().format(format));
endTimeLabel.setText(newSelection.getEndDateTime().format(format));
}
});
room2TableView.getSelectionModel().selectedItemProperty().addListener((obs, oldSelection, newSelection) ->{
movie = newSelection;
if (newSelection != null){
sellingPane.setVisible(true);
roomNameLabel.setText("Room 2");
movieNameLabel.setText(newSelection.getTitle());
DateTimeFormatter format = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
startTimeLabel.setText(newSelection.getStartDateTime().format(format));
endTimeLabel.setText(newSelection.getEndDateTime().format(format));
}
});
Label errorLabel = new Label();
clearButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
//hide form
sellingPane.setVisible(false);
//clear combobox
seatsBox.valueProperty().set(null);
//clear name input field
nameInput.clear();
//clear error message
errorLabel.setText("");
//unselect row in table
room1TableView.getSelectionModel().select(null);
room2TableView.getSelectionModel().select(null);
//clear movie
movie = null;
}
});
purchaseButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent actionEvent) {
Integer selectedSeats = seatsBox.getValue();
String name = nameInput.getText();
if (selectedSeats == null || selectedSeats == 0){
errorLabel.setText("The minimum number of tickets you need to buy 1.");
} else if (name == null) {
errorLabel.setText("Please fill in your name.");
} else if (movie.getSeats() == 0) {
errorLabel.setText("There are no seats left for this movie, please try different room.");
} else {
//clear error message from possible previous attempt
errorLabel.setText("");
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setTitle("Confirm payment");
alert.setHeaderText("Please confirm payment");
alert.setContentText("Do you want to buy tickets for this movie?");
Optional<ButtonType> result = alert.showAndWait();
if (result.get() == ButtonType.OK){
movieController.purchaseTicket(movie, selectedSeats, name, roomNameLabel.getText());
room1TableView.refresh();
room2TableView.refresh();
//clear and hide form
clearButton.fire();
}
}
}
});
VBox mainPane = new VBox();
//rooms together
HBox roomsPane = new HBox();
//rooms
VBox room1Pane = new VBox();
VBox room2Pane = new VBox();
roomsPane.setStyle("-fx-padding: 10;" +
"-fx-border-style: solid inside;" +
"-fx-border-width: 2;" +
"-fx-border-color: #8398AE;");
roomsPane.setSpacing(10);
room2Pane.getChildren().addAll(room2Label, room2TableView);
room1Pane.getChildren().addAll(room1Label, room1TableView);
roomsPane.getChildren().addAll(room1Pane, room2Pane);
mainPane.getChildren().addAll(title, roomsPane, sellingPane, errorLabel);
this.getChildren().addAll(mainPane);
}
}
您需要努力将视图与控制器分开。本质上,您需要处理模型视图控制器 (MVC)。您的控制器应该处理事件等。例如,这里不使用匿名 class
purchaseButton.setOnAction(new EventHandler<ActionEvent>() {
在您的控制器中创建一个方法class。
public class SellingPaneController{
Node sellingPane;
Button purchaseButton;
ComboBox<Integer> seatsBox;
public SellingPaneController(){
sellingPane = ...;
purchaseButton = ...;
purchaseButton.setOnAction(this::purchaseButtonAction);
}
public void purchaseButtonAction( ActionEvent actionEvent ){
//All of you local GUI classes here should be part of the grid view.
}
public Node getSellingPane(){ return sellingPane;}
}
当您创建控制器时,它将构建 GUI 元素并附加侦听器。
注意:这是 FXML 的优势,它会为您构建 gui 组件并附加监听器。您只需声明所有字段并编写事件处理程序。
这是一项相当大的工作量,因为您已将所有内容捆绑在一起。例如 room1Movies
是 MovieController 的一部分。您可能会做一些事情,例如让您的 SellingPaneController 构造函数将 MovieController 作为参数,然后它可以保留引用。