Setting the value of VBox to a different FXML VBox? - javafx

You can do it with a BorderPane ie:
FXMLLoader loader = new FXMLLoader(getClass().getResource("contacts.fxml"));
HBox root = loader.load();
rootPane.setTop(root);
}
The VBox does not have a .set(node) method.

With a VBox (and with many other Panes) you just modify the children ObservableList the way you would modify any other List.
E.g.
// add root as bottom-most child of rootPane
rootPane.getChildren().add(root);

Related

How can I get objects from FXML to Java Code

I created a GridPane in my JFX Fluidon Designer and I'm trying to reference it in one of my java files.
More specifically, I'd like to programatically put it inside a Vbox with an Hbox I also created in Java. I'll post the code below, it might make more sense.
When I run this code, I get an error that my gridPane variable is null when I use it in the addAll method.
Thanks in advance!
public class MyProgram extends Application {
Label mStatus;
ImageView img_x;
ImageView img_o;
#FXML public GridPane gridPane;
#Override
public void start(Stage primaryStage) {
BorderPane root = new BorderPane();
img_x = new ImageView("file:x.png");
img_o = new ImageView("file:o.png");
img_x.setUserData("X");
img_o.setUserData("O");
HBox hbox = new HBox();
hbox.getChildren().addAll(img_x, img_o);
VBox vbox = new VBox();
vbox.getChildren().addAll(hbox, gridPane);
root.setCenter(vbox);

How to block a ScrollPane panel JavaFX

I have a small problem. I'm building an interface with JavaFX like this:
I wonder, how can I do to block those "lines" of the ScrollPane I indicated in the image? Practically it is not to be resizable but among its properties the ScrollPane does not allow me to put the check on that property:
How can I do to solve?
thanks to all in advance!
I think your problem is that you have not added a minimum value to your ScrollPanes here's an example :
SplitPane split = new SplitPane();
split.setPrefSize(400, 400);
//First ScrollPane
ScrollPane spA = new ScrollPane();
spA.setMinWidth(100); //Block the scrollPane width to 100
spA.setFitToHeight(true);
spA.setFitToWidth(true);
Pane paneA = new Pane();
paneA.setStyle("-fx-background-color:red;");
spA.setContent(paneA);
//Second ScrollPane
ScrollPane spB = new ScrollPane();
spB.setMinWidth(100); //Block the scrollPane width to 100
spB.setFitToHeight(true);
spB.setFitToWidth(true);
Pane paneB = new Pane();
paneB.setStyle("-fx-background-color:blue;");
spB.setContent(paneB);
split.getItems().addAll(spA,spB);
To be able to use your scrollPane as it grows, you can use the binding and bind the content's (width/height properties) of your ScrollPane to their parents (ScrollPane) example :
//set the (FitToHeight/FitToWidth) properties to false before !
spA.widthProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
paneB.setMinWidth((double)newValue);
}
});
Good luck !

How do I make different panes visible when button selected?

So here is the problem I am having: I have 3 button, when I press one of the 3 buttons the new scene will display. Yet I cant seem to figure out how to make different panes appear visible depending on which button is pressed. what is the best method to perform this action? How do i use Id's from different scene controllers in order to change the properties of the pane within the main scene button listener?
currently on my main controller when each button is released the below action listener executes and displays secondscreen.fxml. the secondscreen.fxml has 2 different panes, depending on which button is pressed I need 1 of the 2 pains to set to visable.
#FXML
public void handleButtonAction(MouseEvent event) {
Parent root;
try {
root = FXMLLoader.load(getClass().getResource("secondscreen.fxml"));
Stage stage = new Stage();
stage.setTitle("title");
stage.setScene(new Scene(root));
stage.show();
((Node)(event.getSource())).getScene().getWindow();
} catch (Exception e) {
e.printStackTrace();
}
}
After you load a view, you can access its controler.
Keep in mind, that your controller must be asigned to your fxml file fx:controller="your.package.SecondScreenController.java"
FXMLLoader loader = new FXMLLoader.load(getClass().getResource("secondscreen.fxml"));
// load view
Parent root = loader.load();
// after view is loaded, access its controller
SecondScreenController controller = (SecondScreenController) loader.getController();
// modify view using methods on your controller
controller.setTabIndex(0)
Stage stage = new Stage();
stage.setScene(new Scene(root));
stage.show();

A code I don't understand about switching scenes in JavaFX and SceneBuilder

Ater some googling, I figured that I can change scenes while remaining in the same stage by assigning this method to a button:
Parent root = FXMLLoader.load(getClass().getResource("view/bambam"));
Stage stage= (Stage) ((Node) event.getSource()).getScene().getWindow();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
I don't understand the second line though. What does the stage and node in parenthesis mean? Is it some type of casting? Does it refer to the "primary" stage somehow? I'll be very thankful if someone could fully explain this line or tell me what material I've missed.
The syntax in which the type is placed in parentheses ahead of the expression is a downcast, which is explained nicely here and here. If you expand the code, it might be clearer:
Parent root = FXMLLoader.load(getClass().getResource("view/bambam"));
// get the source of the event
Object eventSource = event.getSource();
// the event only knows its source is some kind of object, however, we
// registered this listener with a button, which is a Node, so we know
// the actual runtime type of the source must be Button (which is a Node)
// So tell the compiler we are confident we can treat this as a Node:
Node sourceAsNode = (Node) eventSource ;
// get the scene containing the Node (i.e. containing the button):
Scene oldScene = sourceAsNode.getScene();
// get the window containing the scene:
Window window = oldScene.getWindow();
// Again, the Scene only knows it is in a Window, but we know we specifically
// put it in a stage. So we can downcast the Window to a Stage:
Stage stage = (Stage) window ;
// Equivalently, just omitting all the intermediate variables:
// Stage stage= (Stage) ((Node) event.getSource()).getScene().getWindow();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
IMHO this is pretty badly written code. Firstly, downcasting to some extent sidesteps the usual compile-time type checks, relying on our own analysis of our coding logic to avoid runtime exceptions. Thus it is good practice to avoid it when possible.
In this case, you state that this code is part of a handler registered with a button. Therefore, the source of the event is the button. So, instead of going through all those steps to get back a reference to the button, we can just use an existing reference. In other words, you have something like:
button.setOnAction(event -> {
Parent root = FXMLLoader.load(getClass().getResource("view/bambam"));
Stage stage= (Stage) ((Node) event.getSource()).getScene().getWindow();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
});
Here ((Node) event.getSource()) must be the button, so you can immediately simplify to
button.setOnAction(event -> {
Parent root = FXMLLoader.load(getClass().getResource("view/bambam"));
Stage stage = (Stage) button.getScene().getWindow();
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
});
Secondly, there's really no need to replace the Scene at all: why not just replace the root of the existing Scene? For this you can do
button.setOnAction(event -> {
Parent root = FXMLLoader.load(getClass().getResource("view/bambam"));
Scene scene = button.getScene();
scene.setRoot(root);
});
(clearly the Stage is already showing, since the user clicked on the button, so stage.show() is redundant).
If you prefer, you can simplify that to
button.setOnAction(event -> {
Parent root = FXMLLoader.load(getClass().getResource("view/bambam"));
button.getScene().setRoot(root);
});
or even just
button.setOnAction(event ->
button.getScene().setRoot(FXMLLoader.load(getClass().getResource("view/bambam"))));

JavaFX: Set textfield value before showing window

I'm creating a new modal dialog from the main controller class. How do I set some textfield values in the dialog before it is displayed?
URL url = getClass().getResource("SeedNodeForm.fxml");
Stage stage = new Stage();
stage.setTitle("Seed Node Information");
stage.initModality(Modality.WINDOW_MODAL);
stage.initOwner(((Node) event.getSource()).getScene().getWindow());
stage.initStyle(StageStyle.UTILITY);
Parent root = FXMLLoader.load(url);
stage.setScene(new Scene(root));
stage.centerOnScreen();
textfield1.setValue("foo!");
textfield2.setValue("foo2");
stage.showAndWait();
Thank you Uluk Biy - your link led me to the answer which is:
// get the controller from the loader
SeedNodeFormController c = (SeedNodeFormController) fxmlLoader.getController();
// call setter in controller routine to set needed values
c.setSeedNode(value);

Resources