当前位置: 首页 > 知识库问答 >
问题:

如何提高ScrollPane JavaFX的滚动速度

楚宪
2023-03-14

嗨,有没有什么方法可以提高滚动速度。我找到了一些解决方案,但都不适合我。这就是我尝试的:

@FXML
private ScrollPane scrollPane;

@FXML
public void initialize() {
    Platform.runLater(() -> setFasterScroller(scrollPane));
}

private static void setFasterScroller(ScrollPane scrollPane) {
    ScrollBar verticalScrollbar = (ScrollBar) scrollPane.lookup(".scroll-bar:vertical");
    double defaultUnitIncrement = verticalScrollbar.getUnitIncrement();
    verticalScrollbar.setUnitIncrement(defaultUnitIncrement * 3);
}

或者使用css:

.scroll-pane .scroll-bar:vertical {
    -fx-unit-increment: 10 ;
    -fx-block-increment: 50 ;
}

.scroll-pane .scroll-bar:horizontal {
    -fx-unit-increment: 5 ;
    -fx-block-increment: 20 ;
}

还有别的办法吗?编辑:上面的解决方案都不起作用,我试图使用大得离谱的数字,但滚动速度还是一样

共有1个答案

柴翰藻
2023-03-14

应用程序应该“更快”呈现滚动窗格内容以提高滚动速度。您可以实现它,减少要渲染的对象数量或/并减少“重新绘制”方法调用的数量(JFX中的layoutChildren)。据我所知,代码片段,您将减少重新绘制的数量,因为更改增量参数可以减少重新绘制内容的次数。

  • blockIncrement(如果点击了条的轨迹)
  • unitIncrement(如果单击了向上、向下、右、左按钮)

当您单击滚动窗格按钮时调用方法ScrollPane.layoutChildren()。它使ScrollBar重置增量(ScrollPaneSkin.updateVerticalSB(),ScrollPaneSkin.updateHorizontalSB())。因此您需要存储以前的增量值并过滤'开箱即用'滚动事件。

资料来源:

public class UnitIncrementScrollPaneSkin extends ScrollPaneSkin {

    private double prevVerticalBlockIncrement;
    private double prevHorizontalBlockIncrement;
    private double prevVerticalUnitIncrement;
    private double prevHorizontalUnitIncrement;

    public UnitIncrementScrollPaneSkin(final ScrollPane scrollPane) {
        super(scrollPane);
        filterScrollEvents();
    }

    @Override
    protected void layoutChildren(final double x, final double y, final double w, final double h) {
        prevVerticalUnitIncrement = getVerticalScrollBar().getUnitIncrement();
        prevHorizontalUnitIncrement = getHorizontalScrollBar().getUnitIncrement();
        prevVerticalBlockIncrement = getVerticalScrollBar().getBlockIncrement();
        prevHorizontalBlockIncrement = getHorizontalScrollBar().getBlockIncrement();
        super.layoutChildren(x, y, w, h);
        getVerticalScrollBar().setUnitIncrement(prevVerticalUnitIncrement);
        getHorizontalScrollBar().setUnitIncrement(prevHorizontalUnitIncrement);
        getVerticalScrollBar().setBlockIncrement(prevVerticalBlockIncrement);
        getHorizontalScrollBar().setBlockIncrement(prevHorizontalBlockIncrement);
    }

    private void filterScrollEvents() {
        getSkinnable().addEventFilter(ScrollEvent.SCROLL, event -> {

            if (event.getDeltaX() < 0) {
                getHorizontalScrollBar().increment();
            } else if (event.getDeltaX() > 0) {
                getHorizontalScrollBar().decrement();
            }

            if (event.getDeltaY() < 0) {
                getVerticalScrollBar().increment();
            } else if (event.getDeltaY() > 0) {
                getVerticalScrollBar().decrement();
            }

            event.consume();
        });
    }

    public ScrollBar getVerticalScrollBar() {
        return vsb;
    }

    public ScrollBar getHorizontalScrollBar() {
        return hsb;
    }
}

用法:

@FXML
public void initialize() {
    final double initialInc = 0.2;
    UnitIncrementScrollPaneSkin skin = new UnitIncrementScrollPaneSkin(scrollPane);
    skin.getVerticalScrollBar().setUnitIncrement(initialInc);
    skin.getVerticalScrollBar().setBlockIncrement(initialInc);
    skin.getHorizontalScrollBar().setUnitIncrement(initialInc);
    skin.getHorizontalScrollBar().setBlockIncrement(initialInc);
    scrollPane.setSkin(skin);
}

测试应用程序:

<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="226.0" prefWidth="215.0" xmlns="http://javafx.com/javafx/8.0.141" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.stackoverflow.app.scrollpane.SpeedUpScrollPaneController">
   <children>
      <ScrollPane fx:id="scrollPane" fitToHeight="true" fitToWidth="true" hbarPolicy="ALWAYS" prefHeight="200.0" prefWidth="200.0" vbarPolicy="ALWAYS">
         <content>
            <GridPane>
              <rowConstraints>
                <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
              </rowConstraints>
            </GridPane>
         </content>
      </ScrollPane>
      <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
         <children>
            <Label text="V:" />
            <Spinner fx:id="spinnerVertical" prefHeight="25.0" prefWidth="85.0">
                 <valueFactory>
                    <SpinnerValueFactory.DoubleSpinnerValueFactory amountToStepBy="0.1" max="1.0" min="0" />
                 </valueFactory>
            </Spinner>
         </children>
      </HBox>
      <HBox alignment="CENTER" prefHeight="100.0" prefWidth="200.0">
         <children>
            <Label text="H:" />
            <Spinner fx:id="spinnerHorizontal" prefHeight="25.0" prefWidth="85.0">
                <valueFactory>
                    <SpinnerValueFactory.DoubleSpinnerValueFactory amountToStepBy="0.1" max="1.0" min="0" />
                 </valueFactory>
            </Spinner>
         </children>
      </HBox>
      <ListView fx:id="listViewLog" prefHeight="200.0" prefWidth="200.0" />
   </children>
</VBox>
public class SpeedUpScrollPaneController {

    @FXML
    private ListView<String> listViewLog;
    @FXML
    private Spinner<Double> spinnerVertical;
    @FXML
    private Spinner<Double> spinnerHorizontal;
    @FXML
    private ScrollPane scrollPane;

    @FXML
    public void initialize() {
        mockScrollPane();
        initScrollPane();
    }

    private void mockScrollPane() {
        for (int i = 0; i < 100; i++) {
            for (int j = 0; j < 100; j++) {
                final Label label = new Label(i + "," + j);
                label.setMinWidth(60);
                label.setMinHeight(30);
                ((GridPane) scrollPane.getContent()).add(label, i, j);
            }
        }
    }

    private void initScrollPane() {
        final UnitIncrementScrollPaneSkin skin = new UnitIncrementScrollPaneSkin(scrollPane);
        scrollPane.setSkin(skin);
        initIncrement(0.2, spinnerHorizontal, skin.getHorizontalScrollBar());
        initIncrement(0.2, spinnerVertical, skin.getVerticalScrollBar());
    }

    private void initIncrement(final double increment, final Spinner<Double> spinner, final ScrollBar scrollBar) {
        scrollBar.unitIncrementProperty().addListener((source, prev, curr) -> {
            final String vLog = String.format("%tr: %s unitIncrement=%f", Calendar.getInstance(),
                    scrollBar.getOrientation(), curr);
            listViewLog.getItems().add(vLog);
            listViewLog.scrollTo(vLog);
        });
        scrollBar.blockIncrementProperty().addListener((source, prev, curr) -> {
            final String vLog = String.format("%tr: %s blockIncrement=%f", Calendar.getInstance(),
                    scrollBar.getOrientation(), curr);
            listViewLog.getItems().add(vLog);
            listViewLog.scrollTo(vLog);
        });
        spinner.valueProperty().addListener((source, prev, curr) -> {
            scrollBar.setUnitIncrement(curr);
            scrollBar.setBlockIncrement(curr);

        });

        Platform.runLater(() -> {
            scrollBar.setUnitIncrement(increment);
            scrollBar.setBlockIncrement(increment);
            spinner.getValueFactory().setValue(scrollBar.getUnitIncrement());
        });
    }
}
  • 0.0-

注:如果你有很多要滚动的对象,你可以尝试以下方法:

  • 创建代表滚动窗格内容的图像位图
  • 开始滚动时显示图像位图
  • 在X,Y处移动图像(基于ScrollEvent.getDeltaX()ScrollEvent)。getDeltaY()
  • 隐藏图像,在完成滚动时用新坐标显示滚动窗格节点
 类似资料:
  • 我正在项目的中添加。 所有工作都很好,但在JPanel中使用鼠标滚轮滚动鼠标存在一个问题。滚动时速度很慢。如何让它更快? 我的代码是:

  • 我正在使用来使我的中的项目在屏幕上“对齐”(我的卡片占据了屏幕的大部分,所以我希望它们在每次刷/抛/滚动时都对齐并填充屏幕)。 我在苦苦思索如何让卡片更快地卡入位。我已经尝试创建自定义的(并编辑或中的方法),以及自定义的(并编辑fling方法)。但没有任何东西影响卡“卡”入位的速度。 我想问题是我真的不明白是如何将卡片“滚动”到正确的位置的。它似乎没有使用的或方法。

  • 问题内容: 我看到了启用或禁用鼠标滚轮滚动的方法。但是,有什么方法可以调整滚动速度?我认为这太慢了。不管我使窗口多大,每次单击滚动大约三个像素。我希望它远不止于此。 有任何想法吗? 问题答案: 您可以尝试以下方法:

  • 本文向大家介绍如何提高.Net动态页面响应速度?相关面试题,主要包含被问及如何提高.Net动态页面响应速度?时的应答技巧和注意事项,需要的朋友参考一下 研究表明,页面响应速度超过5秒,90%的用户会选择关闭页面。影响页面响应速度因素很多,分别从前端,后端,数据库,运维阐述。 一、前端性能优化(引用网址 https://www.jianshu.com/p/60b715bd5d73) 思路:分析一个

  • 本文向大家介绍如何提高javascript加载速度,包括了如何提高javascript加载速度的使用技巧和注意事项,需要的朋友参考一下 方法如下: 1、将所有<script>标签放在尽可能接近<body>标签底部的位置,以保证页面在脚本运行之前完成解析尽量减少对整个页面下载的影响 2、限制页面的<script>总数也可以改善性能。每当页面解析碰到一个<script>标签时, 紧接着有一段时间用于代

  • 我是Apache Hbase的新手,我使用的是hbase-0.98.13,并且我已经创建了一个表示例,其列族为sample_family。并且我已经将pig脚本的输出加载到hbase表中。当我尝试基于列族中的一个列扫描表时,它需要超过2分钟。 是否为此进行任何配置更改?有人能帮我吗?