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
我相信唯一不同的是 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