javafx8 FXMLLoader returns 空

javafx8 FXMLLoader returns null

我相信唯一不同的是 SceneBuilder 的版本是 8.3,我在 Oracle 中使用 TreeTableView 和 TreeTableColumn Java 8 这是 fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.TreeTableColumn?>
<?import javafx.scene.control.TreeTableView?>

<TreeTableView maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="1" minWidth="1" prefHeight="400.0" prefWidth="600.0" showRoot="false" stylesheets="@org/cornova/AudioExplorer.css" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.cornova.AudioExplorerController">
  <columns>
    <TreeTableColumn fx:id="mixerName" editable="false" maxWidth="6000.0" minWidth="100.0" prefWidth="-1.0" text="Mixers" />
    <TreeTableColumn fx:id="lineNames" maxWidth="49.0" minWidth="100.0" prefWidth="-1.0" text="Lines" />
      <TreeTableColumn fx:id="controlNames" minWidth="100.0" prefWidth="-1.0" text="Controls" />
      <TreeTableColumn fx:id="formatsNames" minWidth="100.0" prefWidth="-1.0" text="Formats" />
  </columns>
</TreeTableView>

这里是控制器class

/**
 * Sample Skeleton for 'AudioExplorer.fxml' Controller Class
 */

package org.cornova;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.scene.control.TreeTableColumn;

public class AudioExplorerController  {

    @FXML // ResourceBundle that was given to the FXMLLoader
    private ResourceBundle resources;

    @FXML // URL location of the FXML file that was given to the FXMLLoader
    private URL location;

    @FXML // fx:id="mixerName"
    private TreeTableColumn<?, ?> mixerName; // Value injected by FXMLLoader

    @FXML // fx:id="lineNames"
    private TreeTableColumn<?, ?> lineNames; // Value injected by FXMLLoader

    @FXML // fx:id="controlNames"
    private TreeTableColumn<?, ?> controlNames; // Value injected by FXMLLoader

    @FXML // fx:id="formatsNames"
    private TreeTableColumn<?, ?> formatsNames; // Value injected by FXMLLoader

    @FXML // This method is called by the FXMLLoader when initialization is complete
    void initialize() {
        assert mixerName != null : "fx:id=\"mixerName\" was not injected: check your FXML file 'AudioExplorer.fxml'.";
        assert lineNames != null : "fx:id=\"lineNames\" was not injected: check your FXML file 'AudioExplorer.fxml'.";
        assert controlNames != null : "fx:id=\"controlNames\" was not injected: check your FXML file 'AudioExplorer.fxml'.";
        assert formatsNames != null : "fx:id=\"formatsNames\" was not injected: check your FXML file 'AudioExplorer.fxml'.";

    }
}

这里是主要内容class

package org.cornova;

import java.net.URL;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.fxml.FXMLLoader;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.TreeTableColumn.CellDataFeatures;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.control.TreeTableView;
import javafx.stage.Stage;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Mixer;
import javax.sound.sampled.Mixer.Info;

/**
 *
 * @author walt
 */
public class AudioExplorer extends Application {

    private URL url;
    private FXMLLoader explorerLoader;
    private AudioExplorerController audioController;

    @Override
    public void start(Stage stage) throws Exception {
        stage.setTitle("Audio Explorer");
        final Scene scene = new Scene(new Group(), 200, 400);
        Group sceneRoot = (Group)scene.getRoot();
        try {
            url = getClass().getResource("/AudioExplorer.fxml");
            explorerLoader = new FXMLLoader(url);
            explorerLoader.setLocation(url);
            audioController = explorerLoader.getController();
        } catch (Exception e) {
            System.out.println(e);
        }      
        //Creating the root element
        TreeItem rootNode = new TreeItem();
        rootNode.setExpanded(true);   
        Info mixers[] = AudioSystem.getMixerInfo();
        rootNode = new TreeItem<>(mixers[0]);
        //Creating tree items
        for (int i = 0; i < mixers.length; i++) {
            rootNode.getChildren().add(new TreeItem<>(mixers[i]));
        }

        //Creating a column
        TreeTableColumn<Info,String> mixerInfo = new TreeTableColumn<>("Mixers");
        mixerInfo.setMaxWidth(1500);   

        //Defining cell content
        mixerInfo.setCellValueFactory((CellDataFeatures<Info, String> p) -> 
            new ReadOnlyStringWrapper(p.getValue().getValue().getName()));  

        //Creating a tree table view
        final TreeTableView<Info> treeTableView = new TreeTableView<>(rootNode);
        treeTableView.getColumns().add(mixerInfo);
        treeTableView.setMaxWidth(1500);
        treeTableView.setShowRoot(false);
        treeTableView.autosize();
        sceneRoot.getChildren().add(treeTableView);
        stage.setScene(scene);
        stage.show();     
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

这都是在netbeans 8.2下完成的。大约 18 个月前,我已经完成了大约几十个基于场景构建器的图形应用程序。我当时发现的一件事是确保 css 的位置和控制器源根据它们所在的名称 space 进行了调整,这反映在 fxml 中。

css 文件是空的,因为我此时只在 SceneBuilder 中定义了它,这就是我没有包含它的原因(仅评论)。

有人认为我确实记得我刚开始使用 SceneBuilder 的时候是无声失败的倾向。 谢谢!

您实际上需要加载fxml,以便根据fxml 创建控制器。也不需要两次传递位置:

url = getClass().getResource("/AudioExplorer.fxml");
explorerLoader = new FXMLLoader(url);

try {
    TreeTableView<?> audioExplorer = explorerLoader.load();
    audioController = explorerLoader.getController();
    ...
} catch ...

此外,几乎没有理由在字段中保留对 FXMLLoader 实例的引用。完成加载后,只需提取所需的信息和 "drop" 加载程序参考即可。无论如何都应该避免第二次调用 load...

除了 fabian 的回答,请注意我写了一些 utility methods,可以将 FXML 加载减少到单个语句,例如:

TreeTableView<?> audioExplorer = FXMLLoaders.load(AudioExplorer.class);

请注意,这只有在您遵守以下命名约定的情况下才有可能:

If a class "mypackage.<name>" loads a FXML file, then the FXML file should be in the same package and be named "<name>.fxml".

库是开源的。也许你觉得它有用:

<dependency>  
    <groupId>org.drombler.commons</groupId>  
    <artifactId>drombler-commons-fx-core</artifactId>  
    <version>0.10</version>  
</dependency>  

您可以在此处阅读更多相关信息: http://puces-blog.blogspot.ch/2015/03/drombler-commons-conventions-to.html