gpt4 book ai didi

java - 使用滚动 Pane javafX 时出现空指针异常

转载 作者:行者123 更新时间:2023-12-02 10:07:50 25 4
gpt4 key购买 nike

我一直在构建一个电影预订应用程序,并尝试创建一个显示电影和放映时间的场景。当我使用 anchor Pane 和 vbox 来显示所有信息时,它可以工作,但是当我尝试插入额外的滚动 Pane (在场景构建器中)时,FXML 加载器返回空指针异常,我无法弄清楚为什么......

这是我的 FXML 代码

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<AnchorPane prefHeight="598.0" prefWidth="798.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="MovieShowingsController">
<children>
<MenuBar>
<menus>
<Menu mnemonicParsing="false" text="myBookings">
<items>
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
</menus>
</MenuBar>
<ScrollPane fx:id="scrollpane" hbarPolicy="NEVER" layoutY="22.0" prefHeight="576.0" prefWidth="798.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="22.0">
<content>
<VBox fx:id="vbox" prefHeight="555.0" prefWidth="740.0" />
</content>
</ScrollPane>
</children>
</AnchorPane>

这是 Controller 类

public class MovieShowingsController {

@FXML
private VBox vbox;

private ArrayList<FilmInfo> filmList;

private ArrayList<Screening> screeningList;

private MovieShowings showings;

//FXML loader instance variable to be accessed by dynamic scene controller
private VBox holder;

@FXML
private void initialize() {
}

public MovieShowingsController() {

}

public MovieShowingsController(MovieShowings showings) {

String date = "2019-04-15";
Date sqlDate = Date.valueOf(date);

System.out.println("\n");
System.out.println("***Screenings for " + date + "***");

filmList = new ArrayList();
screeningList = DatabaseConnection.getInstance().retrieveScreeningsForDay(sqlDate);

for (Screening screeningInstance : screeningList) {

if (!filmList.contains(screeningInstance.getFilmInfo())) {

filmList.add(screeningInstance.getFilmInfo());

}

System.out.println(screeningInstance.toString());
}

Collections.sort(screeningList);

this.showings = showings;

//populating FXML instance variable from loader
this.holder = (VBox) showings.getRoot().lookup("#vbox");

buildMovieShowings(holder);
}

private void buildMovieShowings(VBox holder) {

holder.setSpacing(50);

for (int i = 0; i < filmList.size(); i++) {

VBox infoHolder = new VBox();

infoHolder.setSpacing(10);

Label title = new Label(String.format("%s%8s", filmList.get(i).getTitle(),
"(" + filmList.get(i).getRating() + ")"));

title.setStyle("-fx-font: 24 arial;");

Label duration = new Label(String.format("%s%s%s", "Film Length: ",
filmList.get(i).getDuration(), " mins"));

duration.setStyle("-fx-font: 24 arial;");

Label director = new Label(String.format("%s%s", "Directed By: ",
filmList.get(i).getDirector()));

director.setStyle("-fx-font: 24 arial;");

infoHolder.getChildren().addAll(title, duration, director);

HBox timesHolder = new HBox();

timesHolder.setSpacing(10);

for (int j = 0; j < screeningList.size(); j++) {

if (screeningList.get(j).getFilmInfo().equals(filmList.get(i))){

Label time = new Label();

Background black = new Background(new BackgroundFill(Color.BLACK, CornerRadii.EMPTY, Insets.EMPTY));

Background red = new Background(new BackgroundFill(Color.RED, CornerRadii.EMPTY, Insets.EMPTY));

time.setBackground(black);

Screen screen = screeningList.get(j).getScreen();
Screening screening = screeningList.get(j);

time.setOnMouseClicked(new EventHandler<MouseEvent>() {

@Override
public void handle(MouseEvent e) {

try {

System.out.println(screening.getFilmInfo().getTitle() + screening.getShowTime());

time.setBackground(red);

SeatMap seatMap = new SeatMap();

SeatMapController seatMapController = new SeatMapController(seatMap,
screen);

Scene seatMapScene = seatMap.getScene();

Stage window = (Stage) ((Node) e.getSource()).getScene().getWindow();

window.setResizable(false);

window.setWidth(800);
window.setHeight(600);

window.setScene(seatMapScene);

window.show();

}

catch (IOException ex) {

ex.printStackTrace();

}

}

});

time.setPrefSize(100, 100);

time.setAlignment(Pos.CENTER);

time.setStyle("-fx-border-color: black");

time.setStyle("-fx-font: 22 arial;");

time.setStyle("-fx-text-fill: white");

time.setText(screeningList.get(j).getShowTime());

timesHolder.getChildren().add(time);
}
}

infoHolder.getChildren().add(timesHolder);

holder.getChildren().add(infoHolder);
}
}
}

主类

public class MovieShowings{

private AnchorPane root;

public MovieShowings() {

try {

root = FXMLLoader.load(getClass().getResource("movieshowings.fxml"));
}

catch(IOException e){

e.printStackTrace();
}

}


public Scene getScene() {

Scene scene = new Scene(root,800,600);

return scene;

}

public AnchorPane getRoot() {

return root;
}

}

以及用户登录后调用它的代码

if(DatabaseConnection.getInstance().login(Username.getText(), Password.getText())) {

MovieShowings films = new MovieShowings();

MovieShowingsController filmsController = new MovieShowingsController(films);

Scene movieShowings = films.getScene();

Stage window = (Stage) ((Node) e.getSource()).getScene().getWindow();

window.setScene(movieShowings);

window.show();

关于如何解决这个问题有什么想法吗?

编辑:即使 fx:id 'vbox' 已被注入(inject)到 FXML 加载器中,也不会从 getRoot() 方法访问它

最佳答案

这样做的原因是ScrollPane添加内容,ScrollBar等。创建皮肤时的第一个布局过程中的场景。此布局传递发生在 JavaFX 应用程序线程“重新获得控制”之后(即您已完成事件处理程序、Application.start 方法或让 JavaFX 执行代码的类似方式)。

请注意,您正在以一种非常奇怪的方式使用 Controller 类。我建议使用此问题的答案中描述的方法之一与 Controller 进行通信:Passing Parameters JavaFX FXML

例如:

public class MovieShowings{

private AnchorPane root;

public MovieShowings() {

try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("movieshowings.fxml"));
root = loader.load();
MovieShowingsController controller = loader.getController();
controller.initMovieShowings(this);
}

catch(IOException e){

e.printStackTrace();
}

}
...

}
public class MovieShowingsController {

...

public void initMovieShowings(MovieShowings showings) {
String date = "2019-04-15";
Date sqlDate = Date.valueOf(date);

System.out.println("\n");
System.out.println("***Screenings for " + date + "***");

filmList = new ArrayList();
screeningList = DatabaseConnection.getInstance().retrieveScreeningsForDay(sqlDate);

for (Screening screeningInstance : screeningList) {

if (!filmList.contains(screeningInstance.getFilmInfo())) {

filmList.add(screeningInstance.getFilmInfo());

}

System.out.println(screeningInstance.toString());
}

Collections.sort(screeningList);

this.showings = showings;

//populating FXML instance variable from loader

// use the injected field here
buildMovieShowings(vbox);
}

...
}
<小时/>

因为您实际上并未使用 MovieShowings Controller 中的对象,可以通过从 a 进行初始化来稍微简化代码

@FXML
private void initialize()

Controller 中的方法并删除每个 MovieShowings Controller 代码中的相关部分。这样您就无需将其传递给 Controller ​​。

使用 ListView使用自定义单元格也可以是显示电影的选项...

关于java - 使用滚动 Pane javafX 时出现空指针异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55210545/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com