Javafx 滚动条拇指变得太小

Cal*_*n_Z 4 javafx

当我使用一些包含滚动条的组件时,例如TextArea、ListView和ScrollPane,当内容很长时,滚动条的拇指会变得很小。如何设置拇指的最小长度?

Sai*_*dem 5

现阶段没有直接的方法来限制拇指的大小。

但通过一些小小的调整,您可以获得所需的行为;-)。如果您可以使用lookup()方法,请检查以下方法。

总体思路是查找“拇指”并在其高度/位置发生变化时动态更新其尺寸。

下面是用于此目的的实用程序类,您可以向其传递所需的控件,实用程序将确保搜索所需的更新并将其添加到垂直滚动条。

import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Orientation;
import javafx.scene.control.Control;
import javafx.scene.control.ScrollBar;
import javafx.scene.control.Skin;
import javafx.scene.layout.StackPane;

import java.util.Optional;

public class ScrollThumbSizing {
    private static final double THUMB_MIN_HEIGHT = 50;
    private static final String THUMB_STYLECLASS = ".thumb";
    private static final String DISABLE_LISTENERS = "listener";
    private static final String ACTUAL_HEIGHT = "height";

    public static void enable(final Control control) {
        final ChangeListener<Skin<?>> changeListener = (obs, old, skin) -> {
            if (skin != null) {
                searchScrollBar(control);
            }
        };
        control.skinProperty().addListener(changeListener);
        if (control.getSkin() != null) {
            searchScrollBar(control);
        }
    }

    private static void searchScrollBar(final Control control) {
        // When the skin is loaded, let the things settle and do search operation at later stage
        Platform.runLater(() -> {
            // Find the vertical scroll bar
            Optional<ScrollBar> scrollBar = control.lookupAll(".scroll-bar").stream()
                    .map(node -> (ScrollBar) node)
                    .filter(sb -> sb.getOrientation() == Orientation.VERTICAL)
                    .findFirst();

            scrollBar.ifPresent(sb -> {
                final StackPane thumb = (StackPane) sb.lookup(THUMB_STYLECLASS);
                if (thumb != null) {
                    // When the thumb exists, and if the height/position is changed, recompute the thumb dimensions.
                    final ChangeListener<? super Number> listener = (obs1, old1, val) -> adjustThumb(sb, thumb);
                    thumb.heightProperty().addListener(listener);
                    thumb.translateYProperty().addListener(listener);
                    adjustThumb(sb, thumb);
                }
            });
        });
    }

    private static void adjustThumb(final ScrollBar scrollBar, final StackPane thumb) {
        final double thumbHeight = thumb.getHeight();
        /* Caching the actual thumb height if it is less than the minimum height */
        if (thumbHeight < THUMB_MIN_HEIGHT) {
            scrollBar.getProperties().put(ACTUAL_HEIGHT, thumbHeight);
        } else if (thumbHeight > THUMB_MIN_HEIGHT) {
            scrollBar.getProperties().remove(ACTUAL_HEIGHT);
        }

        /* If the thumb height is less than or equal to the minimum height, adjust the thumb size */
        /* DISABLE_LISTENERS key is to NOT let the things happen in loop forever... */
        if (scrollBar.getProperties().get(DISABLE_LISTENERS) == null && thumbHeight <= THUMB_MIN_HEIGHT) {
            /* Disabling the listeners */
            scrollBar.getProperties().put(DISABLE_LISTENERS, true);

            /* Resizing the thumb to minimum height */
            thumb.resize(scrollBar.getWidth(), THUMB_MIN_HEIGHT);

            /* Positioning the thumb when set to minimum height */
            final Object thumbActualHgtObj = scrollBar.getProperties().get(ACTUAL_HEIGHT);
            final double thumbActualHgt = thumbActualHgtObj == null ? 0 : (double) thumbActualHgtObj;
            final double ty = thumb.getTranslateY();
            final double sbHeight = scrollBar.getHeight();
            final double tyMax = sbHeight - thumbActualHgt;
            final double tH = sbHeight - THUMB_MIN_HEIGHT;
            thumb.setTranslateY(ty / tyMax * tH);

            /* Enabling the listeners */
            scrollBar.getProperties().remove(DISABLE_LISTENERS);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

出于演示目的,我在 TextArea、ScrollPane、ListView 和 TableView 上应用了此实用程序。请查看下面的演示。

设置 ScrollThumbSizing 之前:

在此输入图像描述

设置 ScrollThumbSizing (50px) 后:

在此输入图像描述

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class ScrollThumbSizing_Demo extends Application {
    @Override
    public void start(final Stage stage) throws Exception {
        GridPane root = new GridPane();
        root.setPadding(new Insets(10));
        root.setVgap(10);
        root.setHgap(10);
        ColumnConstraints columnConstraints = new ColumnConstraints();
        columnConstraints.setPercentWidth(100);
        root.getColumnConstraints().addAll(columnConstraints,columnConstraints);

        // TextArea
        TextArea textArea = new TextArea();
        textArea.setMinHeight(150);
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < 2000; i++) {
            builder.append("abc" + i).append(System.lineSeparator());
        }
        textArea.setText(builder.toString());

        // ListView
        ListView<String> listView = new ListView<>();
        for (int i = 0; i < 1000; i++) {
            listView.getItems().add("Item " + i);
        }

        // TableView
        TableView<String> tableView = new TableView<>();
        TableColumn<String, String> col = new TableColumn<>("Column");
        col.setCellValueFactory(p -> new SimpleStringProperty(p.getValue()));
        tableView.getColumns().add(col);
        for (int i = 0; i < 1000; i++) {
            tableView.getItems().add("T Item " + i);
        }

        // ScrollPane
        ScrollPane scrollPane = new ScrollPane();
        scrollPane.setMinHeight(150);
        StackPane content = new StackPane();
        content.setMinSize(100, 1500);
        content.setStyle("-fx-background-color:linear-gradient(to bottom, gray,red,yellow,green,pink,orange, white);");
        scrollPane.setContent(content);

        root.addRow(0, textArea, scrollPane);
        root.addRow(1, listView, tableView);
        Scene scene = new Scene(root, 400,350);
        stage.setScene(scene);
        stage.setTitle("ScrollThumbSizing Demo");
        stage.show();

        // You can add this before/after showing the stage.
        ScrollThumbSizing.enable(textArea);
        ScrollThumbSizing.enable(listView);
        ScrollThumbSizing.enable(tableView);
        ScrollThumbSizing.enable(scrollPane);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 很好:)想知道通过 CSS 设置拇指的最小值是否可行?(不在我的 IDE 附近,所以无法尝试;) (2认同)