Modifying a Child Node in JavaFX - javafx

I have a question which I think is based on my poor conceptual understanding of OOP/programming generally, but it has come up, specifically, in a JavaFX scenario.
I want to add a child node to parent node and then update that child, and see the update reflected, without having to remove it and re-add it to the parent node. Is this possible? More specifically, I have a Pane (parent) and an ImageView (child) which I want to add to the parent and then later modify.
Pane pane = new Pane();
ImageView picture = new ImageView("dog.png");
pane.getChildren().add(picture);
//now I'm seeing a picture of a dog in my Pane
picture = new ImageView("cat.png");
//So I've reassigned "picture" but am I still seeing a dog?
pane.getChildren().remove(picture);
pane.getChildren().add(picture);
//Am I seeing a cat now?
My apologies if this is unclear or too basic. I can attempt to clarify if needed. Any help is appreciated.

Reusing an existing ImageView
An ImageView is a view to an image.
You don't need to create a new view to view a new image, you can directly change the image you are viewing.
ImageView picture = new ImageView("dog.png");
Pane pane = new Pane(picture);
// . . .
// use alchemy to transmute a dog into a cat.
// . . .
picture.setImage(new Image("cat.png"));
Creating and using a new ImageView
You could make it work the way you originally coded it, though that is suboptimal. The change here is that you must remove the dog image view using the picture reference before you assign the picture reference to a new image view (not after as you did in your question).
Pane pane = new Pane();
ImageView picture = new ImageView("dog.png");
pane.getChildren().add(picture);
//now I'm seeing a picture of a dog in my Pane
// . . .
// remove the dog before you reassign the picture to a cat.
pane.getChildren().remove(picture);
picture = new ImageView("cat.png");
//So I've reassigned "picture" and can now see a cat, not a dog.
pane.getChildren().add(picture);

Related

How to play a video in a alert using JavaFX?

I'm trying to play a video in a alert dialog using JavaFX. The problem is that I can't find how to display the video or more how to insert it in the alert ?
Here is my alert code
MediaPlayer player = new MediaPlayer( new Media(getClass().getResource("video.mp4").toExternalForm()));
MediaView mediaView = new MediaView(player);
private void alert(){
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Don't be a fool");
alert.setHeaderText("");
alert.setContentText("Do you really think your time is correct ?");
Optional<ButtonType> result = alert.showAndWait();
}
An Alert extends from Dialog, which means you can customize its DialogPane. If you want to add a video to your alert, the best place is probably the dialog pane's content. But note that setting the content will replace the contentText (which you set in your example code):
In addition to the header and content properties, there exists header text and content text properties. The way the *Text properties work is that they are a lower precedence compared to the Node properties, but they are far more convenient for developers in the common case, as it is likely the case that a developer more often than not simply wants to set a string value into the header or content areas of the DialogPane.
This means, if you still want to display "Do you really think your time is correct?", you'll have to add your own Label to the content as well. For example:
Alert alert = new Alert(Alert.AlertType.ERROR);
alert.setTitle("Don't be a fool");
alert.setHeaderText("");
Label label = new Label("Do you really think your time is correct?");
VBox content = new VBox(10, label, mediaView);
content.setAlignment(Pos.CENTER);
alert.getDialogPane().setContent(content);
alert.setOnShowing(e -> player.play());
alert.showAndWait();

Open a javafx fxml file in separate window on a button click without duplication

I use the below code to open a javafx fxml file in a different window on a button click event and it works fine. But if I click the same button again while the window opened it will create a duplicate window. Is there a possibly solutions to overcome this problem? Thanks in advance.
Parent parent = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Stage stage = new Stage(StageStyle.DECORATED);
stage.setTitle("Title");
stage.setScene(new Scene(parent));
stage.show();
I just stumbled upon this old question and figured I might answer it for anyone new to JavaFX or coding in general (I'm bored..).
In the provided code (see below) a new Stage is created every time, meaning that if this is run inside of a method you actually create a new Stage variable every time that the code is run:
Stage stage = new Stage(StageStyle.DECORATED);
What you could do instead create your Stage variable outside the method so that you either 1. just overwrite it every time or 2. have some "is showing" or a nullcheck or similar to see if a new stage should be created or if the existing one just needs to be shown.
For example:
private Stage stage;
private void onOpenNewStageBtnClicked(){
if(stage == null){
Parent parent = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
stage = new Stage(StageStyle.DECORATED);
stage.setTitle("Title");
stage.setScene(new Scene(parent));
}
stage.show();
}
Also, what I usually do is I create a Stage factory to avoid a lot of duplicate code and so that I can break out the creation of the stages and the loading of fxmls to other classes than my controller.

JavaFX - How to open a new stage in same window?

I'm a beginner, I don't know how to open a new stage in same window in javaFX8?
Stage modal_stage = new Stage();
modal_stage.setScene(new Scene(root, 500, 575));
modal_stage.setTitle("modal");
modal_stage.initModality(Modality.APPLICATION_MODAL);
modal_stage.initOwner(modal_stage.getOwner());
modal_stage.setResizable(false);
modal_stage.show();
When I opened a new stage through the above code, the stage always opening in a difference window,like this:
But I want the new stage will not create a new icon in StartMenu taskbar, just like Swing's Dialog of Jframe---No matter how many dialogs I open under jframe, It is always displayed as one window. So what can I do?
Sorry, I am not very good at English, I wish I had clarified the question.
Assuming that you have a parent stage:
Stage parentStage = new Stage();
And the child Stage:
Stage childStage = new Stage();
You have to set the init owner of the childStage to be the parent:
childStage.initOwner(parent);
Mention that the above has to be called before the childStage to be shown.
Also mention that doing this you will have some behaviour like when parent child is minimized then childStage will be also minimized.

I need to create a back button functionality in javafx?

I am presently using something like this binding this code to fxml javafx button
Parent parent = FXMLLoader.load(getClass().getResource("AolRun.fxml"));
Stage stage = new Stage();
stage.initStyle(StageStyle.UTILITY);
stage = (Stage) run.getScene().getWindow();
Scene scene = new Scene(parent);
stage.setScene(scene);
scene.getStylesheets().add("/css/Style.css");
stage.setTitle("Output");
stage.setResizable(false);
stage.show();
Is there a generic function we can use for back which just transits screen from the present fxml scene to the next fxml .
I have separate scene for every fxml.
1)A better approach is to change the parent layout and use only one Scene.
2)Although you can have the functionality you want using a Button.When the onAction method is fired you choose in what Scene to go.You can either have the Scenes stored in the array and move to the next or previous index, or implement your own logic which Scene will follow or which Scene is the previous of the current Scene.
Here is where the 1 is more usefull cause you can go to the next or previous "Scene" using an Animation.For example TransitionAnimation.
~~> In addition to the comments below
If you want to know in which Scene was the user before you can use an ObservableList or Array.
Everytime the user changes Scene ,the previous Scene is stored in the array.

How to creat a button programmatically with JavaFX?

I want to make a button on an AnchorPane without drag it from the library in the FXML file I want to do it progammatically: if the search button clicked, should show a new button not existed in the AnchorPane before I did this code but I don't know what is wrong with it:
private void searchButton(ActionEvent evt) {
Button tab = new Button();
tab.setLayoutX(147);
tab.setLayoutY(102);
tab.setText("Tab1");
tab.setPrefHeight(27);
tab.setPrefWidth(69);
WebView wb = new WebView();
wb.setLayoutX(-1);
wb.setLayoutY(128);
wb.setPrefWidth(1604);
wb.setPrefWidth(700);
}
I am assuming that you searchButton method is in controller attached to some FXML. Then all you need to do is this:
yourAnchorPane.getChildren().add(tab);
If you don't have already published reference to anchorPane in your controller, then add this into your controller
#FXML
AnchorPane yourAnchorPane;
And in SceneBuilder select your anchorPane, go to code tab and enter "yourAnchorPane" as fx:id.
Further info on working with anchorpane is javadoc.
You probably also want to set some constraints on the tab to locate it at a position within the AnchorPane. For instance, the following code will locate your button tab relative to the top left corner of the AnchorPane: Ten pixels down and fifteen pixels to the right.
AnchorPane.setTopAnchor(tab, 10.0);
AnchorPane.setLeftAnchor(tab, 15.0);

Resources