Creating a JavaFX TreeView using Scene Builder - java

I'm starting working with JavaFX and wish to use the new tree view (as you can use multiple icons to represent your data - which is what I wish to take advantage of).
I have created a basic form/scene that has a tree view and one button on it. When this button is pressed I wish to populate the treeview.
Now, all the examples ive looked at are where the form/scene is generated in code and the treeview is bound to that control....how do I have a pre designed form with Scene builder and populate it from external code?

You could use the following code in a controller class. Inside the FXML file you will need to set the FXID to selectionTreeView. Tested in JDK 8u5 and it worked.
#FXML
TreeView selectionTreeView;
#FXML
private void handleButtonAction(ActionEvent event) {
createTree();
}
public void createTree(String... rootItems) {
//create root
TreeItem<String> root = new TreeItem<>("Root");
//root.setExpanded(true);
//create child
TreeItem<String> itemChild = new TreeItem<>("Child");
itemChild.setExpanded(false);
//root is the parent of itemChild
root.getChildren().add(itemChild);
selectionTreeView.setRoot(root);
}

Set the class name (including package) on the root node of your control in scene builder. If you click on, then go to the code tab on the right it is the top field.
Now set an ID on the TreeView in your control.
Now in the controller object add a TreeView field, the variable name should be the same as what you set the TreeView ID as in scene builder. Annotate with field with #FXML.
Now when the FXML is loaded, the controller is created and the TreeView field is set.

Related

JavaFX multiple stages

I'm new to using Java FX and was wondering if anyone could provide some answers for me on creating multiple independent stages. I'm also using Scene Builder for ActionEvents.
An example of multiple stages could be something like this:
Login page -> main stage -> other sub stages.
The way I understand is that you need a FXML loader on each controller to bring up each stage. So on my Main java class, under START method, I'll bring up a Login stage. And on my Login Controller, I'll have a method to bring up a Main Stage (i.e. once the Login button is pressed), and finally/similarly, I'll have a method under my Main Controller to bring up other sub stages, once a button to that sub stage is pressed from the Main Stage.
Is this the right way of opening new stages? Or do I have to have all the methods in one main class to open all the stages?
Thank you for any help.
no you don't need to have to have all the methods in one main class to open all the stages. you can create your new stages in other controller when they need to be built. for example in your login page, in the controller when a button is clicked And you want to go to main stage, code for the event be like:
FXMLLoader main = new FXMLLoader();
main.setLocation(getClass().getResource("adress"));
Parent mainParent = main.load();
Scene mainScene = new Scene(mainParent);
Scene currentScene = anItemOfProgram.getScene();
Stage stage = (Stage) currentScene.getWindow();
stage.setScene(mainScene);
and this is right way to create multiple stages

How to add JavaFX Pane to TornadoFX Component?

How do I add a JavaFX Pane to a TornadoFX vbox?
All I get is a blank window.
class TradingButtons : View() {
override val root = vbox {
ChartTest()
}
}
class ChartTest(vararg children: Node?) : Pane(*children) {
init {
val xAxis = CategoryAxis()
val yAxis = NumberAxis(1.0, 21.0, 0.1)
val lineChart = LineChart(xAxis, yAxis)
this.children.add(lineChart)
}
}
As per the documentation:
However, to actually show something on screen we want to populate this VBox acting as the root control. Using the initializer block, let's add a JavaFX Button and a Label.
Also take note of the tornadofx.* import. This is important and should be present in all your TornadoFX related files. The reason this is important is that some of the functionality of the framework isn't discoverable by the IDE without the import. This import enabled some advanced extension functions that you really don't want to live without :)
import tornadofx.*
class MyView: View() {
override val root = vbox {
button("Press me")
label("Waiting")
}
}
TornadoFX provides a builder syntax that will streamline your UI code. Instead of creating UI elements and manually adding them to the parent element's children list, the builders allow us to express the UI as a hierarchical structure which enables you to visualize the resulting UI very easily. Note that all builders are written in lowercase, so as to not confuse them with manual instantiation of the UI element classes.
I hope, this may helps.

Setting node layoutProperty() in FXML

I'm creating a UI for a project in javafx. I'm using CSS for the styles, FXML for the structure, and also .java controllers. I'm trying to make my node(s) (i.e. button, borderpane) layout bind to the scene size, so that the window can be resized and the layout stay the same. Normally if the node was defined in a jar file I would use:
button.layoutYProperty().bind((scene.heightProperty().divide(2)));
or something similar, but my nodes are defined within the FXML file.
How can I access the nodes from outside of the FXML file so that I can define the layout or how can I define the layout within the FXML file.
(I am not using and do not intend to use scene builder).
First, you should never need to do things like this. If you use layout panes you should always be able to choose a combination of layout panes and settings that automatically position the nodes as you want them. The solutions outlined below should never really be needed.
In the controller, you typically don't have direct access to the scene, so you need to listen for when the sceneProperty() is initialized on the node and act accordingly:
public class Controller {
#FXML
private Button button ;
public void initialize() {
button.sceneProperty().addListener((obs, oldScene, newScene) -> {
button.layoutYProperty().unbind();
if (newScene != null) {
button.layoutYProperty().bind(newScene.heightProperty().divide(2));
}
});
// ...
}
}
But again, the correct approach here is to choose appropriate layout panes to achieve what you want.

JavaFX Scene Builder - How can I access the components

I've build a Gui using the scene builder application. I've loaded it into my application but I want to add components to a VBox buried in the design. It seems that all i have access to use is the AnchorPanel that is returned from FXMLLoader.load.
Is there any way more elegant then drilling down the children tree's to get to the component i want?
Thanks.
If you need to add to the VBox from some random class:
give an fx:id to the VBox, say "vbox"
create a Controller for the view and associate it to the view in the FXML
in the Controller, add a #FXML VBox vbox; (where vbox it the same as the fx:id)
retrieve the controller from the FXMLLoader and access the VBox: controller.vbox;.
If you just need to add something to the VBox when your view is loaded, follow 1 to 3 above and add the relevant code in the initialize method of the Controller.

Which ChoiceBox-Event to choose?

I placed a ChoiceBox inside an fxml with JavaFX Scene Builder.
The FXML has a controller assigned to it.
My question is: Which event do I need to register if I want to know about changed values?
onInputMethodTextChanged="#languageSelectionModified"
this does not work with the following code
public void languageSelectionModified(Event event) {
ChoiceBox<String> box = (ChoiceBox<String>) event.getSource();
System.out.println(box.getValue());
}
and this only works for the initial click (i.e. opening the list, not when selecting an item):
onMouseClicked="#languageSelectionModified"
Although the Mouse-Events would never be a good choise because of situations where the touch or keyboard is the input-method, it still proves that the System.out can be reached.
I have absolutly no idea where those things are documentated (in the default Java-API they are not)
Add a listener to your #FXML injected choicebox in your controller:
choicebox.getSelectionModel().selectedItemProperty().addListener(choiceboxSelectionChangeListener);
You can also bind to the selected item:
label.textProperty().bind(choicebox.getSelectionModel().selectedItemProperty());
Here is an example of hooking up a listener in a controller for a ComboBox defined in FXML. Logic for a ChoiceBox is pretty much identical.
You can also use FXML onAction attribute:
<ChoiceBox onAction="#languageSelectionModified" />

Categories

Resources