JavaFX TableView scrollTo() 导致错误的行开始编辑

2024-03-15

我有一个可编辑的 TableView,其中有一个按钮添加新行,然后在该行的第一列上调用 table.edit() 。当用户想要添加不在视口之外的行时,应该发生的情况是表格在视口内滚动新行并开始编辑。但是,调用 table.scrollTo(newRow) 会导致各种错误行为。该行已进入视图,但只有部分时间进行编辑。最常见的情况似乎是视口中的第一行开始编辑,而不是新添加的行。这种情况发生在将添加到视图中的行以及将不在视图中的行上。

My code:

import javafx.application.Application;
import javafx.application.Platform;
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.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;


public class TableViewScrollToTest extends Application {

    private final TableView<Person> table = new TableView<>();
    private final ObservableList<Person> data = FXCollections.observableArrayList();
    private final HBox hb = new HBox();
    private final Button addButton = new Button("_Add");
    private int seq = 0;

    @Override
    public void start(Stage primaryStage) throws Exception {
        Scene scene = new Scene(new Group());
        primaryStage.setTitle("Table View Scroll To Test");
        primaryStage.setWidth(450);
        primaryStage.setHeight(300);

        table.setEditable(true);

        TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
        firstNameCol.setMinWidth(100);
        firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));
        firstNameCol.setCellFactory(TextFieldTableCell.<Person> forTableColumn());
        firstNameCol.setOnEditCommit((CellEditEvent<Person, String> event) -> {
            event.getRowValue().setFirstName(event.getNewValue());
        });

        TableColumn<Person, String> lastNameCol = new TableColumn<>("Last Name");
        lastNameCol.setMinWidth(100);
        lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));
        lastNameCol.setCellFactory(TextFieldTableCell.<Person> forTableColumn());
        lastNameCol.setOnEditCommit((CellEditEvent<Person, String> event) -> {
            event.getRowValue().setLastName(event.getNewValue());
        });

        TableColumn<Person, String> emailCol = new TableColumn<>("Email");
        emailCol.setMinWidth(200);
        emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email"));
        emailCol.setCellFactory(TextFieldTableCell.<Person> forTableColumn());
        emailCol.setOnEditCommit((CellEditEvent<Person, String> event) -> {
            event.getRowValue().setEmail(event.getNewValue());
        });

        table.setItems(data);
        table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
        table.setPrefHeight(165);

        addButton.setOnAction(event -> {
            table.getSelectionModel().clearSelection();
            Person p = new Person("First Name", "Last Name " + seq++, "");
            data.add(p);
            table.getSelectionModel().select(p);
            Platform.runLater(() -> {
                table.scrollTo(p); //causes buggy behavior
                table.edit(data.indexOf(p), firstNameCol);
            });
        });

        hb.getChildren().add(addButton);

        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 0, 0, 10));
        vbox.getChildren().addAll(table, hb);

        ((Group)scene.getRoot()).getChildren().addAll(vbox);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static class Person {

        private StringProperty firstName;
        private StringProperty lastName;
        private StringProperty email;

        public Person(String first, String last, String email) {
            firstName = new SimpleStringProperty(this, "firstName", first);
            lastName = new SimpleStringProperty(this, "lastName", last);
            this.email = new SimpleStringProperty(this, "email", email);
        }

        public void setFirstName(String value) { firstNameProperty().set(value); }
        public String getFirstName() { return firstNameProperty().get(); }
        public StringProperty firstNameProperty() { 
            if (firstName == null) firstName = new SimpleStringProperty(this, "firstName", "First");
            return firstName; 
        }

        public void setLastName(String value) { lastNameProperty().set(value); }
        public String getLastName() { return lastNameProperty().get(); }
        public StringProperty lastNameProperty() { 
            if (lastName == null) lastName = new SimpleStringProperty(this, "lastName", "Last");
            return lastName; 
        } 

        public void setEmail(String value) { emailProperty().set(value); }
        public String getEmail() { return emailProperty().get(); }
        public StringProperty emailProperty() {
            if(email == null) {
                email = new SimpleStringProperty(this, "email", "");
            }
            return email;
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

如果您注释掉 table.scrollTo(),添加然后编辑该行效果很好。我试过https://stackoverflow.com/a/27786741/3050379 https://stackoverflow.com/a/27786741/3050379但 isIndexVisible() 有时会返回 false,即使添加的行在视图中也是如此。我已经尝试了我能想到的方法调用和可运行程序的顺序的每种组合,但都得到了相同的结果。如果有人可以帮助我,我将非常感激。


完全随机的黑客似乎有效,尽管我对此没有任何解释:

    table.scrollTo(p); 
    table.layout();
    table.edit(data.indexOf(p), firstNameCol);

你不需要Platform.runLater(...)有了这个。我会提交错误 https://javafx-jira.kenai.com/secure/Dashboard.jspa不过,为此,随机黑客应该是不必要的......

这是受到 Uluk Biy 的回答的启发这个问题 https://stackoverflow.com/questions/30052685/recreate-bar-chart-without-it-remembering-data

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

JavaFX TableView scrollTo() 导致错误的行开始编辑 的相关文章

随机推荐

  • json_encode() 返回 false

    这是我第一次面对数组结果布尔值的 var dumping json encode 我有一个由反序列化产生的数组 我 var dumped 它并确保它是一个有效的数组 结果如下 这只是一部分 而不是整个调试视图 array size 3 id
  • 如何直接访问azure应用程序服务实例

    我是天蓝色的新手 我有一个 Asp Net MVC 应用程序托管在 azure 应用程序服务 上 有两个实例 我的应用程序使用本地缓存 有时我需要清除这个缓存 但问题是 当我清除缓存时 我实际上只针对一个特定实例执行此操作 而其他实例仍然保
  • Symfony2创建服务[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 symfony2 文档中曾经有关于如何创建服务 my mailer 的操作方法 但我似乎无法在任何地方
  • MySQL 8.0.11 由于 caching_sha2_password 连接错误

    当我尝试连接到 MySQL Workbench 上的服务器时 收到错误消息 您的连接尝试无法以 localhost 3306 身份从主机到服务器的用户 root 认证插件caching sha2 password无法加载 指定的模块无法找到
  • WiX 安装程序:使用 xslt 和 heat.exe 来更新属性

    我正在尝试为 Windows 服务创建 WiX 安装程序 并且我读到需要将所有文件的 KeyPath 设置为 no WiX 脚本中的 exe 除外 我目前正在使用 Heat exe 生成目录和文件结构 这是我的命令 WIX bin heat
  • 绘制路径大于最大位图尺寸

    我想画一条比canvas getMaximumBitmapWidth and or canvas getMaximumBitmapHeight 在可缩放的视图内 特别是在较旧的设备 Android 9 及更早版本 上 这会导致 路径太大而无
  • 当标签已存在于远程时​​,Git 强制推送标签

    我已经将标签推送到遥控器上 当另一个用户创建相同的标签并尝试推送时 推送将失败 因为该标签已存在于远程上 但我想如果我这么做了 f force tag push 它应该可以工作 但我所看到的并非如此 我想我必须这样做 Create tag
  • 是否应该迁移变更集的用户名和时间戳?

    以下文字关于OpsHub 迁移实用程序页面 https visualstudiogallery msdn microsoft com 28a90a17 d00c 4660 b7ae 42d58315ccf2表示用户名和时间戳将嵌入到迁移的变
  • 在 BIDS 中使用存储过程作为 OLE DB 源

    我正在测试 SSIS 包和存储过程 因为我只是一个初学者 我需要做的是使用在源数据库上安装的存储过程来返回数据集 然后我需要一个 ssis 包来使用存储过程返回的数据集作为 OLE DB 源来填充第二个目标表 基本上我有两张桌子 测试源 测
  • 可变参数模板的可扩展性

    我正在使用 C 11 开发一个大规模软件基础设施 该基础设施广泛使用了可变参数模板 我的问题如下 这种方法的可扩展性如何 首先 可变参数模板可以采用的参数数量是否有上限 其次 当使用许多参数时 并且 通过扩展 这些参数的许多组合将产生模板化
  • 在 Java 中用 Scala 中的 Option 包装返回 null 的方法?

    假设我有一个方法session get str String String但你不知道它会返回一个字符串还是一个 null 因为它来自 Java 在 Scala 中是否有更简单的方法来处理这个问题而不是session get foo null
  • 客户端加密的有效用例有哪些?

    我刚刚读到斯坦福大学 Javascript 加密库 http crypto stanford edu sjcl jsfiddle 示例 http jsfiddle net kRcNK 它完全用 JavaScript 支持 SHA256 AE
  • DICOM 和图像位置患者

    我试图弄清楚 DICOM 图像位置 0020 0032 是绝对坐标还是只是我拥有的任何切片方向的坐标 例如 我有两个平面 一个矢状平面和一个冠状平面 与 DICOM 标头中的 x y z 形式的相应图像位置 以毫米为单位 交错 我的问题是
  • 应用内结算,签名验证失败

    当我尝试获取订阅时 出现以下错误 签名认证失败 签名与数据不匹配 应用内结算警告 购买签名验证FAILED 不添加项目 我的代码是 String base64EncodedPublicKey MY KEY compute your publ
  • 我如何判断给定的 hWnd 是否仍然有效?

    我正在使用生成 Internet Explorer 实例的第三方类 该类有一个属性 hWnd 它返回进程的 hWnd 稍后 我可能想重用应用程序的实例 如果它仍然存在 因此我需要告诉我的帮助器类附加到它 在此之前 我想知道给定的 hWnd
  • 为什么我们需要绑定 std::cin 和 std::cout?

    默认情况下 标准输入设备与标准输出设备以以下形式绑定在一起 std cin tie std cout 这保证了在调用输入之前输出缓冲区已被刷新 所以我尝试使用来解开它们std cin tie 0 但看起来 结果 与并列的没有什么区别 inc
  • 如何使用另一个反应性对象 (ref) 的值设置反应性对象 (ref) 的值?

    我正在尝试设置 a 的值Form基于另一个反应变量中的数据 称为Product但它似乎不起作用 这Form应将其值设置为Product数据如果可用 如果不可用 则使用null 这是vue组件代码的一部分 props ProductID ty
  • CSS 动态创建列

    我有三个 div 要素 div class foo A div div class foo B div div class foo C div 期望的行为 我想编写一些CSS来随着屏幕尺寸的变化创建以下效果 不良行为 我知道如何实现以下 不
  • 如何增加数组的长度

    我有一个快速的问题 我在 java 中有一个整数数组 它的长度需要在整个类中变化 具体来说 我需要在某些情况下将其增加一 我这样尝试过 sbgHeadX new int numberOfSBG 当我需要时 我会增加整数变量 numberOf
  • JavaFX TableView scrollTo() 导致错误的行开始编辑

    我有一个可编辑的 TableView 其中有一个按钮添加新行 然后在该行的第一列上调用 table edit 当用户想要添加不在视口之外的行时 应该发生的情况是表格在视口内滚动新行并开始编辑 但是 调用 table scrollTo new