当前位置: 首页 > 知识库问答 >
问题:

JavaFX:当有阴影效果的舞台时,如何正确地滑动窗格?

钱承允
2023-03-14

我在“JavaFX:如何为窗格创建动画效果的幻灯片(在透明的舞台内)”上看到过这个问题。

我不明白约翰·阿斯特拉里迪斯最后一条评论中的部分代码。似乎解决了我的问题。我想滑动一个带有影子舞台的窗格。现在我的问题是幻灯片动画播放超出了我的视觉根窗格的限制,它只是与舞台(或实际根窗格)的限制播放。

我的可视根窗格是实际根窗格的子级,我用填充和corlor.transparent设置实际根窗格来实现我的可视根窗格阴影效果。

@Override
public void start(Stage stage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
    stage.initStyle(StageStyle.TRANSPARENT);
    Scene scene = new Scene(root);//
    stage.setScene(scene);
    stage.show();
}
public static void main(String[] args) {
    launch(args);
}
<AnchorPane xmlns:fx="http://javafx.com/fxml/1" fx:id="anchorPane" prefWidth="500" prefHeight="500" style="-fx-background-color: transparent;"   
        fx:controller="leftslidemenusample.FXMLDocumentController">
<children>
    <ToolBar AnchorPane.topAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" minHeight="56.0"   >
           <Button text="menu" fx:id="menu"  />
    </ToolBar>
    <StackPane fx:id="mainContent"  style="-fx-background-color:rgba(0,0,0,0.30)" AnchorPane.bottomAnchor="0.0" AnchorPane.topAnchor="56.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"    >
        <children>
        </children>
    </StackPane>
    <AnchorPane fx:id="navList" style="-fx-background-color:white" AnchorPane.topAnchor="56.0" AnchorPane.bottomAnchor="0.0" prefWidth="180.0" translateX="-180"   >
        <children>
            <Label text="left side menu"/>
        </children>
    </AnchorPane>
</children>

控制器FXMLDocumentController.java

public class FXMLDocumentController implements Initializable {
@FXML
private AnchorPane anchorPane;
@FXML
private Button menu;
@FXML
private AnchorPane navList;

private double shadowSize = 15;

@Override
public void initialize(URL url, ResourceBundle rb) {

    Rectangle rectangle = new Rectangle(500,500);

    anchorPane.setClip(rectangle);
    anchorPane.getChildren().add(setupShadowPane());

    prepareSlideMenuAnimation();
}
private Pane setupShadowPane() {
    Pane shadowPane = new Pane();
    shadowPane.setPrefHeight(500);
    shadowPane.setPrefWidth(500);
    shadowPane.setStyle(
            "-fx-background-color: RED;" +
                    "-fx-effect: dropshadow(gaussian, black, " + 20 + ", 0, 0, 0);" +
                    "-fx-background-insets: " + shadowSize + ";"
    );

    Rectangle innerBounds = new Rectangle();
    Rectangle outerBounds = new Rectangle();
    shadowPane.layoutBoundsProperty().addListener((observable, oldBounds, newBounds) -> {
        System.out.println(newBounds.getWidth());
        innerBounds.relocate(newBounds.getMinX() + shadowSize, newBounds.getMinY() + shadowSize);
        innerBounds.setWidth(newBounds.getWidth() - shadowSize * 2);
        innerBounds.setHeight(newBounds.getHeight() - shadowSize * 2);
        outerBounds.setWidth(newBounds.getWidth());
        outerBounds.setHeight(newBounds.getHeight());

        Shape clip = Shape.subtract(outerBounds, innerBounds);
        shadowPane.setClip(clip);
    });

    return shadowPane;
}
private void prepareSlideMenuAnimation() {
    TranslateTransition openNav=new TranslateTransition(new Duration(350), navList);
    openNav.setToX(0);
    TranslateTransition closeNav=new TranslateTransition(new Duration(350), navList);
    menu.setOnAction((ActionEvent evt)->{
        if(navList.getTranslateX()!=0){
            openNav.play();
        }else{
            closeNav.setToX(-(navList.getWidth()));
            closeNav.play();
        }
    });
}

}

共有1个答案

马冯浩
2023-03-14

最后,我完成了。我认为约翰·阿斯特拉里迪斯的答案是错误的。但谢谢。关键是:

  1. 使用StackPane作为实际的根窗格,然后将可视根窗格和阴影窗格添加到实际的根窗格中作为StackPane的子窗格。可视根窗格是添加阴影效果窗格的必要条件。
  2. 用芯片设置可视根窗格,该芯片组成其外部布局,以显示阴影窗格的阴影效果;
  3. 用芯片设置阴影窗格,该芯片组成其内部布局,以显示可视根窗格的内容。

希望我用我糟糕的英语回答可以帮助一些人。我在下面发布了我的整个演示代码:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

public class FXApplication extends Application {

@Override
public void start(Stage stage) throws Exception {
    Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
    stage.initStyle(StageStyle.TRANSPARENT);
    Scene scene = new Scene(root);//
    scene.setFill(Color.TRANSPARENT);
    stage.setScene(scene);
    stage.show();
}

public static void main(String[] args) {
    launch(args);
}
}
<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<StackPane xmlns:fx="http://javafx.com/fxml/1" fx:id="pane" prefWidth="500" prefHeight="500" style="-fx-background-color: transparent;"
        fx:controller="FXMLDocumentController">
<children>
    <AnchorPane fx:id="anchorPane" prefWidth="500" prefHeight="500" style="-fx-background-color: WHITE;">
        <children>
            <ToolBar AnchorPane.topAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" minHeight="56.0"   >
                <Button text="menu" fx:id="menu"  />
            </ToolBar>
            <StackPane fx:id="mainContent"  style="-fx-background-color:rgba(0,0,0,0.30)" AnchorPane.bottomAnchor="0.0" AnchorPane.topAnchor="56.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"    >
                <children>
                </children>
            </StackPane>
            <AnchorPane fx:id="navList" style="-fx-background-color:white" AnchorPane.topAnchor="56.0" AnchorPane.bottomAnchor="0.0" prefWidth="180.0" translateX="-180"   >
                <children>
                    <Label text="left side menu"/>
                </children>
            </AnchorPane>
        </children>
    </AnchorPane>
</children>

控制器类--FXMLDocumentController.java

import javafx.animation.TranslateTransition;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;
import javafx.util.Duration;
import java.net.URL;
import java.util.ResourceBundle;

public class FXMLDocumentController implements Initializable {

@FXML
private AnchorPane anchorPane;
@FXML
private StackPane pane;
@FXML
private Button menu;
@FXML
private AnchorPane navList;
private double shadowSize = 10;

@Override
public void initialize(URL url, ResourceBundle rb) {

    Rectangle rectangle = new Rectangle(480,480);
    rectangle.relocate(10,10);
    anchorPane.setClip(rectangle);
    pane.getChildren().add(setupShadowPane());

    prepareSlideMenuAnimation();
}
private Pane setupShadowPane() {
    Pane shadowPane = new Pane();
    shadowPane.setPrefHeight(500);
    shadowPane.setPrefWidth(500);
    shadowPane.setStyle(
            "-fx-background-color: RED;" +
                    "-fx-effect: dropshadow(gaussian, black, " + 20 + ", 0, 0, 0);" +
                    "-fx-background-insets: " + shadowSize + ";"
    );

    Rectangle innerBounds = new Rectangle();
    Rectangle outerBounds = new Rectangle();
    shadowPane.layoutBoundsProperty().addListener((observable, oldBounds, newBounds) -> {
        innerBounds.relocate(newBounds.getMinX() + shadowSize, newBounds.getMinY() + shadowSize);
        innerBounds.setWidth(newBounds.getWidth() - shadowSize * 2);
        innerBounds.setHeight(newBounds.getHeight() - shadowSize * 2);
        outerBounds.setWidth(newBounds.getWidth());
        outerBounds.setHeight(newBounds.getHeight());

        Shape clip = Shape.subtract(outerBounds, innerBounds);
        shadowPane.setClip(clip);
    });

    return shadowPane;
}
private void prepareSlideMenuAnimation() {
    TranslateTransition openNav=new TranslateTransition(new Duration(350), navList);
    openNav.setToX(0 + shadowSize);
    TranslateTransition closeNav=new TranslateTransition(new Duration(350), navList);
    menu.setOnAction((ActionEvent evt)->{
        if(navList.getTranslateX()!=0+shadowSize){
            openNav.play();
        }else{
            closeNav.setToX(-(navList.getWidth())+shadowSize);
            closeNav.play();
        }
    });
}

}

和下图:

 类似资料:
  • 我读过许多关于透明度和阴影的问题,但我认为我没有看到这个具体的问题得到解决。 我能够成功地创建一个既有透明度又有阴影的窗口,但我不知道如何使颜色阴影不影响透明度颜色。 例如,下面的代码创建了一个具有灰色透明度和红色阴影的窗口。然而,红色也影响了主窗口的透明度,但我只想让阴影延伸到窗口的边框之外。 我的测试代码:

  • 我想要一些指导方针,如何实现一个幻灯片在过渡的窗格时,用户按下按钮,就像材料设计做它的滑动菜单。 这是一个视频链接,说明了我的需要。 我试过ScaleTransition,TranslateTransition,但他们没有成功。 我想在用户单击按钮时缩小锚窗格。 我错过了什么? ---更新2--- null 这是一个锚格(在其全宽处具有珊瑚色;展开)内的锚格(灰色的根格)。 这就是当你点击菜单按钮

  • 在这个框架中,每一个元素都一个 z 方向的深度,这个决定了这个元素是远离页面还是贴近页面。 你可以很简单的应用一个阴影效果,通过增加 class="z-depth-2" 类到 HTML 标签中。或者你可以继承这些阴影通过 Sass,通过使用 @extend .z-depth-2. A z-depth-0 来移除元素原有的深度的阴影。 <div class="col s12 m2"> <p clas

  • 假设我在JavaFX中有一个舞台。我没有按X关闭按钮来关闭窗口,而是隐藏窗口,或者说切换到计算机上的其他应用程序。无论何时我隐藏窗口或切换到PC的任何其他窗口,我都希望舞台自动关闭。 我尝试了这三种方法,但所有这些方法仅在我自己关闭窗口时激活,而不是在我隐藏窗口时激活。 任何帮助将不胜感激。谢谢。

  • 本文向大家介绍如何在JavaFX中的文本节点上添加阴影效果?,包括了如何在JavaFX中的文本节点上添加阴影效果?的使用技巧和注意事项,需要的朋友参考一下 您可以使用setEffect()方法将效果添加到JavaFX中的任何节点对象。此方法接受Effect类的对象,并将其添加到当前节点。 javafx.scene.effect.DropShadow类表示投影效果。此效果使用指定的参数(颜色,偏移量

  • 问题内容: 我们正在Windows中构建JavaFX应用程序,我们希望能够做一些事情来操纵我们的应用程序在Windows 7/8任务栏中的显示方式。这需要修改Windows变量,称为“ 应用程序用户模型ID ”。 我们已经通过使用JNA设法完全完成了我们在Swing中想要的工作,并且我们想在JavaFX中重复我们的解决方案。不幸的是,要做到这一点,我们需要能够为应用程序中的每个窗口检索(窗口句柄)