我知道我加载应用程序的方式可能很奇怪,但我不明白为什么 testfx 套件会为根窗格返回 EmptyNodeQueryException
org.testfx.service.query.EmptyNodeQueryException: there is no node in the scene-graph matching the query: NodeQuery: from nodes: [MainPane[id=mainPane, styleClass=root]],
lookup by function: "org.testfx.util.NodeQueryUtils$$Lambda$245/968514068@57829d67",
lookup by selector: "#removeScriptButton"
我的一些视图组件(不是全部,大多数都没有附加 fxml 文档)是用这种方法制作的:
https://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm
虽然我没有在构造函数中使用 fxml 加载器,但我在实例化后从父类调用的“createView()”方法中使用了它
根类看起来像这样
public class MainPane extends BorderPane implements etc{
//declarations ...
public MainPane(String fxmlName) {
this.fxmlName = fxmlName;
}
@Override
public void createView() {
fxmlLoader.assign(this, fxmlName); //<-----------
this.setCenter(mainScrollPane);
this.setTop(mainMenuBar);
}
}
装载机:
public class ExtendedFxmlLoader implements IFxmlLoader {
@Override
public void assign(Parent parent, String fileName) {
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/" + fileName));
fxmlLoader.setRoot(parent);
fxmlLoader.setController(parent);
try {
fxmlLoader.load();
int bp =234;
} catch (IOException exception) {
throw new RuntimeException(exception);
}
}
}
Root 的 fxml 文档
<fx:root fx:id="mainPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="128.0" minWidth="128.0" prefHeight="720.0" prefWidth="1280.0" type="javafx.scene.layout.BorderPane" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1">
<opaqueInsets>
<Insets />
</opaqueInsets>
</fx:root>
失败的测试(对于另一个组件)
public class RemoveScriptButtonTest extends ApplicationTest{
private Button button;
private RemoveScriptButton removeScriptButton;
@Before
public void setUpApp() throws Exception {
ApplicationTest.launch(App.class);
}
@Override
public void start(Stage stage) {
stage.show();
}
@Test
public void just_click(){
removeScriptButton = new RemoveScriptButton(new ExtendedFxmlLoader(), "removeScriptButton.fxml");
removeScriptButton.createView();
button = find("#removeScriptButton");
clickOn(button);
}
public <T extends Node> T find(final String query) {
/** TestFX provides many operations to retrieve elements from the loaded GUI. */
return lookup(query).query();
}
@After
public void tearDown() throws TimeoutException {
FxToolkit.hideStage();
release(new KeyCode[] {});
release(new MouseButton[] {});
}
}
RemoveScriptButton 也是类似于 MainPane 的自定义控件
所以我不确定这里发生了什么,我是否应该尝试将根更改为实现 Initializable 的普通控制器类,然后以标准方式加载它,例如
Parent root = FXMLLoader.load(getClass().getResource("mainPane.fxml"));