【问题标题】:Why isn't a TreeView root shown in this FXML app?为什么此 FXML 应用程序中不显示 TreeView 根?
【发布时间】:2025-12-01 13:50:01
【问题描述】:

我正在开发一个 FXML 应用程序,我遇到了这个我无法解决的错误:附加代码生成的 TreeViews 不显示它们的根,尽管据我所知它们应该(TreeViews自己确实显示)。按钮和标签工作正常。

另外,initialize() 方法到底应该做什么?目前,我只是在其中写一些东西,就像他们在教程中所做的那样,并希望它以某种方式出现。关于该方法,我发现的只是 Initializable 接口上的文档,这并没有让我变得更聪明。关于位置和资源的一些东西,但就 Java 而言,这到底意味着什么?这些术语过于笼统,无法通过 Google 搜索。

此外,代码是从仅使用 Javafx 的早期应用程序复制过来的,没有 FXML,并且在那里运行良好。那为什么现在不行呢?

    package sample;

import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;

import java.io.IOException;

public class FolderSyncerMainWindowController {

    final String FOLDER_SYNCER = "FolderSyncer";
    final String BROWSE = "Browse";
    final String SOURCE = "Source...";
    final String TARGET = "Target...";
    final String COMPARE = "Compare";
    final String CANCEL = "Cancel";
    final String SYNCHRONIZE = "Synchronize";
    final String COMPARING = "Comparing, this may take several minutes.";
    final String SYNCHRONIZING = "Synchronizing, this may take several minutes.";
    final String DONE = "Done.";


    @FXML
    private Label sourceLabel;
    @FXML
    private Label targetLabel;
    @FXML
    private Button sourceBrowseButton;
    @FXML
    private Button targetBrowseButton;
    @FXML
    private Button compareButton;
    @FXML
    private Button synchronizeButton;
    @FXML
    private TreeView sourceTreeView;
    @FXML
    private TreeView targetTreeView;
    @FXML
    private TreeItem sourceTreeViewRoot;
    @FXML
    private TreeItem targetTreeViewRoot;


    public void initialize() {
        sourceLabel.setText(SOURCE);
        targetLabel.setText(TARGET);
        sourceBrowseButton.setText(BROWSE);
        targetBrowseButton.setText(BROWSE);
        compareButton.setText(COMPARE);
        synchronizeButton.setText(SYNCHRONIZE);
        sourceTreeViewRoot = new TreeItem<>();
        targetTreeViewRoot = new TreeItem<>();
        sourceTreeViewRoot.setExpanded(true);
        targetTreeViewRoot.setExpanded(true);
        sourceTreeView = new TreeView<>(sourceTreeViewRoot);
        targetTreeView = new TreeView<>(targetTreeViewRoot);
        sourceTreeView.setShowRoot(true);
        targetTreeView.setShowRoot(true);

    }
}

【问题讨论】:

  • 从不初始化@FXML-带注释的字段。
  • 为什么不呢?这些注释实际上是做什么的?请注意,我只是在模仿我在某个教程中看到的内容,我从来不明白这些注释或 initialize() 方法的真正用途。
  • 这意味着这些是对FXMLLoader创建的对象的引用。见*.com/questions/33881046/…

标签: java javafx initialization treeview fxml


【解决方案1】:

这个论坛上有几个与此相同的问题,但我无法通过快速搜索找到它们。

初始化@FXML-annotated 字段总是错误的。换句话说,你永远不应该写这样的代码

@FXML
private TreeView sourceTreeView ;

// ...

    sourceTreeView = new TreeView<>(...);

@FXML 注释表示该字段引用由FXMLLoader 创建的对象,作为解析 fxml 文件的一部分;该对象被添加到场景图中。如果您随后使用 sourceTreeView = new TreeView... 重新分配引用,则该引用将不再指向作为场景图一部分的树视图。

相反,做

sourceTreeView.setRoot(sourceTreeViewRoot);

顺便说一句,您不应使用原始类型 (TreeView),而应使用适当的泛型类型:TreeView&lt;Something&gt;,其中Something 是每个树项中值的类型。

【讨论】:

    最近更新 更多