[英]groovy - javafx - Can't open new window from FXML after using WebLogic InitialContext
This is a very, very weird and specific situation. 这是一个非常非常奇怪和具体的情况。 I made a minimal verifiable example: 我做了一个最小的可验证的例子:
File: Main.groovy 文件:Main.groovy
public class Main extends Application {
public static void main(String[] args) {
launch(Main,args);
}
@Override
public void start(Stage primaryStage) {
Button destroy = new Button("Break the program")
Button openWindow= new Button("Open new Window")
destroy.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent e) {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "[IP censored]");
InitialContext ic = new InitialContext(env);
}
});
openWindow.setOnAction(new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent e) {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getClassLoader().getResource("test.fxml"))
TestController testController =new TestController()
loader.setController(testController)
Parent testWindowRoot = loader.load();
Scene scene = new Scene(testWindowRoot);
Stage stage = new Stage()
stage.setTitle("Test");
stage.setScene(scene);
stage.show();
}
});
HBox hbox = new HBox(destroy,openWindow)
StackPane root = new StackPane();
root.setPadding(new Insets(5));
root.getChildren().add(hbox);
primaryStage.setTitle("JavaFX Test");
primaryStage.setScene(new Scene(root, 300, 150));
primaryStage.show();
}
}
File: TestController.groovy 文件:TestController.groovy
class TestController implements Initializable {
@FXML AnchorPane mainAnchorPane
@FXML Label label
public void initialize(URL arg0, ResourceBundle arg1) {
label.setText("test 2") //this is line 20
}
}
File: test.fxml 文件:test.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane fx:id="mainAnchorPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label fx:id="label" layoutX="240.0" layoutY="192.0" text="Test 1" />
</children>
</AnchorPane>
So this is a very basic example to reproduce what happens. 所以这是重现所发生事情的一个非常基本的例子。 When I click on the Open Window button, I see a new Window with the text Test 2 because in the initialize()
method of TestController there is a call to setText("Test 2")
. 当我单击Open Window按钮时,我看到一个带有文本Test 2的新窗口,因为在TestController的initialize()
方法中有一个对setText("Test 2")
的调用setText("Test 2")
。 Then when I click on "Break the Program", it creates a map and populates it with JMS info (sorry I can't give you the IP for the JMS queue) and instantiates InitialContext. 然后当我点击“Break the Program”时,它会创建一个地图并用JMS信息填充它(抱歉我不能给你JMS队列的IP)并实例化InitialContext。 After that, any click to the Open Window button crashes the program. 之后,任何单击“打开窗口”按钮都会导致程序崩溃。 No other window opens ever. 没有其他窗口打开。 I see the following stack trace: 我看到以下堆栈跟踪:
java.lang.NullPointerException: Cannot invoke method setText() on null object
[...]
at TestController.initialize(TestController.groovy:20)
Which of course is not true, since he never had a problem opening that window until I tried to connect to WebLogic. 这当然不是真的,因为在我尝试连接到WebLogic之前,他从未遇到过打开该窗口的问题。
Note: this only happens when I execute JavaFX from Groovy, not from Java, something that has been working for me flawlessly for months. 注意:这只发生在我从Groovy执行JavaFX时,而不是从Java执行,这些内容已经为我完美地工作了好几个月。
So, what's the deal? 那么,这笔交易是什么? What is the connection between these two things? 这两件事之间有什么联系? Why can't I open a FXML window after instantiating InitialContext? 为什么我不能在实例化InitialContext后打开FXML窗口?
Using jdk1.8.0_181 使用jdk1.8.0_181
edit: I HAVE FOUND A WORKAROUND! 编辑:我发现了一个变通方法! It only fixes the symptom though. 它只能修复症状。 The issue was that the GUI objects were magically set to null after using WL. 问题是使用WL后GUI对象被神奇地设置为null。 Well, I can just use the lookup() method to "refresh" the object reference. 好吧,我可以使用lookup()方法“刷新”对象引用。 This is not the perfect solution obviously, but my code works now. 这显然不是完美的解决方案,但我的代码现在可以正常工作。 I am still extremely curious about the true answer to this questions though. 我对这个问题的真正答案仍然非常好奇。
I think this is because you create the controller like this 我想这是因为你创建了这样的控制器
TestController testController =new TestController()
Use the loader
使用loader
FXMLLoader loader = new FXMLLoader(getClass().getClassLoader().getResource("test.fxml"));
TestController testController = (TestController) loader.getController();
or 要么
TestController testController = loader.getController();
Just a wild guess: Maybe initializing WebLogic is messing up the class loader. 只是一个疯狂的猜测:也许初始化WebLogic搞乱了类加载器。 Try to print out the value of getClass().getClassLoader().getResource("test.fxml")
before using it. 尝试在使用之前打印出getClass().getClassLoader().getResource("test.fxml")
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.