Buenas,
Tengo una aplicación en JavaFX realizada por FXML mediante Modelo Vista Controlador. El tema es que quiero mover unos sliders con el teclado. Para ello en la clase principal pongo un KeyEvent para escuchar lo que acontece en el teclado. En la clase FXMLDocumentController que actúa de controlador creo las variables FXML de los sliders. Estas variables son pasadas a una tercera clase. Donde allí se modifican los sliders cuando se hace algún click.
El problema es que cuando paso las variables de los sliders en la tercera clase se almacenan perfectamente pero a la hora de ejecutar el código que debería modificar los sliders que viene pasado de la clase principal cuando se hace click estás variables FXML son null.
Aquí os dejo el código:
Clase principal:
public class OpenPilot extends Application {
Movements Movements = new Movements();
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Scene scene = new Scene(root);
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent Key) {
Movements.GetKeys(Key);
}
});
stage.setScene(scene);
stage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Aquí el controlador:
public class FXMLDocumentController implements Initializable {
Movements Movements = new Movements();
@FXML public Slider SpeedSlider;
@FXML public Slider TurnsSlider;
@Override
public void initialize(URL url, ResourceBundle rb) {
//Send GUI Information
Movements.GetSliders(SpeedSlider, TurnsSlider);
}
}
Y por última la tercera clase llamada Movements:
public class Movements {
//Define Data Variables
public double SpeedValue;
public double TurnsValue;
//Define GUI Variables
private Slider SpeedSlider;
private Slider TurnsSlider;
public void GetSliders(Slider SpeedSlider, Slider TurnsSlider) {
this.SpeedSlider = SpeedSlider;
this.TurnsSlider = TurnsSlider;
}
//Get Sliders
public void GetKeys(KeyEvent Key) {
System.out.println(Key.getCode());
System.out.println(SpeedSlider);
Platform.runLater(new Runnable() {
@Override public void run() {
TurnsSlider.setValue(10);
}
});
}
}
Me han dicho que el problema viene dado porque estoy usando dos instancias de Movements, una en la clase principal y otra en el controlador y como no uso métodos estáticos no soy capaz de mantener el contenido de las variables.
He probado este código:
Controlador:
public class FXMLDocumentController implements Initializable {
Movements movements = new Movements();
public Movements getMovements() {
return movements;
}
@FXML public Slider SpeedSlider;
@FXML public Slider TurnsSlider;
@Override
public void initialize(URL url, ResourceBundle rb) {
//Send GUI Information
movements.GetSliders(SpeedSlider, TurnsSlider);
}
}
y Clase Principal:
public class OpenPilot extends Application {
Movements movements;
@Override
public void start(Stage stage) throws Exception {
FXMLLoader fxmlLoader = new FXMLLoader();
Parent root = fxmlLoader.load(getClass().getResource("FXMLDocument.fxml"));
// get movements from via controller
FXMLDocumentController controller = (FXMLDocumentController)fxmlLoader.getController();
movements = controller.getMovements();
Scene scene = new Scene(root);
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent Key) {
movements.GetKeys(Key);
}
});
stage.setScene(scene);
stage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Pero en la clase principal alguna de estas dos líneas genera error:
FXMLDocumentController controller = (FXMLDocumentController)fxmlLoader.getController();
movements = controller.getMovements();
El error no es detectado en un principio por netbeans pero al arrancar el programa en la consola del IDE me da lo siguiente:
CitarException in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:367)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:305)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:894)
at com.sun.javafx.application.LauncherImpl.access$000(LauncherImpl.java:56)
at com.sun.javafx.application.LauncherImpl$1.run(LauncherImpl.java:158)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.NullPointerException
at openpilot.OpenPilot.start(OpenPilot.java:35)
at com.sun.javafx.application.LauncherImpl$8.run(LauncherImpl.java:837)
at com.sun.javafx.application.PlatformImpl$7.run(PlatformImpl.java:335)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:301)
at com.sun.javafx.application.PlatformImpl$6$1.run(PlatformImpl.java:298)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl$6.run(PlatformImpl.java:298)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.access$300(WinApplication.java:39)
at com.sun.glass.ui.win.WinApplication$4$1.run(WinApplication.java:112)
... 1 more
Exception running application openpilot.OpenPilot
Java Result: 1