在表格视图中的水平滚动条上方添加阴影

2024-01-07

我试图向我的用户表明,如果他们向下滚动,表中会有额外的数据,我想使用阴影效果来做到这一点。如何在水平滚动条上方添加阴影?


考虑到所有不同的条件,我能想到的解决此问题的一种方法是将节点包含到 TableView 的内部子级中。这样我就能更好的控制效果。

如果您可以使用查找方法并调整 TableView 的子项,那么您可以考虑以下方法:)。

总体思路是:

  • 我们将创建一个所需高度的窗格来显示效果。我使用窗格的背景颜色来更好地控制效果颜色、大小等。
  • 然后我们将该节点包含到包含 TableRows 的 Group 中。
  • 根据 TableView 视口的尺寸,我们定位该窗格。
  • 为了处理效果的可见性,我们访问虚拟滚动条并监听其可见性和滚动值。

总结以上所有内容,下面是一个展示阴影效果的快速演示。请注意,阴影不会与滚动条重叠,因为我们将窗格包含在保存 TableRows 的 Group 节点中。

UPDATE:我更新了下面的演示以包括FadeTransition以获得更平滑的阴影可见度。

import javafx.animation.FadeTransition;
import javafx.application.Application;
import javafx.beans.InvalidationListener;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ScrollBar;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;

public class TableViewShadowForScrollDemo extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        ObservableList<Person> persons = FXCollections.observableArrayList();
        for (int i = 0; i < 15; i++) {
            persons.add(new Person("Name " + i, "Last" + i, "City " + i));
        }

        TableColumn<Person, String> fnCol = new TableColumn<>("First Name");
        fnCol.setCellValueFactory(param -> param.getValue().firstNameProperty());

        TableColumn<Person, String> lnCol = new TableColumn<>("Last Name");
        lnCol.setCellValueFactory(param -> param.getValue().lastNameProperty());

        TableColumn<Person, String> cityCol = new TableColumn<>("City");
        cityCol.setCellValueFactory(param -> param.getValue().lastNameProperty());
        fnCol.setPrefWidth(150);
        lnCol.setPrefWidth(100);
        cityCol.setPrefWidth(200);

        MyTableView<Person> tableView = new MyTableView<>();
        tableView.getColumns().addAll(fnCol, lnCol, cityCol);
        tableView.setItems(persons);

        StackPane root = new StackPane(tableView);
        root.setPadding(new Insets(15));
        Scene scene = new Scene(root, 500, 300);
        primaryStage.setScene(scene);
        primaryStage.setTitle("TableView Scroll Shadow Demo");
        primaryStage.show();
    }

    class MyTableView<S> extends TableView<S> {
        private final double SHADOW_HEIGHT = 40;

        private Group sheet;

        private StackPane shade;

        private Rectangle clip;

        private BooleanProperty show;

        @Override
        protected void layoutChildren() {
            super.layoutChildren();
            // Ensuring that we set the configurations only once.
            if (sheet == null) {
                show = new SimpleBooleanProperty();
                // Create a pane for creating the shadow. I choose to use background-color instead of effect for better control of the effect.
                shade = new StackPane();
                shade.setMouseTransparent(true);
                shade.setStyle("-fx-background-color:linear-gradient(to top, #999999, transparent 70%, transparent);");

                // Access the Group node to which the shade has to be included.
                sheet = (Group) lookup(".sheet");
                final ObservableList<Node> sheetChildren = sheet.getChildren();
                sheetChildren.add(shade);
                // Ensure to always keep the shade on top of all table row nodes.
                sheet.needsLayoutProperty().addListener((obs, old, needsLayout) -> {
                    if (!needsLayout && sheetChildren.indexOf(shade) != sheetChildren.size() - 1) {
                        sheetChildren.remove(shade);
                        sheetChildren.add(shade);
                    }
                });

                // Get the clipped container for position calculations of the shade.
                Region clipCont = (Region) lookup(".clipped-container");
                clip = (Rectangle) clipCont.getClip();
                // Add listener to resize/reposition the shade, when ever the table dimensions are changed
                InvalidationListener listener = e -> {
                    shade.resize(sheet.getLayoutBounds().getWidth(), SHADOW_HEIGHT);
                    shade.setLayoutY(clip.getLayoutY() + clipCont.getHeight() - SHADOW_HEIGHT);
                };
                clipCont.widthProperty().addListener(listener);
                clipCont.heightProperty().addListener(listener);

                // Access the vertical scroll bar for deciding the visibility of the shade.
                ScrollBar vBar = (ScrollBar) lookup(".scroll-bar:vertical");
                FadeTransition fadeTransition = new FadeTransition(Duration.millis(500), shade);
                fadeTransition.setOnFinished(e -> shade.setVisible(show.get()));
                show.addListener((obs, old, val) -> {
                    if (val) {
                        shade.setVisible(true);
                    }
                    fadeTransition.setFromValue(val ? 0.0 : 1.0);
                    fadeTransition.setToValue(val ? 1.0 : 0.0);
                    fadeTransition.play();
                });
                show.bind(Bindings.createBooleanBinding(() -> vBar.isVisible() && vBar.getValue() < 1.0, vBar.visibleProperty(), vBar.valueProperty()));
            }
        }
    }

    class Person {
        private StringProperty firstName = new SimpleStringProperty();
        private StringProperty lastName = new SimpleStringProperty();
        private StringProperty city = new SimpleStringProperty();

        public Person(String fn, String ln, String cty) {
            setFirstName(fn);
            setLastName(ln);
            setCity(cty);
        }

        public String getFirstName() {
            return firstName.get();
        }

        public StringProperty firstNameProperty() {
            return firstName;
        }

        public void setFirstName(String firstName) {
            this.firstName.set(firstName);
        }

        public String getLastName() {
            return lastName.get();
        }

        public StringProperty lastNameProperty() {
            return lastName;
        }

        public void setLastName(String lastName) {
            this.lastName.set(lastName);
        }

        public String getCity() {
            return city.get();
        }

        public StringProperty cityProperty() {
            return city;
        }

        public void setCity(String city) {
            this.city.set(city);
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在表格视图中的水平滚动条上方添加阴影 的相关文章

  • 将 JavaFX FXML 对象分组在一起

    非常具有描述性和信息性的答案将从我这里获得价值 50 声望的赏金 我正在 JavaFX 中开发一个应用程序 对于视图 我使用 FXML
  • 即使在轴上进行自动量程调整,我也可以保留积分刻度线吗?

    我 偷 了一些代码here http fxexperience com 2012 01 curve fitting and styling areachart 拥有一个AreaChart我在 FXML 中使用了 平滑线条 它的工作原理如下
  • 删除 JFX 中选项卡后面的灰色背景

    So is there any way to remove the gray area behind the tab s 我尝试过用 CSS 来做到这一点 但没有找到方法 要设置 tabpane 标题的背景颜色 请在 CSS 文件中写入 t
  • 如何从 JavaFX 中的另一个控制器类访问 UI 元素?

    我有一个使用 NetBeans 8 编写的 JavaFX Java 8 应用程序 没有SceneBuilder 我的应用程序有一个主窗口 该窗口有自己的 FXML 文件 primary fxml 和自己的控制器类 FXMLPrimaryCo
  • Javafx 组合框不会在实时更改时更新下拉列表大小?

    我正在使用 Javafx v8 0 25 b18 我出现的问题是动态组合框的下拉列表的大小不会改变 所以如果我最初在下拉列表中有两个项目 那么下拉列表大小将适合两个项目 但如果我现在用以下内容填充动态组合框三个项目 然后我在里面得到一个小滚
  • 使用多个值过滤 JFX TableView

    我目前正在尝试过滤我的数据TableView using FilteredList with predicate 我有2个ComboBoxes来过滤值 我的表包含Result Each Result has a Student that S
  • 错误:缺少 JavaFX 运行时组件,并且需要使用 Gradle 示例来运行此应用程序

    我知道这个问题已被问过多次 但我似乎找不到解决方案 摘自官方指南示例 https openjfx io openjfx docs gradle https openjfx io openjfx docs gradle我继续添加了我的构建 g
  • 从 MS Access 中提取 OLE 对象(Word 文档)

    我有一个 Microsoft Access 数据库 其中包含一个包含 Microsoft Word 文档的 OLE 对象字段 我试图找到代码来检索保存在 OLE 对象中的文件 以便用户可以从我的 JavaFx 应用程序中的按钮下载它 但没有
  • JavaFX颜色选择器的语言

    有没有办法改变语言ColorPicker的文本 例如 自定义颜色 当前颜色 新颜色 色相 饱和度 亮度 不透明度 保存 使用 取消 编辑 以下答案适合那些需要更多内容的人exotic语言 如果您使用其中之一 de es fr it ja k
  • JavaFX 动画使用循环?

    我正在尝试制作一款类似太空侵略者的游戏 我画了一个正方形 我想通过使用循环逐步向下移动它thread sleep 然而 正方形立即被绘制出来 我知道有可以使用的动画路径 但我想保持低水平并仅使用坐标系 有没有办法使用这样的循环来制作时间轴动
  • JavaFX 8 默认消息图标

    随着 JavaFX 的最近几次更新 我们收到了警报 我想获取消息的默认图标 错误 警告 在Swing中 我可以通过一些方式获取L F消息图标UIManager的属性 如何在 JavaFX 中获取消息的默认图标 它们是包含在属性中 还是由 C
  • JavaFX 中的 MVC 模式与场景生成器

    我是 JavaFX 新手 根据我当前的设置 正在努力创建合适的 MVC 架构 我使用 Scene Builder 单击了一个 UI 并指定了一个 Controller 类 Startup public class Portal extend
  • mobileapplication.mobileevent BACK_BUTTON_PRESSED

    我的两个视图中有 2 个 Android 本机音频实例 当用户按下后退按钮并离开视图时 我试图让音频停止 因为它不会自动发生 我查看了文档并看到了 MobileEvent 类 我尝试实现它的构造函数 但没有成功 这是我的第一个应用程序 为此
  • 场景生成器删除 fxml 文件中的导入

    我使用场景构建器 Gluon Scene Builder JavaFX Scene Builder 8 1 1 来创建应用程序的 UI 并使用 Eclipse 开发 JavaFX 现在 每次我在场景生成器中保存某些内容时 它都会从 fxml
  • 错误:无法初始化主类 FileChooser_1 原因:java.lang.NoClassDefFoundError:阶段 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我在这里编写了以下代码 我无法运行该程序 并且不断出现下面提到的错误 我尝试了很多可能的解决方案 但都是徒劳 import java
  • JavaFX - 如何从另一个控制器使用一个控制器中的方法?

    使用场景构建器 我有 2 个阶段 每个阶段都有一个控制器 stage1Controller stage2Controller Stage1控制器 public class Stage1Controller FXML private Menu
  • JavaFX 应用程序隐藏 OSX 停靠图标

    我需要隐藏 javafx 应用程序的停靠图标 在普通的 java 应用程序中 这可以通过以下属性来实现 System setProperty apple awt UIElement true 然而 这似乎不适用于 JavaFX Thanks
  • 如何平滑拖动JavaFX多边形?

    我有一个多边形 三角形 我想让它可以用鼠标拖动 下面是我尝试过的代码 但是使用此代码我无法顺利拖动它 请让我知道如何才能使其顺利拖动 public void start Stage primaryStage throws Exception
  • JavaFX 拖放无法正常工作

    我在网格窗格中使用两个 Imageview 进行拖放测试 我的问题是 当我完成拖放并将目标图像视图移动到源图像视图并释放鼠标时 我错误地最终显示了 img2 中的图片 而不是 img1 中的图片 当我注释掉 setOnDragExited
  • Javafx过滤表视图

    我正在尝试使用文本字段来过滤表视图 我想要一个文本字段 txtSearch 来搜索 nhs 号码 名字 姓氏 和 分类类别 我尝试过在线实施各种解决方案 但没有运气 我对这一切仍然很陌生 所以如果问得不好 我深表歉意 任何帮助将不胜感激 我

随机推荐

  • Gmail 附件和自定义扩展程序

    我目前正在开发一个 Android 应用程序 该应用程序读取具有自定义扩展名的文件 其中一项强制性功能是 当用户收到带有附件 our 扩展名的邮件时 该应用程序必须由 Gmail 推荐 我做了一些研究 发现Android上的gmail客户端
  • 使用 youtube-dl 将 YouTube 下载到 mp3 并将元数据(艺术家/歌曲标题)写入 mp3 文件

    我只使用 YouTube 视频提取音频youtube dl 我想在下载后将元数据 即艺术家姓名和歌曲标题 写入mp3文件中 我尝试从以下代码开始实现此目的 echo off set dl https www youtube com watc
  • Swift Firebase 身份验证在另一个课程中不起作用

    我正在尝试一个项目只是为了好玩 我想使用 Firebase 我为用户创建了一个类来处理用户相关的事情 我正在测试注册功能 当它在一个类中时 它首先产生 false 然后产生 true 但是 当我不将其放置在单独的类中并将其直接放置在视图控制
  • 如何从数据框创建矩阵?

    我有一个数据框如下 我想创建一个矩阵 其中根据3个招聘地点 site 和5个招聘年份 year 显示平均睡眠持续时间 SLP SLP site year 8 6 1 2008 7 2 1 2005 6 4 2 2006 9 5 3 2007
  • 如何在 Javascript 中创建异步函数?

    看看这个code http jsfiddle net 5H9XT 5 a href Link a span Moving span link click function console log Enter link animate wid
  • python-keyring 在 Windows 上是如何实现的?

    python keyring 如何在 Windows 上提供安全性 在 Linux 上的 GNOME KDE 中 系统会提示用户输入密码以授权对每个应用程序访问密钥环 在Windows中 当应用程序访问密钥环时 没有这样的提示 是什么阻止随
  • 如何在symfony2中获取请求的路径

    我知道方法 Symfony Component HttpFoundation Request getPathInfo 但是在文档中它指出 这只返回与 执行脚本 相对 的请求路径 我怎样才能获得完整路径 第二个注意点是 执行脚本 是什么意思
  • 从 http:// 重定向到 https:// [重复]

    这个问题在这里已经有答案了 我想将用户从我的 http 网站重定向到 https 网站 是否有像元或 JavaScript 或 html 那样的元或 JavaScript 或 html 来执行此操作 我的网站有一个 http 服务器以及一个
  • 使用 Apache Commons CSV 从带有标头的 HashMap 列表写入 CSV

    我必须采取ArrayList of HashMap并使用 Apache Commons CSV 创建 CSV 但是 它没有将值写入正确的标头 有没有一种简单的方法可以让库使用枚举自动将值放置到正确的标题中 我不想手动分配它 因为我将添加更多
  • 如何将 xml 属性添加到 jaxb 带注释的类 XmlElementWrapper?

    我有一个带有 XmlElementWrapper 注释的类 例如 XmlElementWrapper name myList XmlElements XmlElement name myElement private List
  • JSP 表达式中的 if-then-else?

    您可以在 JSP 表达式中执行 if then else 语句吗 EDIT 具体来说 我正在寻找 JSP 解决方案 而不是 JSTL 解决方案 但下面的一些 JSTL 解决方案受到高度评价并且非常受欢迎 只是请不要因为重复的问题而投票否决我
  • 红宝石非空?方法

    我想使用表达式 1 2 3 43 5 empty gt false 1 2 3 3 5 empty gt true 检查两个数组是否至少包含一个公共值 我想知道是否有更好的方法 也许是这样的 1 2 3 3 5 non empty 怎么写n
  • OpenCV:像 matlab 中那样的 randn() 生成器

    我正在寻找最好的解决方案来生成 在OpenCV中 一个平均值为0 方差为1的随机数矩阵 2xN 就像函数一样randn 在Matlab中 有一个randn OpenCV 库中的函数 但我不知道如何将参数传递给该函数以生成均值 0 和方差 1
  • 如何使用 F# 中的类型提供程序连接到 SQL Server Compact Edition 4.0?

    我正在尝试从 F 连接到 SQL Server Compact Edition 数据库 并尝试使用类型提供程序 这是在 Visual Studio 11 Beta 中 所以我意识到可能会因此出现问题 但我认为更有可能的是我还不具备相关知识
  • Gradle 项目同步失败。基本功能(例如编辑、调试)在 android studio 1.0.1 中无法正常工作

    我已经开始使用 Android Studio 1 0 1 但我无能为力 因为出现此错误 甚至无法呈现 XML 错误 无法启动守护进程 此问题可能是由于守护程序配置不正确造成的 例如 使用了无法识别的 jvm 选项 请参阅有关守护进程的用户指
  • 预填充的数据库在 API 28 上不起作用,会抛出“没有这样的表”异常

    我在我的项目中使用预先填充的数据库 我创建了一个 sql 库并在第一次启动时复制它 该库有 33mb 大 private void copyDataBase throws IOException InputStream externalDb
  • 阅读不使用 automodule 的文档

    我已经为我的项目编写了一些文档 在 Python 文档字符串中 并在我的本地计算机上使用 Sphinx 测试了所有内容 一切正常 所有导入工作正常等等 所以我在阅读文档上设置了一个自定义环境 Python 3 numpydoc和我的图书馆
  • ios7 新的平移手势返回导航堆栈不会清除桌面视图选择

    我有一个类似注释的应用程序 uitableviewcontroller 通过将各个注释推送到导航堆栈来显示它们 我决定使用 ios7 后退按钮和附带的平移手势识别器 我唯一的修改是在推送详细视图控制器之前 通过将来自控制器的 navigat
  • 如何消除无子节点的递归 AJAX 请求?

    Problem 据作者称 jsTree 文档 http www jstree com documentation json data 当打开一个关闭的节点 没有加载的子节点 时 会发出 AJAX 请求 我该如何配置jsTree摆脱对每个空
  • 在表格视图中的水平滚动条上方添加阴影

    我试图向我的用户表明 如果他们向下滚动 表中会有额外的数据 我想使用阴影效果来做到这一点 如何在水平滚动条上方添加阴影 考虑到所有不同的条件 我能想到的解决此问题的一种方法是将节点包含到 TableView 的内部子级中 这样我就能更好的控