Многоуровневые макеты JavaFX с тенями - PullRequest
0 голосов
/ 01 марта 2019

Я изучаю JavaFX и пытаюсь создать AnchorPane, который включает в себя еще 3 AnchorPane с.В настоящее время у меня есть проблема, когда тень панели скрыта из-за панели рядом с ней.Поэтому мне нужно несколько предложений о том, как решить эту проблему.

Я пытался создать расстояние между ними, но затем я вижу белый слой позади.Я пытался изменить z-порядок слоя, кажется, не работает, поэтому теперь после 2 часов не зная, что делать, я спрашиваю здесь.может кто знает.

Мой код:

    DropShadow dropShadow2;
    AnchorPane iconPane, menuPane, viewPane;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage){
        dropShadow2 = new DropShadow();
        dropShadow2.setOffsetX(6.0);
        dropShadow2.setOffsetY(4.0);

        //Main layout
        AnchorPane main_layout = new AnchorPane();

        //Icon layout (left)
        setUpIconLayout();

        //Menu layout (center)
        setUpMenuLayout();

        //View layout (right)
        setUpViewLayout();

        main_layout.getChildren().addAll(iconPane, menuPane, viewPane);

        Scene scene = new Scene(main_layout, 1000, 600);
        primaryStage.setTitle("Delivery System Database");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void setUpIconLayout() {

        iconPane = new AnchorPane();
        iconPane.setPrefSize(50,600);
        String hexColor_left = "D64550";
        iconPane.setStyle("-fx-background-color: #" + hexColor_left);
        iconPane.setEffect(dropShadow2);
    }

    private void setUpMenuLayout() {

        menuPane = new AnchorPane();
        menuPane.setPrefSize(200,600);
        String hexColor_mid = "EA9E8D";
        menuPane.setStyle("-fx-background-color: #" + hexColor_mid);
        menuPane.setEffect(dropShadow2);
        menuPane.setTranslateX(50);
    }

    private void setUpViewLayout() {
        viewPane = new AnchorPane();
        viewPane.setPrefSize(700,600);
        String hexColor_right = "DAEFB3";
        viewPane.setStyle("-fx-background-color: #" + hexColor_right);
        viewPane.setEffect(dropShadow2);
        viewPane.setTranslateX(250);
    }
}

Ответы [ 2 ]

0 голосов
/ 01 марта 2019

Как сказал @VGR, дочерние узлы отображаются в порядке их появления в дочерних узлах ObservableList.Это означает, что дети с более высоким индексом будут отображаться поверх детей с более низким индексом.Из-за этого тени покрываются другими узлами в вашем примере.Поскольку вы используете AnchorPane, который использует абсолютные позиции, установленные разработчиком, простое исправление заключается в изменении порядка следования дочернего списка (как показано VGR ).

ТоРешение не будет работать хорошо, если вы используете макет, который также позиционирует своих дочерних элементов в соответствии с порядком списка дочерних элементов, например HBox.Вы можете обойти эту проблему, установив соответствующие преобразования преобразования, но это не рекомендуется.Вместо этого вы можете установить свойство viewOrder - добавленное в JavaFX 9 - дочерних элементов.Это свойство:

Определяет порядок рендеринга и выбора этого Node в пределах его родителя.

Это свойство используется для изменения порядка рендеринга и выбора узла в пределах его родителя.без изменения порядка в списке родителей.Например, это можно использовать как более эффективный способ реализации прозрачной сортировки.Для этого приложение может присвоить значение viewOrder каждого узла вычисленному расстоянию между этим узлом и средством просмотра.

Родитель будет проходить через children в порядке убывания viewOrder.Это означает, что ребенок с более низким viewOrder будет перед ребенком с более высоким viewOrder.Если у двух детей одинаковый viewOrder, родитель будет проходить их в том порядке, в котором они указаны в списке children родителя.

Поскольку вы хотите, чтобы предыдущие дети отображались над последующими, вы можете просто установитьviewOrder к их индексу в списке children.Вот пример:

import java.util.stream.DoubleStream;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.effect.BlurType;
import javafx.scene.effect.DropShadow;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) {
        HBox root = new HBox(createRegions(50.0, 200.0, 700.0));
        root.setPadding(new Insets(0.0, 75.0, 0.0, 0.0));
        for (int i = 0; i < root.getChildren().size(); i++) {
            root.getChildren().get(i).setViewOrder(i);
        }
        primaryStage.setScene(new Scene(root));
        primaryStage.setTitle("ViewOrder Example");
        primaryStage.show();
    }

    private Region[] createRegions(double... prefWidths) {
        return DoubleStream.of(prefWidths).mapToObj(prefWidth -> {
            Region region = new Region();
            region.setMinSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
            region.setPrefSize(prefWidth, 600.0);
            region.setMaxSize(Region.USE_PREF_SIZE, Region.USE_PREF_SIZE);
            region.setEffect(new DropShadow(BlurType.THREE_PASS_BOX, Color.BLACK, 10.0, 0.0, 6.0, 4.0));
            region.setBackground(new Background(new BackgroundFill(Color.WHITE, null, null)));
            return region;
        }).toArray(Region[]::new);
    }

}

Вы упомянули одно из решений, которое вы пытались установить Z-Order для детей, но оно не работало.Чтобы установить координату z, необходимо включить буферизацию глубины при создании Scene.Вы можете проверить это, изменив приведенный выше пример:

  • Измените setViewOrder(i) на setTranslateZ(i).
  • Измените new Scene(root) на new Scene(root, -1.0, -1.0, true)

Преимущество работы в JavaFX 8.

0 голосов
/ 01 марта 2019

Дочерние узлы отображаются в порядке их добавления, поэтому должно быть достаточно добавить их в обратном порядке:

main_layout.getChildren().addAll(viewPane, menuPane, iconPane);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...