如何在JavaFX上的场景上绘制渐变?

Mat*_*ari 3 java javafx javafx-2 javafx-8

有没有办法在JavaFX舞台的整个场景中绘制从黑色到透明的径向渐变?我希望实现这样的目标: 例

jew*_*sea 6

这是一个快速回答,它使用StackPane作为场景根,以允许添加具有从黑色到透明的径向渐变背景的叠加.

  • 您可以调整径向渐变颜色或半径,例如制作内部颜色Color.BLACK.deriveColor(0, 1, 1, 0.2),以更改效果中的高光量和强度.
  • 像这样的渐变也可以在CSS中设置,因此如果您愿意,可以使用CSS而不是Java代码来设置效果的样式.
  • 这种实现的输出稍微受到径向渐变的束缚(不确定如何进一步改善),但是根据你的公差,它是好的.

阴影

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.effect.BoxBlur;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import javafx.stage.Stage;

// java 8
// click on the scene to place a shaded lens effect over the scene.
public class ShadedScene extends Application {
    @Override
    public void start(Stage stage) {
        StackPane layout = new StackPane(
                new Label("Click to shade/unshade")
        );
        layout.setPrefSize(400, 300);

        Scene scene = new Scene(layout);
        makeShadeable(scene);

        stage.setScene(scene);
        stage.show();
    }

    /**
     * Applies a lens effect gradient to a scene root node.
     * The effect is kind of like a flashlight shining against the wall in the dark.
     *
     * For the gradient to be applied, the scene's root must be defined and a Pane
     * to which the effect can added and removed as a child.
     * 
     * @param scene the scene to have the effect applied.
     */
    private void makeShadeable(Scene scene) {
        if (scene.getRoot() == null ||
            !(scene.getRoot() instanceof Pane)) {
            return;
        }

        Pane shade = new Pane();
        RadialGradient shadePaint = new RadialGradient(
                0, 0, 0.5, 0.5, 1, true, CycleMethod.NO_CYCLE,
                new Stop(1, Color.BLACK),
                new Stop(0, Color.TRANSPARENT)
        );

        shade.setBackground(
                new Background(
                        new BackgroundFill(
                                shadePaint, null, new Insets(-10)
                        )
                )
        );

        // blur helps reduce visible banding of the radial gradient.
        shade.setEffect(new BoxBlur(5, 5, 3));

        Pane root = (Pane) scene.getRoot();
        scene.setOnMouseClicked(event -> {
            if (root.getChildren().contains(shade)) {
                root.getChildren().remove(shade);
            } else {
                root.getChildren().add(shade);
            }
        });
    }

    public static void main(String[] args) {
        launch(args);
    }
}
Run Code Online (Sandbox Code Playgroud)

还有其他方法可以实现类似于所需效果的方法.例如,下面的技术直接将内部阴影和颜色调整应用于根窗格,因此不需要其他节点.

阴影内阴影

private void makeShadeableByInnerShadow(Scene scene) {
    InnerShadow shade = new InnerShadow();
    shade.setWidth(120);
    shade.setHeight(120);
    shade.setInput(new ColorAdjust(0, 0, -0.3, 0));

    Parent root = scene.getRoot();
    scene.setOnMouseClicked(event -> {
        if (root.getEffect() == null) {
            root.setEffect(shade);
        } else {
            root.setEffect(null);
        }
    });
}
Run Code Online (Sandbox Code Playgroud)