所以这是我的问题。在JavaFX中,我创建了一个StackPane,并在其中添加了各种其他窗格。结果如下图所示。当我点击下面的按钮时,使用" toFront()"方法。我想在所有Panes上创建监听器,无论何时它们出现在前面都会触发。 我试过用
pane.sceneProperty().addListener((obs, oldValue, newValue) -> {});
但在我的情况下不起作用,因为窗格已经是StackPane的子窗口,因此已经在场景中。
我想在这里实现的是在窗格/节点实际渲染到场景时监听。据我所知,前窗格后面的堆栈窗格中的窗格不会被渲染。
此致 约翰尼拉
答案 0 :(得分:1)
据我了解,前窗格后面的堆栈窗格中的窗格不会被渲染。
这不是真的。堆栈窗格中的窗格以与子列表中的位置对应的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
&#39; s centerProperty
始终保持可见节点。还有很多其他方法可以做到这一点。