Инструкции по Javafx 2.0 Application.getParameters() в файле Controller.java
Учитывая следующий пример.
Как получить доступ к аргументам / параметрам приложения в контроллере?
Спасибо.
NB. Я пытался смешать App.java и MyController.java только в одном файле класса, но это не помогло.
App.java (упрощенно):
public class App extends Application {
public static void main(String[] args) {
Application.launch(App.class, args);
}
@Override
public void start(Stage primaryStage) throws Exception {
// output arguments in console
System.out.println(getParameters().getNamed().toString());
Parent root = FXMLLoader.load(getClass().getResource("MyView.fxml"));
final Scene scene = new javafx.scene.Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
}
MyController.java (упрощенно):
public class MyController implements Initializable {
@Override
public void initialize(URL url, ResourceBundle rb) {
// HOW TO getParameters() HERE ?
}
@FXML
private Button myButton;
@FXML
private void my_Action(ActionEvent event) {
// HOW TO getParameters() HERE ?
}
}
MyView.fxml (упрощенно):
<AnchorPane fx:id="root" fx:controller="mainpackage.MyController">
<children>
<Button fx:id="myButton" onAction="#my_Action" text="Start" />
</children>
</AnchorPane>
3 ответа
1. Самый простой способ - сохранить их в приложении:
public class App extends Application {
public static void main(String[] args) { launch(); }
public static String parameters;
@Override
public void start(Stage primaryStage) throws Exception {
parameters = getParameters().getNamed().toString();
Parent root = FXMLLoader.load(getClass().getResource("MyView.fxml"));
final Scene scene = new javafx.scene.Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
}
и читать их в контроллере:
public class MyController implements Initializable {
@Override
public void initialize(URL url, ResourceBundle rb) {
System.out.println(App.parameters);
}
2. Более сложные (но лучше в целом) подходы описаны в следующих темах:
public static <T extends Node, P> T load(String resource, final P parameter)
throws MoisException {
try {
logger.debug("resource: {}; parameter: {}", resource, parameter);
FXMLLoader loader = new FXMLLoader(getResource(resource));
// pass parameter into Controller,before invoke the initialize()
loader.setControllerFactory(new Callback<Class<?>, Object>() {
@Override
public Object call(Class<?> param) {
Object controller = null;
try {
controller = ReflectUtil.newInstance(param);
} catch (InstantiationException e) {
throw new MoisException("can't new instance for: " + param.getName(), e);
} catch (IllegalAccessException e) {
throw new MoisException("can't new instance for: " + param.getName(), e);
}
if (controller instanceof ParameterAware) {
((ParameterAware<P>) controller).setParameter(parameter);
}
return controller;
}
});
T node = (T) loader.load();
// pass parameter to node
node.setUserData(parameter);
return node;
} catch (IOException e) {
throw new MoisException("can't load the file: " + resource, e);
}
}
и ParameterAware:
public interface ParameterAware<T> {
void setParameter(T param);
}
каждый раз, когда вы загружаете файл fxml, он создает экземпляр контроллера, если вы можете получить этот экземпляр, вы можете передать много данных из класса, в котором вызывается fxml. это позволит избежать ненужных статических объектов.
public class App extends Application {
public static void main(String[] args) {
Application.launch(App.class, args);
}
@Override
public void start(Stage primaryStage) throws Exception {
// output arguments in console
System.out.println(getParameters().getNamed().toString());
String parameters = getParameters().getNamed().toString();
FXMLLoader fxmlLoader = new FXMLLoader(this.getClass().getResource("MyView.fxml"));
Parent root = fxmlLoader.load();
// cast MyController instance from fxmlLoader object
MyController myController =(MyController)fxmlLoader.getController();
// pass parameters string to myController via public method setParameters()
myController.setParameters(parameters);
final Scene scene = new javafx.scene.Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
}
теперь вы получаете строку параметров из класса приложения в качестве частного поля в MyController
public class MyController implements Initializable {
private String parameters;
// method called in App class
public void setParameters(String parameters) {
this.parameters = parameters;
}
@Override
public void initialize(URL url, ResourceBundle rb) {
// HOW TO getParameters() HERE ?
}
@FXML
private Button myButton;
@FXML
private Label label;
@FXML
private void my_Action(ActionEvent event) {
label.setText("parameters from App class in MyController :" + parameters);
}
}
Я добавил метку в файл fxml, чтобы посмотреть, что произойдет.
<AnchorPane id="AnchorPane" prefHeight="400.0" prefWidth="600.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/17" fx:controller="com.giovanni.mavenproject1.MyController">
<children>
<VBox alignment="CENTER" prefHeight="400.0" prefWidth="600.0" spacing="20.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<Button fx:id="myButton" onAction="#my_Action" text="Start" />
<Label fx:id="label" text="Label" />
</children>
</VBox>
</children>
</AnchorPane>