Тени в панели без отделки! В JavaFX

Whats вверх?

Ну, я пытаюсь сделать свою панель немного лучше, визуально, поэтому, что я делаю: установите мою сцену UNDECORATED (OK) и (пытается) добавить эффект тени (не ОК).

Я искал (много) таких вопросов через Интернет, нашел несколько похожих случаев (создание недекорированного этапа в javafx 2.0 и Как добавить тень в окно в JavaFX?) но ни то, ни другое не работает для меня.

кажется, что падение тень просто не устанавливается! Не могу понять, почему.

смотрите, что я получил:

public static int showConfirmDialog(Window father, String title, String body, String[]      msgBtn) 
{
    System.out.println("La vai eu");
    AnchorPane ap = createPaneWithButton(2, msgBtn,body);

    ap.setEffect(initDropShadow());
    Scene scene = new Scene(ap);

    Stage stage = new Stage();

    stage.setTitle(title);

    scene.setFill(null);
    stage.initStyle(StageStyle.TRANSPARENT);


    stage.setScene(scene);
    stage.initStyle(StageStyle.UNDECORATED);
    stage.show();

    return 1;
}

private static AnchorPane createPaneWithButton(int qtBtn, String[] msgsBtn, String body) {
    AnchorPane ap = createPane();
    HBox laneBtn = new HBox(30);
    VBox vbox = new VBox(20);

    BorderPane layout = new BorderPane();

    Button btn;

    for(int i = 0; i < qtBtn; i++ ){
        btn = new Button();
        btn.setText(msgsBtn[i]);

        laneBtn.getChildren().add(btn);
    }

    vbox.getChildren().add(new Text(body));
    vbox.getChildren().add(laneBtn);

    layout.setCenter(vbox);

    ap.getChildren().add(layout);

    return ap;
}

private static AnchorPane createPane() {
    AnchorPane ap = new AnchorPane();

    ap.setLayoutX(250);
    ap.setLayoutY(50);

    return ap;
}

Спасибо, ребята! Я с нетерпением жду ответа! (В то время как я буду продолжать пытаться, что могу).

PS:. Srry для английского, это не мой основной язык. Надеюсь, вы понимаете.

3 ответов


предыдущий пример работает для меня

на код поставляется для ответа на Как добавить тень в окно в JavaFX? отлично работает для меня (тень в диалоговом окне видна) на Java 8b96, Windows 7. Когда я написал его для JavaFX 2, он также работал в этой среде.

Я не мог точно сказать, что вам не хватает в вашем примере, поскольку вы не предоставили полный исполняемый файл код.

transparent-dialog

возможная проблема с вашим кодом

Я предполагаю, что вы не вставляете фоновое содержимое, чтобы в диалоговом окне было пространство для отображения тени. То есть вы заполняете диалоговое окно содержимым и не оставляете места в диалоговом окне вокруг содержимого для отображения эффекта. Пример ниже достигает insetting с правило CSS -fx-background-insets: 12;

Обновленный Образец Код

Я скопировал измененную версию кода примера в этот ответ, чтобы он не просто содержался в неясной ссылке gist от другого ответа. Изменения должны просто использовать стандартные вызовы API, поскольку построители, используемые в исходном ответе, устарели с момента создания исходного ответа.

ModalConfirmExample.java

import javafx.application.Application;
import javafx.beans.value.*;
import javafx.concurrent.Worker;
import javafx.event.*;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.effect.BoxBlur;
import javafx.scene.effect.Effect;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.web.WebView;
import javafx.stage.Modality;
import javafx.stage.*;

/**
 * Application modal dialog with the following properties:
 *   translucent background
 *   drop-shadowed border
 *   non-rectangular shape
 *   blur effect applied to parent when dialog is showing
 *   configurable message text
 *   configurable yes and no event handlers
 */
class ModalDialog extends Stage {
    private static final Effect parentEffect = new BoxBlur();

    private final String messageText;
    private final EventHandler<ActionEvent> yesEventHandler;
    private final EventHandler<ActionEvent> noEventHandler;

    public ModalDialog(
            Stage parent,
            String messageText,
            EventHandler<ActionEvent> yesEventHandler,
            EventHandler<ActionEvent> noEventHandler) {
        super(StageStyle.TRANSPARENT);

        this.messageText = messageText;
        this.yesEventHandler = yesEventHandler;
        this.noEventHandler = noEventHandler;

        // initialize the dialog
        initOwner(parent);
        initParentEffects(parent);
        initModality(Modality.APPLICATION_MODAL);
        setScene(createScene(createLayout()));
    }

    private StackPane createLayout() {
        StackPane layout = new StackPane();
        layout.getChildren().setAll(
                createGlassPane(),
                createContentPane()
        );

        return layout;
    }

    private Pane createGlassPane() {
        final Pane glassPane = new Pane();
        glassPane.getStyleClass().add(
                "modal-dialog-glass"
        );

        return glassPane;
    }

    private Pane createContentPane() {
        final HBox contentPane = new HBox();
        contentPane.getStyleClass().add(
                "modal-dialog-content"
        );
        contentPane.getChildren().setAll(
                new Label(messageText),
                createYesButton(),
                createNoButton()
        );

        return contentPane;
    }

    private Button createYesButton() {
        final Button yesButton = new Button("Yes");
        yesButton.setDefaultButton(true);
        yesButton.setOnAction(yesEventHandler);

        return yesButton;
    }

    private Button createNoButton() {
        final Button noButton = new Button("No");
        noButton.setOnAction(noEventHandler);

        return noButton;
    }

    private Scene createScene(StackPane layout) {
        Scene scene = new Scene(layout, Color.TRANSPARENT);
        scene.getStylesheets().add(
                getClass().getResource(
                        "modal-dialog.css"
                ).toExternalForm()
        );

        return scene;
    }

    private void initParentEffects(final Stage parent) {
        this.showingProperty().addListener(new ChangeListener<Boolean>() {
            @Override public void changed(ObservableValue<? extends Boolean> observableValue, Boolean wasShowing, Boolean isShowing) {
                parent.getScene().getRoot().setEffect(
                        isShowing ? parentEffect : null
                );
            }
        });
    }
}

/**
 * Demonstrates a modal confirm box in JavaFX.
 * Dialog is rendered upon a blurred background.
 * Dialog is translucent.
 */
public class ModalConfirmExample extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(final Stage primaryStage) {
        final WebView webView = new WebView();

        final ModalDialog dialog = createWebViewPreferenceDialog(primaryStage, webView);

        // show the preference dialog each time a new page is loaded.
        webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
            @Override
            public void changed(ObservableValue<? extends Worker.State> observableValue, Worker.State state, Worker.State newState) {
                if (newState.equals(Worker.State.SUCCEEDED)) {
                    dialog.show();
                    dialog.toFront();
                }
            }
        });
        webView.getEngine().load("http://docs.oracle.com/javafx/");

        // initialize the stage
        primaryStage.setTitle("Modal Confirm Example");
        primaryStage.setScene(new Scene(webView));
        primaryStage.show();
    }

    private ModalDialog createWebViewPreferenceDialog(final Stage primaryStage, final WebView webView) {
        final EventHandler<ActionEvent> yesEventHandler =
                new EventHandler<ActionEvent>() {
                    @Override public void handle(ActionEvent actionEvent) {
                        System.out.println("Liked: " + webView.getEngine().getTitle());
                        primaryStage.getScene().getRoot().setEffect(null);
                        Stage dialogStage = getTargetStage(actionEvent);
                        dialogStage.close();
                    }
                };

        final EventHandler<ActionEvent> noEventHandler =
                new EventHandler<ActionEvent>() {
                    @Override public void handle(ActionEvent actionEvent) {
                        System.out.println("Disliked: " + webView.getEngine().getTitle());
                        primaryStage.getScene().getRoot().setEffect(null);
                        Stage dialogStage = getTargetStage(actionEvent);
                        dialogStage.close();
                    }
                };

        return new ModalDialog(primaryStage, "Will you like this Page?", yesEventHandler, noEventHandler);
    }

    private Stage getTargetStage(ActionEvent actionEvent) {
        Node target = (Node) actionEvent.getTarget();
        return ((Stage) target.getScene().getWindow());
    }
}

модальный диалог.в CSS

.root {
  -fx-opacity: 0.9;
}

.modal-dialog-glass {
  -fx-effect: dropshadow(three-pass-box, derive(cadetblue, -20%), 10, 0, 4, 4); 
  -fx-background-color: derive(cadetblue, -20%); 
  -fx-background-insets: 12; 
  -fx-background-radius: 6;
}

.modal-dialog-content {
  -fx-padding: 20;
  -fx-spacing: 10;
  -fx-alignment: center;
  -fx-font-size: 20;
  -fx-background-color: linear-gradient(to bottom, derive(cadetblue, 20%), cadetblue);
  -fx-border-color: derive(cadetblue, -20%);
  -fx-border-width: 5;
  -fx-background-insets: 12;
  -fx-border-insets: 10;
  -fx-border-radius: 6;
  -fx-background-radius: 6;
}

использовать a Библиотека Вместо

Также отметим, что для создания диалогов я настоятельно рекомендую использовать ControlsFX проект, а не создание собственной диалоговой системы. Если ControlsFX не хватает функций, которые вам требуются (например, поддержка Drop shadow), вы можете запрос для этого против проекта ControlsFX и при необходимости вернуться к этому ответу.


простой работающего пример.

First result example Second result example

здесь fxml структура:

AnchorPane(200,200) // pane for space for shadow
    \- AnchorPane(center) // appliction pane
         \- Label // application content

реальные screen.fxml:

<AnchorPane fx:id="shadowPane" prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <AnchorPane fx:id="rootPane" layoutX="56.0" layoutY="62.0">
         <children>
            <Label fx:id="someLabel" layoutX="30.0" layoutY="30.0" text="Label" textFill="#f20000" />
         </children>
         <padding>
            <Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
         </padding>
      </AnchorPane>
   </children>
</AnchorPane>

Main.java

@Override
public void start(Stage stage) throws Exception {
    FXMLLoader loader = new FXMLLoader(getClass().getResource("/sample/screen.fxml"));
    AnchorPane shadowPane = loader.load();
    AnchorPane rootPane = (AnchorPane) shadowPane.lookup("#rootPane");
    rootPane.setStyle("-fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.4), 10, 0.5, 0.0, 0.0);" +
                      "-fx-background-color: white;"); // Shadow effect

    Scene scene = new Scene(shadowPane);
    stage.setScene(scene);

    shadowPane.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.SOLID, null, null))); // Some borders for for clarity

    shadowPane.setStyle("-fx-background-color: transparent;"); // Makes shadowPane transparent
    scene.setFill(Color.TRANSPARENT); // Fill our scene with nothing
    stage.initStyle(StageStyle.TRANSPARENT); // Important one!
    stage.show();
}

Ну, я нашел очень просто решение. Может быть, это не поддерживается в более ранних версиях? Однако.. Код:

iconPane.setEffect(new DropShadow(2d, 0d, +2d, Color.BLACK));

изображение показывает результат - мое намерение состояло в том, чтобы показать значок в виде FAB

enter image description here