How to do it in TestFX 4? - javafx

I have a question about testFx 4.
There is a GUI object, where I want to set text into TextField ("#searchField").
It's works in TestFx 3 as follows:
//Load FXML
#Override
protected Parent getRootNode() {
Parent parent = null;
try {
FXMLLoader loader = new FXMLLoader();
loader.setResources(ResourceBundle.getBundle(ENTITIES_FIELDS_BUNDLE_PATH, Locale.GERMANY));
parent = loader.load(this.getClass().getClassLoader().getResource(SHOW_ALL_LAYOUT_PATH).openStream());
} catch (IOException ex) {}
return parent;
}
//Set text into Field and check it's there
#Test
public void setBothnamesAndCheckEnabledSearchButton() {
TextField searchField = find("#searchField");
searchField.setText("new text");
verifyThat("#searchField", hasText("new text"));
}
So, it works and everything fine.
100% same case in TestFx 4:
#Override
public void start(Stage stage) throws Exception {
try {
FXMLLoader loader = new FXMLLoader();
loader.setResources(ResourceBundle.getBundle(ENTITIES_FIELDS_BUNDLE_PATH, Locale.GERMANY));
AnchorPane pane = (AnchorPane)loader.load(this.getClass().getClassLoader().getResource(SHOW_ALL_LAYOUT_PATH).openStream());
Scene scene = new Scene(pane);
stage.setScene(scene);
} catch (IOException ex) {}
}
#Test
public void setBothnamesAndCheckEnabledSearchButton() {
clickOn("#searchField").write("new text");
verifyThat("#searchField", hasText("new text"));
}
I become always "FxRobotException: the query "#searchField" returned no nodes. So he doesn't "see" the same TextField...
What am I doung wrong? I'm sure it's something really stupid I can't see... Can anybody please help me? Thanks!

So I finally found an answer: i schould call stage.show() at the end of overriden start() method. testFX doesn't find any invisible components...

Related

JavaFX onShowing Stage after fxml is loaded

what im trying to do is a javaFX window that handles my code while my window is shown so i worked on
public void setStage()(Stage stage){
this.stage = stage;
stage.setonShowing(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent event) {
work(); //What i want to do while my window is visible
}
});
stage.show();
}
setStage() gets his Stage from the class where i load my fxml from....
Everytime my window is popping up the sleep is before the fxml is loaded but after the window showed up so i only have a white window with nothing on it
To be honest im not sure what the real problem is
is it that i sleep before the fxml is loaded or is it my setonShowing() which is not working as it should be?
i also tryed to use setonShown() instead of setonShowing() but nothing changed
what i also tryed is to override the setonShowing in my Parent class but that also didnt work
so to make sure i didnt made anything wrong with my fxml here is the code i use to creat the window:
Parent root;
Stage stage = (Stage) StartSingleplayer_B.getScene().getWindow();
stage.close(); // closing my old window
try {
fxmlLoader = new FXMLLoader(getClass().getResource("Spielfeld.fxml"));
root = (Parent) fxmlLoader.load();
GameController controller = fxmlLoader.getController();
Stage stage2 = new Stage();
controller.setStage(stage2);
stage2.setOnShowing(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent event) {
work();
}
});
stage2.setScene(new Scene(root));
stage2.show();
} catch(Exception e) {
e.printStackTrace();
}
i really appreaciate your help so it would be nice if someone could give me a clue what i did wrong and / or how i could fix it

JavaFX FXMLLoader getController NullPointerException

I have a project in school where I have to develop a program where you first can choose whether you want to save/read to/from a SQL DB or to save/read to/from XML.
I've made a GUI where you can choose between both methods.
The GUI closes after the user clicks on one of the buttons and the MainMenu GUI opens.
Now I need to know in the MainMenuController what the user choose.
I found online a Method to call the MainMenuController inside the first controller, with FXMLLoader.getController().
try {
Stage stage = new Stage();
FXMLLoader Loader = new FXMLLoader();
Parent root = Loader.load(getClass().getResource("MainMenu.fxml"));
MainMenuController mc = Loader.getController();
mc.setSave("sql");
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
catch (Exception e) {
e.printStackTrace();
}
MainMenuController
public class MainMenuController {
private String save = null;
public void setSave(String save) {
this.save=save;
}
public String getSave() {
return save;
}
}
But when i try to access a method in MainMenuController I get a NullPointerException for
mc.setSave("sql")
First ,to understand this issue ,you should make some tricks to detect where is your problem.When you do :
System.out.println(mc);
You will find the result is null.So you can not call setSave("sql") with null object,you got a null controller because your did not specify the location of your file,but you can change some lines to resolve your problem :
try {
Stage stage = new Stage();
FXMLLoader fxm = new FXMLLoader(getClass().getResource("MainMenu.fxml"));
Parent parent = (Parent) fxm.load();
Scene scene = new Scene(parent);
stage.setScene(scene);
stage.show();
FirstController mc = fxm.getController();
System.out.println(mc);
mc.setSave("sql");
} catch (Exception e) {
e.printStackTrace();
}
You are calling the static method FXMLLoader.load(URL). Because this is a static method, it has no effect on the state of the FXMLLoader instance you created; specifically the controller field is not set.
Instead, set the location on the FXMLLoader instance, and call the instance method load():
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("MainMenu.fxml"));
// or just FXMLLoader loader = new FXMLLoader(getClass().getResource("MainMenu.fxml"));
Parent root = loader.load();

How to write a MouseListener for JavaFX

I want to write a little game where I shoot from an object to a specific direction on a JavaFX Panel using my mouse position.
I want to turn a Line in the direction where my Mouse is.
Line line = new Line(startPosX, startPosY, mouseDirectionX, mouseDirectionY);
How can I do that?
Add a MOUSE_MOVED event filter like this:
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
Pane root = new Pane();
Line line = new Line( 400,200,400,200);
root.addEventFilter(MouseEvent.MOUSE_MOVED, e -> {
line.setEndX(e.getSceneX());
line.setEndY(e.getSceneY());
});
root.getChildren().add(line);
Scene scene = new Scene(root, 800, 400);
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
If you want the line to be limited in length, you'll have to do the proper calculations of course via the angle.

How do I embed a controller with a new scene in JavaFX

I want to open a new scene with a controller but I get an IOException when I put the controller in it.
This is my method:
private void forgotAccount (ActionEvent event) {
try {
Node node = (Node) event.getSource();
Stage stage = (Stage) node.getScene().getWindow();
Scene scene = stage.getScene();
FXMLLoader loader = new FXMLLoader(Login.class.getResource("/mattiashellkvist/forgotAccount.fxml"));
loader.setController(new ForgotAccountController());
AnchorPane root = (AnchorPane) loader.load();
scene.setRoot(root);
stage.sizeToScene();
}
catch (IOException e) {
System.out.println("Something went wrong");
}
}
code is correct...please check your fxml location(which you provided to FXMLLoader) and fxml file for any error...and in catch use e.getMessage() to get detailed problem (i.e. System.out.println("Something went wrong "+e.getMessage());)

[A]How to use setFullScreen methode in javafx?

I have a stage with these properties
stage = new Stage(StageStyle.DECORATED);
stage.setFullScreen(true);
stage.setFullScreenExitHint("");
stage.setTitle("My App");
stage.getIcons().add(new Image(icon-address));
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("start.fxml"));
fxmlLoader.setController(this);
...
...//and other properties
It is in full screen in this stage. I have a button and each time I click on it , a method of another class is called and the reference of this stage is passed to it.
For example, if I have two classes Start and ButtonClicked
In Start, I have this :
Button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
buttonClicked a = new buttonClicked ();
try {
a.render(stage);
} catch (Exception ex) {
Logger.getLogger(menuController.class.getName())
.log(Level.SEVERE, null , ex);
}
}
});
Now, the render method is called and I have the following code inside render :
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("buttonclicked.fxml"));
fxmlLoader.setController(this);//set Controller for our fxml file
loader = fxmlLoader.load();//loader is a stackPane because buttonclick.fxml has stackPane
stage.setScene(new Scene(loader));
stage.setFullScreen(true);
...
The problem is, if user clicks on button, stage become a 1024x700(because i have pictures in start.fxml and buttonclicked.fxml. The size of both the picture is 1024x700
After a moment, it becomes full screen. How can i fix this ?
I want to kill the delay in full screen
Thanks
Try
stage.getScene().setRoot(loader);
in render method.
By doing this, the creation of a new scene is eliminated. Therefore I guess, some UI related updates and calculations that must be done after the scene has been shown, are also eliminated.

Resources