当我使用一些包含滚动条的组件时,例如TextArea、ListView和ScrollPane,当内容很长时,滚动条的拇指会变得很小。如何设置拇指的最小长度?
现阶段没有直接的方法来限制拇指的大小。
但通过一些小小的调整,您可以获得所需的行为;-)。如果您可以使用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)
| 归档时间: |
|
| 查看次数: |
64 次 |
| 最近记录: |