【问题标题】:Programmatically edit TreeView/TreeItem以编程方式编辑 TreeView/TreeItem
【发布时间】:2015-07-03 23:29:52
【问题描述】:

编辑#2:因为它看起来像一个错误,我已经在javaFx-jira 中发布了一个错误报告。您必须拥有一个帐户才能访问该问题。如果有新信息,我会及时更新这篇文章。

原帖: 我有一个带有按钮和 TreeView 的简单 UI。如果按钮被按下,则应向 TreeView 添加一个新项目。该项目一出现在树中就应该是可编辑的。

import javafx.fxml.FXML;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.control.cell.TextFieldTreeCell;
import javafx.util.converter.DefaultStringConverter;

public class ClientController {

    @FXML
    private TreeView<String> tree;

    public void initialize() {
        tree.setEditable(true);
        tree.setCellFactory(p -> new TextFieldTreeCell<>(new DefaultStringConverter()));

        TreeItem<String> root = new TreeItem<>();
        root.setValue("Items");
        root.setExpanded(true);

        tree.setRoot(root);
    }

    @FXML
    public void createItem() {
        TreeItem<String> newItem = new TreeItem<>();
        newItem.setValue("Item " + tree.getExpandedItemCount());

        tree.getRoot().getChildren().add(newItem);
        tree.requestFocus();
        tree.getSelectionModel().select(newItem);
        tree.edit(newItem);
    }
}

我使用的 CellFactory 是part of the JavaFX api

如果我查看 api 文档 (TreeView#edit),我的网站上没有太多可做的。

我通过 google 找到的许多示例(例如 this)为每个 TreeItem 创建了一个上下文菜单。有用,但不是我现在想要的。

如果我在 UI 中选择/双击该项目,我可以编辑任何以前创建的和现有的 TreeItem。我错过了什么吗?

编辑#1:

如果 createItem 方法更改为以下代码:

@FXML
public void createItem() throws InterruptedException {
    TreeItem<String> newItem = new TreeItem<>();
    newItem.setValue("Item " + this.tree.getExpandedItemCount());

    this.tree.getRoot().getChildren().add(newItem);
    this.tree.requestFocus();
    this.tree.getSelectionModel().select(newItem);
    Thread.sleep(100);
    Platform.runLater(new Runnable() {
        @Override
        public void run() {
            SimpleController.this.tree.edit(newItem);
        }
    });
}

每个新项目都被正确标记为编辑(创建的文本字段及其内容被选中)。 在没有 Thread.sleep 的情况下使用 Platform.runLater 不起作用,而在没有 runLater 的情况下使用 Thread.sleep 也不行。

这根本感觉不对。我的问题是什么?

我提供了一个非常小的示例(eclipse)项目: https://www.dropbox.com/s/duos0ynw4rqp3yn/Test.zip?dl=0 包含主方法、FXML 文件和“有问题的”控制器。

【问题讨论】:

  • 啊。现在我发布了我的问题,突然间我在stackoverflow 上发现了另一个(遗憾的是没有回答)问题
  • 对我来说似乎是一个错误 - 您可以考虑报告它,以便有机会修复它
  • @kleopatra 恐怕你是对的。我会在 JavaFX Jira 平台上做一些研究,如果在那里找不到帮助,我可能会提交一个错误。

标签: java treeview javafx-8


【解决方案1】:

TreeCells(即它们的内容和与 treeItem 的绑定)在布局过程中延迟更新,这在下一个脉冲被触发时非常“迟”。 Platform.runLater(..) 或任何硬编码的延迟都可能在该脉冲之前或之后发生,这(可能)这就是为什么两者似乎都可以正常工作或不正常工作的原因。

因此,另一个奇怪的技巧是在添加新项目之后和以编程方式开始编辑之前手动强制在树上重新布局:

root.getChildren().add(newItem);
tree.layout();
tree.edit(newItem);

不用说,这不应该是必要的 - 当前行为是一个严重的错误,必须立即修复(......意思是...... jdk 9)

【讨论】:

  • 这个答案使睡眠和 PauseTransition 变得不必要。有用。谢谢。如果我找不到任何类似的错误,我将很快在 JavaFX-Jira 上报告一个新错误。
  • 太棒了。五年或更长时间后,使用 JavaFX 13,我仍然觉得这是必要的。您还会将其定性为“严重错误”吗?还是背后有某种设计原理?
  • @mikerodent 好问题 - 回答像 Radio eriwan 是的,但是... ;) 从我的头顶(最近没有检查)但是分支的意思是,似乎没有任何简单的(有点轻描淡写;) - 出路:在布局期间进行布局是一种(坏的,IMO)习惯,与整体设计深度交织,改变那将是太大的风险。顺便说一句:tree.refresh 会有所帮助(与布局相比)吗?
【解决方案2】:

看起来,treeView 需要更多时间来进行内部计算,然后新添加的项目才会反映到它上面。要准确确定是哪些计算导致了问题,需要深入挖掘源代码并查看幕后情况。

解决方法是强制 treeView 立即进行计算,

@FXML
public void createItem() throws InterruptedException {
    TreeItem<String> newItem = new TreeItem<>();
    newItem.setValue("Item " + tree.getExpandedItemCount());

    tree.getRoot().getChildren().add(newItem);

    // Trigger whatever calculations there internally
    TreeItem<String> r = tree.getRoot();
    tree.setRoot( null );
    tree.setRoot( r );

    tree.requestFocus();
    tree.getSelectionModel().select(newItem);
    tree.edit(newItem);
}

这个解决方法是基于 JavaFX 中的其他错误完全直观地发现的 ;-)


或者,由于Platform.runlaters的延迟时间显然不够,你可以使用PauseTransition增加所需时间:

PauseTransition p = new PauseTransition( Duration.millis( 100 ) );
p.setOnFinished( new EventHandler<ActionEvent>()
{
    @Override
    public void handle( ActionEvent event )
    {
        tree.edit( newItem );
    }
} );
p.play();

【讨论】:

  • Platform.runLater 的文档说明调用将在“某个未指定的时间”发生。这也是我所经历的。非常罕见的是它自己与 runLater 一起工作。通过使用 PauseTransition,UI 保持响应,但由于我必须对时间进行硬编码,因此转换将等待可能有一些机器仍然不够。不是说糟糕的用户体验。由于它仍然不是我问题的正确答案,我将推迟接受。我会看看 FX-Jira 平台。
  • @UlukBiy 因为这更“丑陋”,然后直接强制布局我选择 kleopatras 答案而不是你的。尽管如此,它仍在工作。所以我也 +1。
猜你喜欢
  • 1970-01-01
  • 2020-10-16
  • 2010-09-21
  • 1970-01-01
  • 1970-01-01
  • 2013-04-23
  • 2014-01-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多