当前位置: 首页 > 知识库问答 >
问题:

以编程方式编辑TreeView/TreeItem

李睿
2023-03-14

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

原始帖子:我有一个简单的UI,带有一个按钮和一个树状视图。如果按钮被按下,应该会有一个新的项目添加到树视图。此项一出现在树中就应可编辑。

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是JavaFXAPI的一部分。

如果我看看api-留档(TreeView#edit),我的网站上没有太多可做的事情。

我通过谷歌找到的许多例子都为每个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);
        }
    });
}

每个新项目都正确标记为编辑(已选择创建的文本字段及其内容)。使用平台。无线程运行。睡眠不起作用。睡不着也不迟。

这简直是不对的。我有什么问题?

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

共有2个答案

宣胜
2023-03-14

看起来,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中的其他bug直观地发现的;-)

或者,从平台开始。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();
萧宏峻
2023-03-14

TreeCell(这是它们的内容和绑定到treeItem)在布局传递中懒惰地更新,这在下一个脉冲触发时非常“晚”。Platform.run稍后(...)或任何硬编码延迟可能发生在该脉冲之前或之后,这(可能)就是为什么两者似乎都正常工作或不正常。

所以另一个疯狂的黑客是在添加新项目后,在以编程方式开始编辑之前,手动强制重新布局树:

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

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

 类似资料:
  • 问题内容: 我正在开发一个插件。 单击按钮时,我想调用Eclipse的save方法或调用Eclipse工具栏上的save按钮。 怎么做呢? 问题答案: 应该可以。 如果要保存活动的编辑器,请尝试 请注意,导航路径中的元素可以为null。

  • 我正在尝试为具有特定扩展名的文件在“打开”菜单中添加eclipse编辑器。我在org.eclipse.ui.editors扩展点中使用launcher实现了这一点,在launcher中我使用了“open editor”方法,它需要传递编辑器ID。有没有什么方法可以让我们以编程方式打开一个编辑器,而不需要传递编辑器ID呢?我们可以通过传递实现编辑器的类的实例以编程方式打开编辑器吗?..

  • 问题内容: 我有一个多层PSD,其中一个特定的层是非光栅化文本。我试图从bash / perl / python / whatever- else程序中找出一种可行的方法: 加载PSD 编辑所述图层中的文本 展平图像中的所有图层 另存为Web友好格式,如PNG或JPG 我立刻想到了ImageMagick,但是我认为我无法通过IM编辑文本层。如果我可以通过其他编程方式完成前两个步骤,则可以始终使用I

  • 问题内容: 我需要使用python编辑Excel工作簿。有没有这样做的方法,而无需阅读工作簿,编辑我想要的内容并将其写回?即有没有一种方法可以即时进行,因为我只需要在每张纸上编辑几个值? 我已经看过了,和,但他们似乎只支持(据我可以工作),阅读和写作不是编辑。我无法使用,因为我正在使用linux。 对库或特定的工作方式有何建议? 问题答案: xlutils有一个复制模块,可能会与您交错

  • 问题内容: 关闭。 此问题不符合堆栈溢出准则。它当前不接受答案。 想改善这个问题吗? 更新问题,使其成为Stack Overflow的主题。 2年前关闭。 改善这个问题 我需要使用python编辑Excel工作簿。有没有这样做的方法,而无需阅读工作簿,编辑我想要的内容并将其写回?即有没有一种方法可以即时进行,因为我只需要在每张纸上编辑几个值? 我已经看过了,和,但他们似乎只支持(据我可以工作),阅

  • 我已经编写了以下常规的、每次都可用的函数来显示和关闭键盘: |==|以编程方式显示和关闭键盘: 但问题是,当编辑文本位于键盘下方时,活动不会向上移动。仅当用户开始键入时,它才会移动。 那么,一旦键盘出现,我如何使它向上移动呢? 我浏览了下面的所有链接,没有任何帮助: Android:如何防止软键盘将我的视图向上推? adjustPan不阻止键盘覆盖编辑文本 Android:软键盘覆盖编辑文本(ad