8

私は自分のペインを視覚的に少し良くしようとしているので、私がやっていることは、ドロップシャドウ効果を追加するためにステージを装飾されていない(OK)および(TRYING)に設定することです(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;
}
4

4 に答える 4

12

以前の例は私のために働く

How to add shadow to window in JavaFX? への回答用に提供されたサンプルコード? Java 8b96、Windows 7で問題なく動作します(表示されているダイアログに影を落とします)。JavaFX 2用に書いたときは、その環境でも動作しました。

完全な実行可能コードを提供していないため、例に何が欠けているのか正確に言えませんでした。

透過ダイアログ

コードで考えられる問題

私の推測では、影を表示するためのスペースがダイアログにあるように、背景コンテンツを挿入していないということです。つまり、ダイアログをコンテンツでいっぱいにして、エフェクトを表示するためにコンテンツの周りにスペースをダイアログに残しません。以下の例では、css ルールでインセットを実現しています。-fx-background-insets: 12;

更新されたサンプル コード

サンプルコードの修正版をこの回答にコピーして、別の回答からのあいまいな要旨リンクに含まれないようにしました。元の回答が作成されて以来、元の回答で使用されていたビルダーが廃止されたため、変更は標準の 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());
    }
}

modal-dialog.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;
}

代わりにライブラリを使用する

また、ダイアログを作成するには、独自のダイアログ システムを作成するよりも、 ControlsFXプロジェクトを使用することを強くお勧めします。ControlsFX に必要な機能 (ドロップ シャドウのサポートなど) がない場合は、ControlsFX プロジェクトに対してその機能のリクエストを提出し、必要に応じてこの回答にリンクすることができます。

于 2013-07-10T19:46:30.790 に答える
6

簡単な作業例。

最初の結果の例 2 番目の結果の例

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();
}
于 2015-07-28T21:12:15.707 に答える
1

さて、私は非常に簡単な解決策を見つけました。これは以前のバージョンではサポートされていなかったのでしょうか。しかし..コード:

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

写真は結果を示しています-私の意図は、FABの外観でアイコンを表示することでした

ここに画像の説明を入力

于 2015-05-14T00:02:24.900 に答える