Created
June 19, 2018 09:08
-
-
Save dlemmermann/20953076779073d706b6f152c6d32d2a to your computer and use it in GitHub Desktop.
A JavaFX ScrollPane with a drop shadow effect at the top when the user scrolls down.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment