为了账号安全,请及时绑定邮箱和手机立即绑定

包含 EventHandler 的循环没有按预期为 javafx 工作?

包含 EventHandler 的循环没有按预期为 javafx 工作?

catspeake 2022-07-27 20:39:26
我是 JavaFX 新手,在使用 setOnMouseClicked 方法时遇到问题。在下面的代码中,我尝试在嵌套循环中添加一个事件处理程序,以分配每个创建的矩形事件处理程序,单击鼠标,将矩形变为灰色。它似乎根本不起作用,我不知道为什么。我是否缺少需要添加的内容?public class Cinema extends Application {    @Override    public void start(Stage primaryStage) {        try {            Screen screen1 = new Screen(8, 14);            Pane root = FXMLLoader.load(getClass().getResource("Cinema.fxml"));            Scene scene = new Scene(root, 400, 400);            VBox seatHolder = new VBox(5);            seatHolder.setPrefWidth(root.getWidth());            seatHolder.setPrefHeight(root.getHeight());            seatHolder.prefWidthProperty().bind(root.widthProperty());            seatHolder.prefHeightProperty().bind(root.heightProperty());            seatHolder.setAlignment(Pos.CENTER);            for (int i = 0; i < screen1.getSeats().length; i++) {                HBox hbox = new HBox();                hbox.setSpacing(1);                hbox.setAlignment(Pos.CENTER);                for (int j = 0; j < screen1.getSeats()[i].length; j++) {                    Rectangle r = new Rectangle(30, 40);                    r.setOnMouseClicked(new EventHandler<MouseEvent>() {                        @Override                        public void handle(MouseEvent event) {                            r.setFill(Color.GREEN);                        }                    });                    hbox.getChildren().add(r);                    r.widthProperty().bind(root.heightProperty().divide(15));                    r.heightProperty().bind(root.widthProperty().divide(30));                    if (screen1.getSeats()[i][j] != null) {                        r.setFill(Color.RED);                    }                    else {                        r.setFill(Color.BLUE);                    }                }                seatHolder.getChildren().add(hbox);            }    }}
查看完整描述

2 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

问题是seatHolder窗格是在screenHolder窗格之前添加的。这导致screenHolder高于seatHolder。您可以通过添加 轻松看到这一点screenHolder.setStyle("-fx-background-color: #ffff00;");。在这种情况下,您的 EventHandler 永远不会被调用。您可以通过在处理程序方法中打印一些内容来检查这一点。


您可以通过更改将窗格添加到根窗格 ( root.getChildren().addAll(screenHolder, seatHolder);) 的顺序来解决此问题。第一个是最低的,最后一个是最高的。或者,您也可以更改布局。


我建议更改布局并使用BorderPane:


BorderPane root = new BorderPane();

Scene scene = new Scene(root, 400, 400);

VBox seatHolder = new VBox(5);

seatHolder.setAlignment(Pos.CENTER);


// setup seatHolder as before but use 


root.setCenter(seatHolder);


HBox screenHolder = new HBox();

Rectangle screen = new Rectangle(350, 25);

screen.widthProperty().bind(seatHolder.widthProperty());

screen.setFill(Color.LIGHTSLATEGREY);

screenHolder.getChildren().add(screen);

screenHolder.setAlignment(Pos.BOTTOM_CENTER);

root.setBottom(screenHolder);

primaryStage.setScene(scene);

primaryStage.show();

这应该适合你。在这种情况下,您甚至不需要 fxml 文件。


查看完整回答
反对 回复 2022-07-27
?
RISEBY

TA贡献1856条经验 获得超5个赞

我认为这可能r是绑定的值与在处理程序函数中使用它的时间的问题。


在您的 EventHandler 中,尝试以下操作


@Override

public void handle(MouseEvent event) {

  Rectangle clicked = (Rectangle) event.getSource();

  clicked.setFill(Color.GREEN);

}

而不是在处理程序中引用r。


编辑:看起来screenHolder覆盖了所有座位,因此您的点击永远不会注册。尝试设置screenHolder尺寸以匹配屏幕本身:


Rectangle screen = new Rectangle(350, 25);


screenHolder.setPrefWidth(screen.getWidth());

screenHolder.setPrefHeight(screen.getHeight());

screenHolder.prefWidthProperty().bind(screen.heightProperty());

screenHolder.prefHeightProperty().bind(screen.heightProperty());


查看完整回答
反对 回复 2022-07-27
  • 2 回答
  • 0 关注
  • 91 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信