首页 > 解决方案 > 堆栈窗格中的底部节点消失

问题描述

每个堆栈窗格都应该有两个节点。然而,对于堆栈窗格数组中的前 2 个索引,底部节点在 for 循环之外消失。

public class Main extends Application {
    GridPane images;
    StackPane[] stackPane;
    ImageView cardBack;
    ImageView[] cardImages;

    @Override
    public void start(Stage stage) throws FileNotFoundException {
        images = new GridPane(); images.setAlignment(Pos.CENTER);
        images.setVgap(5); images.setHgap(5);

        cardBack = new ImageView(new Image(new FileInputStream("images/b1fv.gif")));
        cardImages = new ImageView[]{
                new ImageView(new Image(new FileInputStream("images/c1.gif"))),
                new ImageView(new Image(new FileInputStream("images/c2.gif"))),
                new ImageView(new Image(new FileInputStream("images/c3.gif")))
        };

        final Button[] flip = new Button[cardImages.length];
        stackPane = new StackPane[cardImages.length];

        for (int i = 0; i < cardImages.length; i++) {
            stackPane[i] = new StackPane();
            stackPane[i].getChildren().addAll(cardBack, cardImages[i]);

            images.add(stackPane[i], i, 0, 1, 1);
            flip[i] = new Button("Flip");
            GridPane.setHalignment(flip[i], HPos.CENTER);
            images.add(flip[i], i, 1, 1, 1);

            // Debug
            System.out.println(stackPane[i].getChildren().toString());

            final int j = i;
            flip[j].setOnAction(event -> doFlip(j));
        }

        // Debug
        System.out.println("");
        for (StackPane pane : stackPane)
            System.out.println(pane.getChildren().toString());

        stage.setTitle("Assignment 11");
        stage.setScene(new Scene(images, 500,200));
        stage.show();
    }

    void doFlip(int loc) {
        // Debug
        System.out.println("");
        for (StackPane pane : stackPane)
            System.out.println(pane.getChildren().toString());

        ObservableList<Node> children = stackPane[loc].getChildren();
        Node topNode = children.get(children.size()-1);
        topNode.toBack();
    }

    public static void main(String[] args) {
        launch(args);
    }
}
[ImageView@5e1bc54a[styleClass=image-view], ImageView@25389181[styleClass=image-view]]
[ImageView@5e1bc54a[styleClass=image-view], ImageView@ff7cf97[styleClass=image-view]]
[ImageView@5e1bc54a[styleClass=image-view], ImageView@18b8669d[styleClass=image-view]]

[ImageView@25389181[styleClass=image-view]]
[ImageView@ff7cf97[styleClass=image-view]]
[ImageView@5e1bc54a[styleClass=image-view], ImageView@18b8669d[styleClass=image-view]]

[ImageView@25389181[styleClass=image-view]]
[ImageView@ff7cf97[styleClass=image-view]]
[ImageView@5e1bc54a[styleClass=image-view], ImageView@18b8669d[styleClass=image-view]]

在 for 循环内,它显示所有对象。但是,在循环之外,除了数组的最后一个元素之外,不显示底部节点。

标签: javajavafx

解决方案


您不能将同一个节点实例添加到多个父节点!

在循环的顶部,您有以下行:

stackPane[i].getChildren().addAll(cardBack, cardImages[i]);

cardBack节点将被添加到所有 StackPanes,但由于它只能有一个父节点,因此将从前一个中删除。Javafx 提供了一种重用图像资源的方法(我想这是您想要实现的目标)。您可以在构造函数ImageView中缓存Image实例传递,而不是创建一个。ImageView例如:

cardBack = new Image(new FileInputStream("images/b1fv.gif"));
// some stuff
for (int i = 0; i < cardImages.length; i++) {
    stackPane[i] = new StackPane();
    stackPane[i].getChildren().addAll(new ImageView(cardBack) , cardImages[i]);
    // rest of the loop
}

如果您使用ImageandImageView如上所述,事情将正常工作。


推荐阅读