Как сказал @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.