【问题标题】:How to set/remember scrollbar thumb position in JavaFX 8 WebView?如何在 JavaFX 8 WebView 中设置/记住滚动条拇指位置?
【发布时间】:2015-07-07 09:31:39
【问题描述】:

我对 JavaFX 8 WebView 及其滚动条有疑问。

我想重新加载一个 HTML 文档并记住当前垂直滚动条的位置。不幸的是,每当我重新加载文档时,滚动条就会移动到它的初始位置。如何强制滚动条记住它的位置?

我解决这个问题的尝试:

通过WebView#lookup(String id)(参见1)可以访问WebView 实例的垂直和水平ScrollBar 实例。这使我可以通过ScrollBar#getValue() 获取当前滚动条值,即拇指位置。不幸的是,通过ScrollBar#setValue(double value) 设置值并没有达到预期的效果。滚动条拇指位置保持不变。

此外,我怀疑 JavaFX 滚动条未呈现。相反,似乎显示了具有类似样式的 WebKit 滚动条。至少通过Scenic View进行的简短场景图分析给了我这样的印象。

这是一个 JavaFX 错误吗?有没有办法实现所需的行为?

这是一个演示 setValue() 问题的示例程序:

import java.util.Set;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollBar;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebView;
import javafx.stage.Stage;

/**
 * ScrollBar bug in JavaFX 8 WebView?
 * 
 * @author Michael Hoffer <info@michaelhoffer.de>
 */
public class WebViewAndItsScrollBars extends Application {

    @Override
    public void start(Stage primaryStage) {

        // create webview and load content
        WebView view = new WebView();
        view.getEngine().load(
                "https://docs.oracle.com/javase/8/javafx/"
                + "api/javafx/scene/control/ScrollBar.html");

        // vertical scrollbar of the webview
        ScrollBar vScrollBar = getVScrollBar(view);

        // change scrollbar value, i.e., thumb position via button
        Button btn = new Button();
        btn.setText("Move ScrollBar");
        btn.setOnAction((ActionEvent event) -> {
            if (vScrollBar != null) {
                double value = 2000;
                System.out.println(">> current value: " + vScrollBar.getValue());
                System.out.println(">> setting scrollbar value to " + value);
                vScrollBar.setValue(value);
            }
        });

        // create root layout
        VBox root = new VBox();
        root.setAlignment(Pos.CENTER);
        root.getChildren().add(view);
        root.getChildren().add(btn);

        // setup and show stage
        Scene scene = new Scene(root, 1024, 600);
        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

    /**
     * Returns the vertical scrollbar of the webview.
     *
     * @param webView webview
     * @return vertical scrollbar of the webview or {@code null} if no vertical
     * scrollbar exists
     */
    private ScrollBar getVScrollBar(WebView webView) {

        Set<Node> scrolls = webView.lookupAll(".scroll-bar");
        for (Node scrollNode : scrolls) {
            if (ScrollBar.class.isInstance(scrollNode)) {
                ScrollBar scroll = (ScrollBar) scrollNode;
                if (scroll.getOrientation() == Orientation.VERTICAL) {
                    return scroll;
                }
            }
        }
        return null;
    }
}

相关问题:How to hide scrollbars in the JavaFX WebView

【问题讨论】:

    标签: java webview webkit javafx-8


    【解决方案1】:

    我找到了解决办法:

    可以通过使用 JavaScript 来实现所需的行为。大多数代码示例通过WebView#getEngine()#loadContent(String content) 将 JavaScript 代码直接注入到内容中。但是,对于 URL,这不起作用。但是网络引擎提供了一种直接执行 JavaScript 的方法:

    webView.getEngine().executeScript("// javascript code");
    

    以下是我用来控制滚动条的方法:

        /**
         * Scrolls to the specified position.
         * @param view web view that shall be scrolled
         * @param x horizontal scroll value
         * @param y vertical scroll value
         */
        public void scrollTo(WebView view, int x, int y) {
            view.getEngine().executeScript("window.scrollTo(" + x + ", " + y + ")");
        }
    
        /**
         * Returns the vertical scroll value, i.e. thumb position.
         * This is equivalent to {@link javafx.scene.control.ScrollBar#getValue().
         * @param view
         * @return vertical scroll value
         */
        public int getVScrollValue(WebView view) {
            return (Integer) view.getEngine().executeScript("document.body.scrollTop");
        }
    
        /**
         * Returns the horizontal scroll value, i.e. thumb position.
         * This is equivalent to {@link javafx.scene.control.ScrollBar#getValue()}.
         * @param view
         * @return horizontal scroll value
         */
        public int getHScrollValue(WebView view) {
            return (Integer) view.getEngine().executeScript("document.body.scrollLeft");
        }
    
        /**
         * Returns the maximum vertical scroll value. 
         * This is equivalent to {@link javafx.scene.control.ScrollBar#getMax()}.
         * @param view 
         * @return vertical scroll max
         */
        public int getVScrollMax(WebView view) {
            return (Integer) view.getEngine().executeScript("document.body.scrollWidth");
        }
    
        /**
         * Returns the maximum horizontal scroll value. 
         * This is equivalent to {@link javafx.scene.control.ScrollBar#getMax()}.
         * @param view 
         * @return horizontal scroll max
         */
        public int getHScrollMax(WebView view) {
            return (Integer) view.getEngine().executeScript("document.body.scrollHeight");
        }
    

    这是问题中代码的工作版本:

    import java.util.Set;
    import javafx.application.Application;
    import javafx.collections.ListChangeListener;
    import javafx.event.ActionEvent;
    import javafx.geometry.Orientation;
    import javafx.geometry.Pos;
    import javafx.scene.Node;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.ScrollBar;
    import javafx.scene.layout.VBox;
    import javafx.scene.web.WebView;
    import javafx.stage.Stage;
    
    /**
     * ScrollBar bug in JavaFX 8 WebView?
     *
     * @author Michael Hoffer &lt;info@michaelhoffer.de&gt;
     */
    public class WebViewAndItsScrollBars extends Application {
    
        @Override
        public void start(Stage primaryStage) {
    
            // create webview and load content
            WebView view = new WebView();
    
            view.getEngine().load(
                    "https://docs.oracle.com/javase/8/javafx/"
                    + "api/javafx/scene/control/ScrollBar.html");
    
            // change scrollbar value, i.e., thumb position via button
            Button btn = new Button();
            btn.setText("Move ScrollBar");
            btn.setOnAction((ActionEvent event) -> {
    
                int value = 2000;
                System.out.println(">> current value: " + getVScrollValue(view));
                System.out.println(">> setting scrollbar value to " + value);
                scrollTo(view, 0, value);
    
            });
    
            // create root layout
            VBox root = new VBox();
            root.setAlignment(Pos.CENTER);
            root.getChildren().add(view);
            root.getChildren().add(btn);
    
            // setup and show stage
            Scene scene = new Scene(root, 1024, 600);
            primaryStage.setTitle("Hello World!");
            primaryStage.setScene(scene);
            primaryStage.show();
        }
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            launch(args);
        }
    
        /**
         * Scrolls to the specified position.
         * @param view web view that shall be scrolled
         * @param x horizontal scroll value
         * @param y vertical scroll value
         */
        public void scrollTo(WebView view, int x, int y) {
            view.getEngine().executeScript("window.scrollTo(" + x + ", " + y + ")");
        }
    
        /**
         * Returns the vertical scroll value, i.e. thumb position.
         * This is equivalent to {@link javafx.scene.control.ScrollBar#getValue().
         * @param view
         * @return vertical scroll value
         */
        public int getVScrollValue(WebView view) {
            return (Integer) view.getEngine().executeScript("document.body.scrollTop");
        }
    
        /**
         * Returns the horizontal scroll value, i.e. thumb position.
         * This is equivalent to {@link javafx.scene.control.ScrollBar#getValue()}.
         * @param view
         * @return horizontal scroll value
         */
        public int getHScrollValue(WebView view) {
            return (Integer) view.getEngine().executeScript("document.body.scrollLeft");
        }
    
        /**
         * Returns the maximum vertical scroll value. 
         * This is equivalent to {@link javafx.scene.control.ScrollBar#getMax()}.
         * @param view 
         * @return vertical scroll max
         */
        public int getVScrollMax(WebView view) {
            return (Integer) view.getEngine().executeScript("document.body.scrollWidth");
        }
    
        /**
         * Returns the maximum horizontal scroll value. 
         * This is equivalent to {@link javafx.scene.control.ScrollBar#getMax()}.
         * @param view 
         * @return horizontal scroll max
         */
        public int getHScrollMax(WebView view) {
            return (Integer) view.getEngine().executeScript("document.body.scrollHeight");
        }
    }
    

    【讨论】:

    猜你喜欢
    • 2013-08-24
    • 1970-01-01
    • 1970-01-01
    • 2014-10-30
    • 1970-01-01
    • 2012-03-11
    • 2014-05-11
    • 2012-10-14
    • 2012-09-26
    相关资源
    最近更新 更多