|
|
Re: JavaFX code from FXML [message #1670211 is a reply to message #1668380] |
Fri, 13 March 2015 05:34 |
Lofi Mayer Messages: 8 Registered: June 2014 |
Junior Member |
|
|
I very much would like to use an fxml and a controller. But e. g. I tried out JDK8u40 and all of a sudden my code wasn't running on Java 7 anymore. And that's for no reason, because it's rather simple. So my solution was to convert the fxml to Java. Another reason for using a Java class is performance. When you have to create a 1000 nodes, the fxml parsing may take its toll.
To make things short, let's say we have this Sample.fxml. It's just some containers for the layouting, 2 named textfields and 1 named button:
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<center>
<GridPane BorderPane.alignment="CENTER">
<columnConstraints>
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
</columnConstraints>
<rowConstraints>
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
</rowConstraints>
<children>
<Label text="Label" />
<Label text="Label" GridPane.rowIndex="1" />
<TextField fx:id="nameTextField" GridPane.columnIndex="1" />
<TextField fx:id="valueTextField" GridPane.columnIndex="1" GridPane.rowIndex="1" />
</children>
</GridPane>
</center>
<bottom>
<Pane prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<Button fx:id="submitButton" layoutX="274.0" layoutY="75.0" mnemonicParsing="false" text="Button" />
</children>
</Pane>
</bottom>
</BorderPane>
In e(fx)clipse I can create the controller. It generates something like this:
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
public class Sample {
@FXML
private TextField nameTextField;
@FXML
private TextField valueTextField;
@FXML
private Button submitButton;
}
Generating the Java code could be like this:
public class Sample extends BorderPane {
@FXML TextField nameTextField;
@FXML TextField valueTextField;
@FXML Button submitButton;
public Sample() {
initComponents();
}
public void initComponents() {
setMaxHeight(Double.NEGATIVE_INFINITY);
setMaxWidth(Double.NEGATIVE_INFINITY);
setMinHeight(Double.NEGATIVE_INFINITY);
setMinWidth(Double.NEGATIVE_INFINITY);
setPrefHeight(400.0);
setPrefWidth(600.0);
{
GridPane e_1 = new GridPane();
{
ColumnConstraints e_2 = new ColumnConstraints();
e_2.setHgrow(javafx.scene.layout.Priority.SOMETIMES);
e_2.setMinWidth(10.0);
e_2.setPrefWidth(100.0);
e_1.getColumnConstraints().add(e_2);
}
{
ColumnConstraints e_3 = new ColumnConstraints();
e_3.setHgrow(javafx.scene.layout.Priority.SOMETIMES);
e_3.setMinWidth(10.0);
e_3.setPrefWidth(100.0);
e_1.getColumnConstraints().add(e_3);
}
{
RowConstraints e_4 = new RowConstraints();
e_4.setMinHeight(10.0);
e_4.setPrefHeight(30.0);
e_4.setVgrow(javafx.scene.layout.Priority.SOMETIMES);
e_1.getRowConstraints().add(e_4);
}
{
RowConstraints e_5 = new RowConstraints();
e_5.setMinHeight(10.0);
e_5.setPrefHeight(30.0);
e_5.setVgrow(javafx.scene.layout.Priority.SOMETIMES);
e_1.getRowConstraints().add(e_5);
}
{
RowConstraints e_6 = new RowConstraints();
e_6.setMinHeight(10.0);
e_6.setPrefHeight(30.0);
e_6.setVgrow(javafx.scene.layout.Priority.SOMETIMES);
e_1.getRowConstraints().add(e_6);
}
{
Label e_7 = new Label();
e_7.setText("Label");
e_1.getChildren().add(e_7);
}
{
Label e_8 = new Label();
e_8.setText("Label");
e_1.getChildren().add(e_8);
GridPane.setRowIndex(e_8,1);
}
{
nameTextField = new TextField();
e_1.getChildren().add(nameTextField);
GridPane.setColumnIndex(nameTextField,1);
}
{
valueTextField = new TextField();
e_1.getChildren().add(valueTextField);
GridPane.setColumnIndex(valueTextField,1);
GridPane.setRowIndex(valueTextField,1);
}
setCenter(e_1);
// an enum type
BorderPane.setAlignment(e_1,javafx.geometry.Pos.CENTER);
}
{
Pane e_9 = new Pane();
e_9.setPrefHeight(200.0);
e_9.setPrefWidth(200.0);
{
submitButton = new Button();
submitButton.setLayoutX(274.0);
submitButton.setLayoutY(75.0);
submitButton.setMnemonicParsing(false);
submitButton.setText("Button");
e_9.getChildren().add(submitButton);
}
setBottom(e_9);
// an enum type
BorderPane.setAlignment(e_9,javafx.geometry.Pos.CENTER);
}
}
}
i. e. the named components are class members, the unnamed ones can remain e_### inside the method.
Works perfectly fine without any external dependency, compatible with Java 7 and Java 8. However, you lose the FXML binding. But I rather prefer to have a compatible and performing program than to have one where you see only at runtime whether or not it works in various environments. I know it's ugly and we've had this for years now, but it's a fallback solution in case you run into problems. You could still load the fxml for proper environments.
Another suggestion would be to simply not use these e_### names and instead use the string identifier and declare it on top of the method. That way one could manually do as I suggest - if need be.
|
|
|
Re: JavaFX code from FXML [message #1678563 is a reply to message #1670211] |
Mon, 16 March 2015 08:43 |
Thomas Schindl Messages: 6651 Registered: July 2009 |
Senior Member |
|
|
Hi,
ok but why do you don't want to keep the controller and UI in seperate
classes, if you would have used package visibility no reflection code
would be generated.
So the code generated would be:
public class Sample extends FXMLDocument<BorderPane> {
Sample _c;
public BorderPane load(LoadData<BorderPane> loadData) {
final Callback<Class<?>, Object> controllerFactory =
loadData.controllerFactory;
if( controllerFactory != null ) {
_c = controllerFactory.call(Sample.class);
} else {
_c = new Sample();
}
// ....
{
TextField e_xx = new TextField();
e_1.getChildren().add(e_x);
GridPane.setColumnIndex(nameTextField,1);
getController().nameTextField = e_x;
}
}
}
So the only real change needed is that the fields in your controller are
package private.
The FXML => Java translator keeps the semantics of FXMLLoader providing
you a transparent and works in conjunction with ExtendedFXMLLoader and
we also make use of the Image & URLBuilder found in the core.fxml
project (which is the sole dependency you need to add).
We could certainly add your preferred way of code generation, so feel
free to file a bug but we currently can only implement this (in the 2.0
timeframe) if you sponsor the development, so its up to you how
important you think it is to get rid of the one additional jar file.
Tom
On 13.03.15 06:34, Lofi Mayer wrote:
> I very much would like to use an fxml and a controller. But e. g. I
> tried out JDK8u40 and all of a sudden my code wasn't running on Java 7
> anymore. And that's for no reason, because it's rather simple. So my
> solution was to convert the fxml to Java. Another reason for using a
> Java class is performance. When you have to create a 1000 nodes, the
> fxml parsing may take its toll.
>
> To make things short, let's say we have this Sample.fxml. It's just some
> containers for the layouting, 2 named textfields and 1 named button:
>
> <BorderPane maxHeight="-Infinity" maxWidth="-Infinity"
> minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0"
> prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.40"
> xmlns:fx="http://javafx.com/fxml/1">
> <center>
> <GridPane BorderPane.alignment="CENTER">
> <columnConstraints>
> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
> prefWidth="100.0" />
> <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0"
> prefWidth="100.0" />
> </columnConstraints>
> <rowConstraints>
> <RowConstraints minHeight="10.0" prefHeight="30.0"
> vgrow="SOMETIMES" />
> <RowConstraints minHeight="10.0" prefHeight="30.0"
> vgrow="SOMETIMES" />
> <RowConstraints minHeight="10.0" prefHeight="30.0"
> vgrow="SOMETIMES" />
> </rowConstraints>
> <children>
> <Label text="Label" />
> <Label text="Label" GridPane.rowIndex="1" />
> <TextField fx:id="nameTextField" GridPane.columnIndex="1" />
> <TextField fx:id="valueTextField" GridPane.columnIndex="1"
> GridPane.rowIndex="1" />
> </children>
> </GridPane>
> </center>
> <bottom>
> <Pane prefHeight="200.0" prefWidth="200.0"
> BorderPane.alignment="CENTER">
> <children>
> <Button fx:id="submitButton" layoutX="274.0" layoutY="75.0"
> mnemonicParsing="false" text="Button" />
> </children>
> </Pane>
> </bottom>
> </BorderPane>
>
>
> In e(fx)clipse I can create the controller. It generates something like
> this:
>
> import javafx.fxml.FXML;
> import javafx.scene.control.Button;
> import javafx.scene.control.TextField;
>
> public class Sample {
>
> @FXML
> private TextField nameTextField;
>
> @FXML
> private TextField valueTextField;
>
> @FXML
> private Button submitButton;
> }
>
>
> Generating the Java code could be like this:
>
>
> public class Sample extends BorderPane {
>
> @FXML TextField nameTextField;
> @FXML TextField valueTextField;
> @FXML Button submitButton;
>
> public Sample() {
> initComponents();
> }
>
> public void initComponents() {
>
> setMaxHeight(Double.NEGATIVE_INFINITY);
> setMaxWidth(Double.NEGATIVE_INFINITY);
> setMinHeight(Double.NEGATIVE_INFINITY);
> setMinWidth(Double.NEGATIVE_INFINITY);
> setPrefHeight(400.0);
> setPrefWidth(600.0);
> {
> GridPane e_1 = new GridPane();
> {
> ColumnConstraints e_2 = new ColumnConstraints();
> e_2.setHgrow(javafx.scene.layout.Priority.SOMETIMES);
> e_2.setMinWidth(10.0);
> e_2.setPrefWidth(100.0);
> e_1.getColumnConstraints().add(e_2);
> }
> {
> ColumnConstraints e_3 = new ColumnConstraints();
> e_3.setHgrow(javafx.scene.layout.Priority.SOMETIMES);
> e_3.setMinWidth(10.0);
> e_3.setPrefWidth(100.0);
> e_1.getColumnConstraints().add(e_3);
> }
> {
> RowConstraints e_4 = new RowConstraints();
> e_4.setMinHeight(10.0);
> e_4.setPrefHeight(30.0);
> e_4.setVgrow(javafx.scene.layout.Priority.SOMETIMES);
> e_1.getRowConstraints().add(e_4);
> }
> {
> RowConstraints e_5 = new RowConstraints();
> e_5.setMinHeight(10.0);
> e_5.setPrefHeight(30.0);
> e_5.setVgrow(javafx.scene.layout.Priority.SOMETIMES);
> e_1.getRowConstraints().add(e_5);
> }
> {
> RowConstraints e_6 = new RowConstraints();
> e_6.setMinHeight(10.0);
> e_6.setPrefHeight(30.0);
> e_6.setVgrow(javafx.scene.layout.Priority.SOMETIMES);
> e_1.getRowConstraints().add(e_6);
> }
> {
> Label e_7 = new Label();
> e_7.setText("Label");
> e_1.getChildren().add(e_7);
> }
> {
> Label e_8 = new Label();
> e_8.setText("Label");
> e_1.getChildren().add(e_8);
> GridPane.setRowIndex(e_8,1);
> }
> {
> nameTextField = new TextField();
> e_1.getChildren().add(nameTextField);
> GridPane.setColumnIndex(nameTextField,1);
> }
> {
> valueTextField = new TextField();
> e_1.getChildren().add(valueTextField);
> GridPane.setColumnIndex(valueTextField,1);
> GridPane.setRowIndex(valueTextField,1);
> }
> setCenter(e_1);
>
> // an enum type
> BorderPane.setAlignment(e_1,javafx.geometry.Pos.CENTER);
> }
> {
> Pane e_9 = new Pane();
> e_9.setPrefHeight(200.0);
> e_9.setPrefWidth(200.0);
> {
> submitButton = new Button();
> submitButton.setLayoutX(274.0);
> submitButton.setLayoutY(75.0);
> submitButton.setMnemonicParsing(false);
> submitButton.setText("Button");
> e_9.getChildren().add(submitButton);
> }
> setBottom(e_9);
>
> // an enum type
> BorderPane.setAlignment(e_9,javafx.geometry.Pos.CENTER);
> }
> }
> }
>
> i. e. the named components are class members, the unnamed ones can
> remain e_### inside the method.
>
> Works perfectly fine without any external dependency, compatible with
> Java 7 and Java 8. However, you lose the FXML binding. But I rather
> prefer to have a compatible and performing program than to have one
> where you see only at runtime whether or not it works in various
> environments. I know it's ugly and we've had this for years now, but
> it's a fallback solution in case you run into problems. You could still
> load the fxml for proper environments.
>
> Another suggestion would be to simply not use these e_### names and
> instead use the string identifier and declare it on top of the method.
> That way one could manually do as I suggest - if need be.
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03672 seconds