据我了解,堆栈窗格中位于前窗格后面的窗格未呈现。
这并不完全正确。堆栈窗格中的窗格以与其在子列表中的位置相对应的 z 顺序呈现;换句话说,它们在另一个之上呈现,列表中的第一个元素位于堆栈的底部,最后一个元素位于顶部。如果它们都是不透明的并且都填满了整个堆栈窗格,那么只有最后一个对用户可见。
您可以将跟踪堆栈窗格列表中最后一项的绑定(即位于前面的节点)与
放在一起
ObjectBinding<Node> frontLayer = Bindings.valueAt(stack.getChildren(),
Bindings.size(stack.getChildren()).subtract(1));
SSCCE:
import java.util.Random;
import java.util.stream.IntStream;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.ObjectBinding;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class StackPaneReorderTest extends Application {
private final Random rng = new Random();
@Override
public void start(Stage primaryStage) {
StackPane stack = new StackPane();
IntStream.rangeClosed(1, 10).mapToObj(this::createPane).forEach(stack.getChildren()::add);
Button button = new Button("Change");
button.setOnAction(e ->
stack.getChildren().get(rng.nextInt(stack.getChildren().size() - 1)).toFront());
BorderPane root = new BorderPane(stack, null, null, button, null);
BorderPane.setAlignment(button, Pos.CENTER);
BorderPane.setMargin(button, new Insets(10));
ObjectBinding<Node> frontLayer = Bindings.valueAt(stack.getChildren(),
Bindings.size(stack.getChildren()).subtract(1));
frontLayer.addListener((obs, oldLayer, newLayer) ->
System.out.println(newLayer.getId() + " moved to front"));
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
private Pane createPane(int i) {
Pane pane = new StackPane();
pane.setId("Layer "+i);
pane.setStyle(String.format("-fx-background-color: -fx-background; -fx-background: #%x%x%x;",
rng.nextInt(16), rng.nextInt(16), rng.nextInt(16)));
pane.getChildren().add(new Label("Layer "+i));
return pane ;
}
public static void main(String[] args) {
launch(args);
}
}
请注意,对于您的特定用例,您正在尝试做的事情可能会有更好的解决方案。例如。您可以使用BorderPane 并使用您要显示的节点调用setCenter。然后BorderPane 的centerProperty 总是持有可见节点。还有很多其他方法可以做到这一点。