JavaFX技巧30:带有DropShadow的ScrollPane

最近,在我的一个项目中,我发现用户很难看到ScrollPane实例的内容当前是否已滚动。 一种更清晰的方法是在滚动窗格的顶部添加阴影。

这也是Google的Material Design建议的。 所以我尝试了一下。 在我的解决方案中,我只是向ScrollPane添加了一个区域,并在对其进行布局时将其移出ScrollPane的视口边界,因此只有应用于该区域的阴影效果仍可以到达该区域。

为了真正确保该区域不可见,我还必须在ScrollPane上设置一个剪辑。 尽管我必须承认我不是100%确信这是实现此目标的最佳方法,但它的效果很好。 因此,如果有人有任何建议/替代方法,请发表评论。

在下面您将看到滚动我们应用程序屏幕之一的屏幕截图之前和之后的内容。

滚动之前

滚动前使用ScrollPane

滚动后

带有阴影的ScrollPane

顺便说一句:我实现了这种方式,使阴影不会突然出现,而是逐步移入视口,具体取决于用户滚动了多远。 要查看此内容,您需要非常缓慢地向下滚动。

ShadowScrollPane的代码可以在GitHub的以下要点中找到:

package uk.co.senapt.desktop.shell;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.Region;
import javafx.scene.shape.Rectangle;

/**
 * Created by lemmi on 23.08.17.
 */
public class ShadowScrollPane extends ScrollPane {

    private Region shadow = new Region();

    public ShadowScrollPane() {
        super();

        init();
    }

    public ShadowScrollPane(Node content) {
        super(content);
        init();
    }

    private void init() {
        skinProperty().addListener(it -> {
            getChildren().addAll(shadow);
        });

        setFitToWidth(true);
        setVbarPolicy(ScrollBarPolicy.NEVER);
        setHbarPolicy(ScrollBarPolicy.NEVER);

        shadow.setManaged(false);
        shadow.setStyle("-fx-pref-height: 10;" +
                "-fx-background-color: black;" +
                "-fx-effect: dropshadow(gaussian, rgba(0, 0, 0, .75), 20, 0.19, 0, 6);");
        shadow.getStyleClass().add("shadow");
        shadow.visibleProperty().bind(showShadowProperty());
        shadow.setMouseTransparent(true);
        shadow.visibleProperty().bind(vvalueProperty().greaterThan(0));

        Rectangle clip = new Rectangle();
        clip.widthProperty().bind(widthProperty());
        clip.heightProperty().bind(heightProperty());
        setClip(clip);

        vvalueProperty().addListener(it -> {
            if (lastOffset != computeOffset()) {
                requestLayout();
            }
        });
        showShadowProperty().addListener(it -> requestLayout());
    }

    private final BooleanProperty showShadow = new SimpleBooleanProperty(this, "showShadow", true);

    public final BooleanProperty showShadowProperty() {
        return showShadow;
    }

    public final boolean isShowShadow() {
        return showShadow.get();
    }

    public final void setShowShadow(boolean show) {
        showShadow.set(show);
    }

    private final int SHADOW_HEIGHT = 30;

    @Override
    protected void layoutChildren() {
        super.layoutChildren();

        if (isShowShadow()) {
            Insets insets = getInsets();
            double w = getWidth();
            double offset = computeOffset();
            shadow.resizeRelocate(-10, insets.getTop() - shadow.prefHeight(-1) - SHADOW_HEIGHT + offset, w + 20, shadow.prefHeight(-1) - 1);
            lastOffset = offset;
        }
    }

    private double lastOffset = 0;

    private double computeOffset() {
        if (getContent() != null) {
            return Math.min(getVvalue() * getContent().prefHeight(-1), SHADOW_HEIGHT);
        }

        return 0;
    }
}

翻译自: https://www.javacodegeeks.com/2018/06/javafx-scrollpane-dropshadow.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值