JavaFX: How to refer to another object with the same fxml file? - javafx

I have got an FXML file in which there is a custom component declared. This component has some logic that requires a reference to another component declared in the same fxml file. The FXML file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.Hyperlink?>
<?import javafx.scene.layout.AnchorPane?>
<BorderPane xmlns:fx="http://javafx.com/fxml" prefWidth="800" prefHeight="400" fx:controller="test.MyController">
<top>
<HBox spacing="10">
<Label text="Test"/>
<TextField fx:id="testField"/>
</HBox>
</top>
<center>
<AnchorPane>
<children>
<VBox fx:id="customBox" visible="false" prefHeight="400" prefWidth="400"
VBox.vgrow="ALWAYS"
initiator="#testField"/>
</children>
</AnchorPane>
</center>
</BorderPane>
So, I need to set the initiator property of customBox. With this, I am getting Caused by: java.lang.IllegalArgumentException: Unable to coerce #testField to class javafx.scene.control.TextField. Any suggestions?

I don't have time to test this, but I think
<KontrollkoderVBox fx:id="customBox" visible="false" prefHeight="400" prefWidth="400"
VBox.vgrow="ALWAYS"
initiator="$testField"/>
will work. See "variable resolution" in the FXML documentation.
You can even do things like binding a StringProperty in KontrolkoderVBox to the TextField's textProperty() by referencing ${testField.text}.

You may set the id of textField (say id="testFieldId" which is different from fx:id) into initiator and do lookup:
// in VBox #customBox
TextField tf = (TextField) getScene().lookup(getInitiator());
where getInitiator() returns String = "#testFieldId".

Related

adding a pane inside Borderpane fxml Javafx

I made an anchorpane with an fxml and a controller. I also made a borderpane with a view, fxml and another controller. How can I add the anchorpane inside the borderpane? The reason I want them in separate fxml and controller is that the borderpane is a lot of code and this would make everything look cleaner.
I thought it would work like this but it doesn't.
Borderfxml:
?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.textfield.*?>
<BorderPane fx:controller="Bordercontroller" xmlns:fx="http://javafx.com/fxml"
prefHeight="200" prefWidth="320">
<top>
</top>
<left>
</left>
<center>
</center>
<right>
<Anchorpane fx:id="Same id as my anchorpane"/>
</right>
<bottom>
</bottom>
</BorderPane>

Using Unicode characters with JavaFX

I've been playing around with swing for some time and decided to check out FX now. So far I'm finding it a lot easier and more fun to work with as compared to swing but I've run into a small speed bump and after hours of looking around I just can't find a solution.
I am unable to use \u when I try to add it through the fxml file It works fine if I don't use the fxml but I want to use the scene builder as it is more convenient.
Here's the small piece of code:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.131" fx:controller="baitform.designDocController">
<children>
<Button fx:id="button" layoutX="126" layoutY="90" onAction="#handleButtonAction" text="Click Me!" />
<Label layoutX="145.0" layoutY="129.0" text="\u0644\u0627\u062B\u0627\u0646\u0649" />
</children>
</AnchorPane>
The error I keep getting is
Caused by: javafx.fxml.LoadException: Invalid escape sequence.
Not sure if relevant, but I'm using jdk1.8.0_131 & netbeans 8.2
If anyone could point me in the right direction here I'd really appreciate it.
FXML is an XML, and so you need to use XML escaping:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/8.0.131" fx:controller="baitform.designDocController">
<children>
<Button fx:id="button" layoutX="126" layoutY="90" onAction="#handleButtonAction" text="Click Me!" />
<Label layoutX="145.0" layoutY="129.0" text="لاثانى" />
</children>
</AnchorPane>
That being said, if you are able to input the characters, you can just insert them as is.
See also: https://www.w3.org/International/questions/qa-escapes

How to use the CSS file in JavaFX project?

i'm trying to build a JavaFX Application and i want to attach the CSS file in the FXML file but when i try to run the app i get a problem like: Property "stylesheets" does not exist or is read-only. in the console i don't know what is the problem exactly (note if i delete the CSS file everything works fine).
The CSS file "csstyle.css" contains:
/*
* Empty Stylesheet file.
*/
.mainFxmlClass {
-fx-background-color: blue;
}
Also i wrote in the Stylesheet in the FXML file the name of the CSS file also in the Style Class : .mainFxmlClass .
So i want to know the error please help me and thanks :)
You have two problems:
The first one is already solved here. Remove
stylesheets="#csstyle.css"
and add it right after the <children> tags of your root container. Since you don't show how is your FXML file, this is how it should look like:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import java.net.*?>
<AnchorPane styleClass="mainFxmlClass" ...>
<children>
...
</children>
<stylesheets>
<URL value="#cssstyle.css" />
</stylesheets>
</AnchorPane>
The second is this one:
styleClass=".mainFxmlClass"
Remove the dot:
styleClass="mainFxmlClass"
EDIT
Given these solutions didn't work and the fact that the OP is using JDK 7 with JavaFX 2.0 these other solutions may help:
Replace:
styleClass="mainFxmlClass"
with:
<styleClass>
<String fx:value="mainFxmlClass"/>
</styleClass>
So your FXML will be like this:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import java.net.*?>
<AnchorPane ...>
<children>
...
</children>
<styleClass>
<String fx:value="mainFxmlClass"/>
</styleClass>
<stylesheets>
<URL value="#cssstyle.css" />
</stylesheets>
</AnchorPane>
And try it again.
Finally, if it is not working, remove the <stylesheets> tags, and set the stylesheet file on your Scene:
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("cssstyle.css").toExternalForm());
So your FXML will be like this:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<AnchorPane ...>
<children>
...
</children>
<styleClass>
<String fx:value="mainFxmlClass"/>
</styleClass>
</AnchorPane>
It's really advisable updating JavaFX to newer versions (2.2.45 is the last one for Java 7), and benefit from many new features added.

JavaFX: how to set a value of a Label to a system property in fxml?

In my application I defined the GUI in FXML. There is a label that always show the version of java. Is it possible to make it show this information without coding it in the controller?
I am thinking something like this:
<Label fx:id="info" fx:value="$java.version"/>
But this of course does not work. Is there a way?
So you don't want to set it via controller class.
Then you can utilize javascripting feature of FXML:
<?language javascript?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<VBox prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="my.FXMLDocumentController">
<fx:script>
var myText = 'version: ' + java.lang.System.getProperty('java.version');
</fx:script>
<children>
<Label text="$myText" />
</children>
</VBox>

How to attach a CSS stylesheet to FXML?

Following Oracle tutorial http://docs.oracle.com/javafx/2/get_started/fxml_tutorial.htm, I create FXML with a fragment
<?xml version="1.0" encoding="UTF-8"?>
<?language javascript?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<GridPane alignment="CENTER" gridLinesVisible="true" hgap="10.0" vgap="10.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="fxmlexample.FXMLExampleController" styleClass="root" >
...other stuff...
<stylesheets>
<URL value="#Login.css" />
</stylesheets>
</GridPane>
NetBeans 8.0 colors the URL red and says: "Class does not exist: URL".
When compiled and run, JRE 1.8 also throws an exception:
...
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: javafx.fxml.LoadException: URL is not a valid type.
file:/C:/Users/User1/Documents/NetBeansProjects/FXMLExample/dist/run1970052180/FXMLExample.jar!/fxmlexample/fxml_example.fxml:46
If I open the fxml_example.fxml file in JavaFX Scene Builder 1.1", it also complains about missing types, elements of which will not be shown:
Missing types are: [URL]
Everyone seems to be using <URL/> elements, why cannot I?
URL is a class in the java.net package; you should import it from the FXML:
<?import java.net.*?>

Resources