diff --git a/src/main/java/com/imyeyu/fx/TimiFX.java b/src/main/java/com/imyeyu/fx/TimiFX.java index ca73404..599c636 100644 --- a/src/main/java/com/imyeyu/fx/TimiFX.java +++ b/src/main/java/com/imyeyu/fx/TimiFX.java @@ -1,10 +1,18 @@ package com.imyeyu.fx; +import com.imyeyu.fx.utils.ScreenFX; +import com.imyeyu.java.bean.Callback; +import com.imyeyu.java.ref.Ref; +import com.imyeyu.utils.Calc; +import com.imyeyu.utils.OS; import javafx.application.Application; import javafx.application.Platform; +import javafx.beans.Observable; import javafx.beans.binding.Bindings; import javafx.beans.binding.BooleanBinding; +import javafx.beans.property.BooleanProperty; import javafx.beans.property.ReadOnlyBooleanProperty; +import javafx.beans.property.SimpleBooleanProperty; import javafx.event.EventHandler; import javafx.geometry.Rectangle2D; import javafx.scene.Node; @@ -18,10 +26,6 @@ import javafx.stage.Screen; import javafx.stage.Stage; import javafx.stage.Window; import javafx.stage.WindowEvent; -import com.imyeyu.fx.utils.ScreenFX; -import com.imyeyu.java.ref.Ref; -import com.imyeyu.utils.Calc; -import com.imyeyu.utils.OS; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -281,7 +285,7 @@ public final class TimiFX { * @param control 控件({@link javafx.scene.control.ListView}, {@link javafx.scene.control.TableView} 等) * @param index 指定项下标 */ - public static void scrollToCenter(Control control, int index) { + public static void scrollToCenter(Control control, int index) { try { if (control.getSkin() == null) { return; @@ -301,7 +305,38 @@ public final class TimiFX { } } + public static void addScrollFinishedListener(Control control, Callback callback) { + BooleanProperty finish = new SimpleBooleanProperty(false); + control.skinProperty().addListener((obs, o, skin) -> { + try { + VirtualFlow flow = Ref.getFieldValue(control.getSkin(), "flow", VirtualFlow.class); + if (flow == null) { + throw new UnsupportedOperationException("unsupported this control"); + } + // 监听总高度和视口高度的变化 + Observable[] dependencies = {flow.layoutBoundsProperty(), flow.parentProperty()}; + BooleanBinding binding = Bindings.createBooleanBinding(() -> { + double totalHeight = flow.prefHeight(-1); + double viewportHeight = flow.getLayoutBounds().getHeight(); + if (viewportHeight <= 0 || totalHeight <= 0) { + return false; + } + double maxVValue = (totalHeight - viewportHeight) / viewportHeight; + double currentVValue = flow.getLayoutY() / viewportHeight; + return currentVValue >= (maxVValue - 0.01); + }, dependencies); + finish.bind(binding); + } catch (Exception e) { + throw new RuntimeException(e); + } + }); + finish.addListener((obs, o, isFinished) -> { + if (isFinished) { + callback.handler(); + } + }); + } /** * 重启程序,命令需自定