簡體   English   中英

如何在StackPane(JavaFX)中將窗格放在最前面?

[英]How to listen when a pane comes to front in StackPane (JavaFX)?

所以這是我的問題。 在JavaFX中,我創建了一個StackPane,並在其中添加了其他各種窗格。 結果如下圖所示。 當我單擊下面的按鈕時,使用“ toFront()”方法將出現相應的窗格。 我想在所有窗格上創建偵聽器,這些偵聽器將在每次出現時觸發。 我嘗試使用

pane.sceneProperty().addListener((obs, oldValue, newValue) -> {});

但在我的情況下不起作用,因為窗格已經是StackPane的子級,因此已經在場景中了。

我要在此處實現的目標是在場景中實際渲染窗格/節點時進行監聽。 據我了解,前窗格后面的堆棧窗格中的窗格不會呈現。

問候,約翰尼

在此處輸入圖片說明

據我了解,前窗格后面的堆棧窗格中的窗格不會呈現。

這不是真的。 堆棧窗格中的窗格以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 然后BorderPanecenterProperty始終包含可見節點。 還有許多其他方法可以做到這一點。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM