javafx使用来自MainController或适当Controller类中的其他控制器的对象
我有以下代码:
package pl.javastart.youtufy.controller; import java.net.URL; import java.util.ResourceBundle; import javafx.application.Platform; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.Node; import javafx.scene.control.Button; import javafx.scene.control.Label; import javafx.scene.control.ToggleButton; import javafx.scene.web.WebEngine; import javafx.stage.Stage; public class ConnectionErrorController implements Initializable { @FXML private Label infoLabel; @FXML private Button tryButton; @FXML private Button exitButton; @Override public void initialize(URL location, ResourceBundle resources) { MainController mc = new MainController(); infoLabel.setText("Connection lost, please try again"); tryButton.setText("try again"); exitButton.setText("exit"); tryButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { WebEngine webEngine = mc.getContentPaneController().getVideoWebView().getEngine(); // 1 ToggleButton playButton = mc.getControlPaneController().getPlayButton(); // 2 Node source = (Node) event.getSource(); Stage stage = (Stage) source.getScene().getWindow(); if (mc.testInet()) { stage.close(); mc.play(webEngine, playButton); } else { stage.close(); MainController.exist = false; } } }); exitButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { Platform.exit(); } }); } }
我正在尝试从MainController中的控制器使用WebEngine和ToggleButton对象(我在MainController中为它们生成了getters和setter):
public class MainController implements Initializable { @FXML private ContentPaneController contentPaneController; @FXML private ControlPaneController controlPaneController; @FXML private MenuPaneController menuPaneController; @FXML private SearchPaneController searchPaneController; private Youtube youtubeInstance; public static boolean exist = false; public ControlPaneController getControlPaneController() { return controlPaneController; } public void setControlPaneController(ControlPaneController controlPaneController) { this.controlPaneController = controlPaneController; } public ContentPaneController getContentPaneController() { return contentPaneController; } public void setContentPaneController(ContentPaneController contentPaneController) { this.contentPaneController = contentPaneController; }
但是它仍然返回NullPointerException。 我有同样的问题,当我试图简单地引用ConnectionErrorController中的控制器。 如何正确引用ConnectionErrorController中控件的ToggleButton i WebEngine对象? 问候
您正在创build一个“手动”的控制器实例
MainController mc = new MainController();
当FXMLLoader
为您创build控制器时,作为加载FXML文件过程的一部分,@FXML @FXML
字段将由FXMLLoader
初始化。 由于您创build的控制器不是由FXMLLoader
创build的控制器实例,因此它的@FXML
字段未初始化(即它们为空),因此您将得到一个空指针exception。
在调用load()
之后, FXMLLoader
通过调用FXMLLoader
实例上的getController()
来获得对FXMLLoader
创build的控制器的引用。
如果您希望一个控制器与另一个控制器进行通信,则通过在第二个控制器中定义适当的方法将该引用传递给另一个控制器:
public class ConnectionErrorController implements Initializable { private MainController mainController ; public void setMainController(MainController mainController) { this.mainController = mainController ; } // ... @Override public void initialize(URL location, ResourceBundle resources) { infoLabel.setText("Connection lost, please try again"); tryButton.setText("try again"); exitButton.setText("exit"); tryButton.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { WebEngine webEngine = mainController.getContentPaneController().getVideoWebView().getEngine(); // 1 ToggleButton playButton = mainController.getControlPaneController().getPlayButton(); // 2 if (mainController.testInet()) { mainController.play(webEngine, playButton); } else { // obviously you can now do something better than the "public static field hack" here: MainController.exist = false; } tryButton.getScene().getWindow().hide(); } }); // ... } }
假设你正在MainController
一个方法中加载第二个fxml文件,那么你可以这样做:
public class MainController { // ... public void showConnectionErrorWindow(String fileName) { FXMLLoader loader = new FXMLLoader(getClass().getResource("path/to/ConnectionError.fxml")); Parent root = loader.load(); ConnectionErrorController connectionErrorController = loader.getController(); connectionErrorController.setMainController(this); Scene scene = new Scene(root); Stage stage = new Stage(); // etc... } // ... }
请注意,解决此问题的方法有很多,比如将ConnectionErrorController
传递给一个callback函数(以lambdaexpression式的forms)来处理调用play(...)
,这样可以避免ConnectionErrorController
和MainController
。 但是,由于您似乎对Java尚不熟悉,因此这种更简单的方法可能更适合。
有关将值传递给控制器的更多信息,请参阅传递参数JavaFX FXML 。