【问题标题】:Completely Hiding or Disabling Horizontal Scrollbar in JavaFX TableView在 JavaFX TableView 中完全隐藏或禁用水平滚动条
【发布时间】:2019-06-26 08:29:49
【问题描述】:

我知道还有其他关于此的帖子,但这不是重复的。

如果我使用以下代码隐藏 TableView 中的水平滚动条,表格底部仍有 1 或 2 个像素区域,用户可以从中水平滚动 TableView --- 使用鼠标滚轮 ( SHIFT+鼠标滚轮也可以在表格区域的任何位置使用)。

.table-view *.scroll-bar:horizontal *.increment-button,
.table-view *.scroll-bar:horizontal *.decrement-button {
    -fx-background-color: null;
    -fx-background-radius: 0;
    -fx-background-insets: 0;
    -fx-padding: 0;
}

.table-view *.scroll-bar:horizontal *.increment-arrow,
.table-view *.scroll-bar:horizontal *.decrement-arrow {
    -fx-background-color: null;
    -fx-background-radius: 0;
    -fx-background-insets: 0;
    -fx-padding: 0;
    -fx-shape: null;
}

我尝试了一些反射技巧来访问滚动条并尝试以这种方式禁用它,但没有成功。有人有想法吗?

编辑 - 这是一个最小的例子,对我来说,它总是可以在 Win 10、JavaFX 12.0.1 上重现。

Test.java:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 * Horizontal scrolling via mouse wheel is possible when you place the cursor at the bottom of the window, just above the resize-area.
 */
public class Test extends Application {

    @Override
    public void start(Stage primaryStage) {
        TableView<String> table = new TableView<>();

        table.getColumns().add(new TableColumn<>("first"));
        table.getColumns().add(new TableColumn<>("second"));
        table.getColumns().add(new TableColumn<>("third"));
        table.getColumns().add(new TableColumn<>("fourth"));
        table.getColumns().add(new TableColumn<>("fifth"));
        table.getColumns().add(new TableColumn<>("sixth"));
        table.getColumns().add(new TableColumn<>("seventh"));
        table.getColumns().add(new TableColumn<>("eighth"));
        table.getColumns().add(new TableColumn<>("ninth"));
        table.getColumns().add(new TableColumn<>("tenth"));

        table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

//        table.addEventFilter(ScrollEvent.ANY, Event::consume);

        ObservableList<String> data = FXCollections.observableArrayList();
        for (int i = 0; i < 5000; i++) {
            data.add("foobar");
        }
        table.setItems(data);

        StackPane root = new StackPane();
        root.getChildren().add(table);

        Scene scene = new Scene(root, 300, 250);

        scene.getStylesheets().add("test.css");

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        Application.launch(Test.class);
    }
}

Test.CSS:

.table-view .scroll-bar * {
    -fx-min-width: 0;
    -fx-pref-width: 0;
    -fx-max-width: 0;

    -fx-min-height: 0;
    -fx-pref-height: 0;
    -fx-max-height: 0;
}

【问题讨论】:

  • table.addEventFilter(ScrollEvent.ANY, Event::consume); 确实有效。但是我不想禁用垂直滚动,getDeltaX() 总是返回 0,因此 TableView 仍然可以通过底部的 1 个像素水平滚动。
  • 我的答案中的 CSS 应该删除滚动条的所有痕迹(目前是水平和垂直的,但您可以通过指定适当的伪类来更改它)。
  • 我也尝试了您的 CSS,但问题仍然存在:底部仍有 1 个像素区域可供用户通过鼠标滚轮滚动。它也可以通过鼠标滚轮垂直滚动——从任何地方——即使没有显示滚动条。
  • 您能否添加minimal reproducible example,可能带有显示问题的 GIF?我正在使用 JavaFX 12.0.1(在 Windows 10 上),但似乎无法重现该问题,尽管我可能只是想念它。

标签: javafx


【解决方案1】:

如果你不想使用 css 解决方案,那么你可以这样做

public static <T extends Control> void removeScrollBar(T table) {
        ScrollBar scrollBar = (ScrollBar) table.queryAccessibleAttribute(AccessibleAttribute.HORIZONTAL_SCROLLBAR);
        /*
         *This null-check is for safety reasons if you are using when the table's skin isn't yet initialized.
         * If you use this method in a custom skin you wrote, where you @Override the layoutChildren method,
         * use it there, and it should be always initialized, so null-check would be unnecessary.
         *
         */
        if (scrollBar != null) {
            scrollBar.setPrefHeight(0);
            scrollBar.setMaxHeight(0);
            scrollBar.setOpacity(1);
            scrollBar.setVisible(false); // If you want to keep the scrolling functionality then delete this row.
        }
    }

【讨论】:

  • 这解决了这个问题,但直到我也打电话给scrollBar.setMouseTransparent(true); 谢谢。
猜你喜欢
  • 2014-12-30
  • 1970-01-01
  • 2012-09-22
  • 1970-01-01
  • 2013-04-23
  • 1970-01-01
  • 2017-06-26
  • 2018-12-10
  • 1970-01-01
相关资源
最近更新 更多