... | @@ -4,79 +4,45 @@ Building a view |
... | @@ -4,79 +4,45 @@ Building a view |
|
The composition mechanism
|
|
The composition mechanism
|
|
-------------------------
|
|
-------------------------
|
|
|
|
|
|
The composition mechanism integrated in AF3’s kernel aims at improving
|
|
The composition mechanism integrated in AF3’s kernel aims at improving the reusability of both layouts and controllers and reduce the overall complexity of user interface development through modularity.
|
|
the reusability of both layouts and controllers and reduce the overall
|
|
|
|
complexity of user interface development through modularity.
|
|
Complex user interfaces can be hierarchically decomposed into smaller, reusable views w.r.t. both layout and logic. This is achieved by allowing each view to define containers where sub-views can be inserted.
|
|
|
|
This way repeating UI elements can be defined once, and reused wherever needed.
|
|
Complex user interfaces can be hierarchically decomposed into smaller,
|
|
|
|
reusable views w.r.t. both layout and logic. This is achieved by
|
|
Each view refers to its own FXML layout file and implements the controller logic for the interface elements it defines. This way not only the layout can be reused, but - most notably - the view’s logic as well.
|
|
allowing each view to define containers where sub-views can be inserted.
|
|
|
|
This way repeating UI elements can be defined once, and reused wherever
|
|
The composition framework is build around the `ICompositeFXController`, an interface for the hierarchic composition of controllers (and their layouts, respectively). Controllers implementing this interface can be containments of other such controllers and take containments as well.
|
|
needed.
|
|
|
|
|
|
|
|
Each view refers to its own FXML layout file and implements the
|
|
|
|
controller logic for the interface elements it defines. This way not
|
|
|
|
only the layout can be reused, but - most notably - the view’s logic as
|
|
|
|
well.
|
|
|
|
|
|
|
|
The composition framework is build around the `ICompositeFXController`,
|
|
|
|
an interface for the hierarchic composition of controllers (and their
|
|
|
|
layouts, respectively). Controllers implementing this interface can be
|
|
|
|
containments of other such controllers and take containments as well.
|
|
|
|
The following figure illustrates the concept:
|
|
The following figure illustrates the concept:
|
|
|
|
|
|
![](composition_illustration.png)
|
|
![](composition_illustration.png)
|
|
|
|
|
|
The illustration also captures how the hierarchic controllers are
|
|
The illustration also captures how the hierarchic controllers are integrated with AutoFOCUS 3: As `ICompositeFXController` s can - and should be - reused in multiple views, they cannot be used to uniquely
|
|
integrated with AutoFOCUS 3: As `ICompositeFXController` s can - and
|
|
identify a single view. Thus, for AF3 to reference all views within `plugin.xml` files, an almost empty class deriving from `AF3FXViewPart` is created for each of them. It contains nothing but a constructor with
|
|
should be - reused in multiple views, they cannot be used to uniquely
|
|
no parameters, passing an instance of the top-most `ICompositeFXController` to the `super` constructor.
|
|
identify a single view. Thus, for AF3 to reference all views within
|
|
|
|
`plugin.xml` files, an almost empty class deriving from `AF3FXViewPart`
|
|
This presentation includes a more comprehensive explanation of the composition framework and how it is applied:
|
|
is created for each of them. It contains nothing but a constructor with
|
|
|
|
no parameters, passing an instance of the top-most
|
|
|
|
`ICompositeFXController` to the `super` constructor.
|
|
|
|
|
|
|
|
This presentation includes a more comprehensive explanation of the
|
|
|
|
composition framework and how it is applied:
|
|
|
|
attachment:af3\_javafx\_composites.pdf
|
|
attachment:af3\_javafx\_composites.pdf
|
|
|
|
|
|
Creating a user interface.
|
|
Creating a user interface.
|
|
--------------------------
|
|
--------------------------
|
|
|
|
|
|
As the loading mechanism for FXML files is common to all JavaFX
|
|
As the loading mechanism for FXML files is common to all JavaFX controllers, the abstract `CompositeFXControllerBase` class is introduced. It implements the `ICompositeFXController` interface and implements the `getOrLoadLayout()` method while keeping all other methods abstract.
|
|
controllers, the abstract `CompositeFXControllerBase` class is
|
|
|
|
introduced. It implements the `ICompositeFXController` interface and
|
|
With the loading logic taken care of, just follow these steps to create a new view within AF3:
|
|
implements the `getOrLoadLayout()` method while keeping all other
|
|
|
|
methods abstract.
|
|
1. Create a new class for the view’s controller extending `CompositeFXControllerBase`.
|
|
|
|
2. If the view is supposed contain other `IComponentFXController` s, pass them to the `super` constructor (otherwise call it without any argument).
|
|
With the loading logic taken care of, just follow these steps to create
|
|
3. Declare the name of the FXML file by overriding the `getFXMLLocation()`.
|
|
a new view within AF3:
|
|
4. Specify how to initialize the view and how to add the given containments (if there are any) in the
|
|
|
|
|
|
1. Create a new class for the view’s controller extending
|
|
|
|
`CompositeFXControllerBase`.
|
|
|
|
2. If the view is supposed contain other `IComponentFXController` s,
|
|
|
|
pass them to the `super` constructor (otherwise call it without any
|
|
|
|
argument).
|
|
|
|
3. Declare the name of the FXML file by overriding the
|
|
|
|
`getFXMLLocation()`.
|
|
|
|
4. Specify how to initialize the view and how to add the given
|
|
|
|
containments (if there are any) in the
|
|
|
|
`initialize(ICompositeFXController[] containments)` method.
|
|
`initialize(ICompositeFXController[] containments)` method.
|
|
5. In order to register a view within the Eclipse platform framework,
|
|
5. In order to register a view within the Eclipse platform framework, the top-most component has to be referenced by a unique wrapper class. This is achieved by creating a class deriving from `AF3FXViewpart`, containing nothing but a constructor with no parameters, passing an instance of the top-most `ICompositeFXController` to the `super` constructor. This class can then be registered in a `plugin.xml` file as a view.
|
|
the top-most component has to be referenced by a unique wrapper
|
|
|
|
class. This is achieved by creating a class deriving from
|
|
|
|
`AF3FXViewpart`, containing nothing but a constructor with no
|
|
|
|
parameters, passing an instance of the top-most
|
|
|
|
`ICompositeFXController` to the `super` constructor. This class can
|
|
|
|
then be registered in a `plugin.xml` file as a view.
|
|
|
|
|
|
|
|
Appendix
|
|
Appendix
|
|
--------
|
|
--------
|
|
|
|
|
|
### Examples
|
|
### Examples
|
|
|
|
|
|
If you don’t want to follow along step-by-step, here are the FXML and
|
|
If you don’t want to follow along step-by-step, here are the FXML and Java files for the following examples:
|
|
Java files for the following examples:
|
|
|
|
|
|
|
|
- attachment:HelloWorldLayout.fxml
|
|
- attachment:HelloWorldLayout.fxml
|
|
- attachment:HelloWorldFXController.java
|
|
- attachment:HelloWorldFXController.java
|
... | @@ -84,22 +50,11 @@ Java files for the following examples: |
... | @@ -84,22 +50,11 @@ Java files for the following examples: |
|
|
|
|
|
#### Let’s say hello to the world.
|
|
#### Let’s say hello to the world.
|
|
|
|
|
|
1. Navigate to the `playground` package in the `src` folder of the
|
|
1. Navigate to the `playground` package in the `src` folder of the `org.fortiss.af3.exploration.ui` plugin.`*`
|
|
`org.fortiss.af3.exploration.ui` plugin.`*`
|
|
2. Create a new class, called `HelloWorldFXController.java`, deriving from `CompositeFXControllerBase`. The IDE will then either tell you to implement the parent’s abstract methods or it will create stubs for the `getFXMLLocation` and `initialize` methods.
|
|
2. Create a new class, called `HelloWorldFXController.java`, deriving
|
|
3. As of now, we don’t have anything to initialize, thus you can leave the respective method empty (but don’t forget to comment the reason for the empty block!).
|
|
from `CompositeFXControllerBase`. The IDE will then either tell you
|
|
4. Now let’s take care of the view’s layout. Start by using the `getFXMLLocation` method to return the name of the FXML file. In our case the only line in that method will read `return "HelloWorldLayout.fxml"`. Your class should look something like this by now:
|
|
to implement the parent’s abstract methods or it will create stubs
|
|
|
|
for the `getFXMLLocation` and `initialize` methods.
|
|
|
|
3. As of now, we don’t have anything to initialize, thus you can leave
|
|
|
|
the respective method empty (but don’t forget to comment the reason
|
|
|
|
for the empty block!).
|
|
|
|
4. Now let’s take care of the view’s layout. Start by using the
|
|
|
|
`getFXMLLocation` method to return the name of the FXML file. In our
|
|
|
|
case the only line in that method will read
|
|
|
|
`return "HelloWorldLayout.fxml"`. Your class should look something
|
|
|
|
like this by now:
|
|
|
|
|
|
|
|
```java">
|
|
|
|
package org.fortiss.af3.exploration.ui.playground;
|
|
package org.fortiss.af3.exploration.ui.playground;
|
|
|
|
|
|
import org.fortiss.tooling.common.ui.javafx.layout.compositefxcontrollerbase;
|
|
import org.fortiss.tooling.common.ui.javafx.layout.compositefxcontrollerbase;
|
... | @@ -128,29 +83,11 @@ Java files for the following examples: |
... | @@ -128,29 +83,11 @@ Java files for the following examples: |
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
```
|
|
|
|
5. now navigate to the same `playground` package within the same
|
|
5. now navigate to the same `playground` package within the same plugin - but this time in the `res` folder! once there, create a new `helloworldlayout.fxml` file and open it using the scenebuilder (see appendix on how to set it u make sure that your file and folder structure looks like this by now: ![](hello-world_files-and-folders.png)
|
|
plugin - but this time in the `res` folder! once there, create a new
|
|
6. in the scenebuilder drag and drop a `pane` in the preview window and resize it as you want. then do the same with a `label`, placing it somewhere on the pane. if you don’t like the label to read “label” feel free to change the text. once you’re happy with the result save the file and switch back to eclipse.
|
|
`helloworldlayout.fxml` file and open it using the scenebuilder (see
|
|
7. the view is now complete! however, we still need to register it in the plugin’s `plugin.xml` file, otherwise you won’t be able to open it. to do so, navigate to the same package where the `helloworldfxcontroller.java` is located (back in the `src` folder) and create another class called “helloworldfxviewpart.java”, this time deriving from `af3fxviewpart`. now add a constructor (eclipse will force you anyways), and remove all parameters. it is only needed to contain a call to the `super` constructor passing an instance of the `helloworldfxcontroller` (as we don’t have css style sheets, the second parameter can be `null`).
|
|
appendix on how to set it u make sure that your file and folder
|
|
|
|
structure looks like this by now:
|
|
|
|
![](hello-world_files-and-folders.png)
|
|
|
|
6. in the scenebuilder drag and drop a `pane` in the preview window and
|
|
|
|
resize it as you want. then do the same with a `label`, placing it
|
|
|
|
somewhere on the pane. if you don’t like the label to read “label”
|
|
|
|
feel free to change the text. once you’re happy with the result save
|
|
|
|
the file and switch back to eclipse.
|
|
|
|
7. the view is now complete! however, we still need to register it in
|
|
|
|
the plugin’s `plugin.xml` file, otherwise you won’t be able to open
|
|
|
|
it. to do so, navigate to the same package where the
|
|
|
|
`helloworldfxcontroller.java` is located (back in the `src` folder)
|
|
|
|
and create another class called “helloworldfxviewpart.java”, this
|
|
|
|
time deriving from `af3fxviewpart`. now add a constructor (eclipse
|
|
|
|
will force you anyways), and remove all parameters. it is only
|
|
|
|
needed to contain a call to the `super` constructor passing an
|
|
|
|
instance of the `helloworldfxcontroller` (as we don’t have css style
|
|
|
|
sheets, the second parameter can be `null`).
|
|
|
|
<code class="java">
|
|
|
|
package org.fortiss.af3.exploration.ui.playground;
|
|
package org.fortiss.af3.exploration.ui.playground;
|
|
|
|
|
|
import org.fortiss.tooling.common.ui.javafx.af3fxviewpart;
|
|
import org.fortiss.tooling.common.ui.javafx.af3fxviewpart;
|
... | @@ -171,45 +108,35 @@ Java files for the following examples: |
... | @@ -171,45 +108,35 @@ Java files for the following examples: |
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
```
|
|
|
|
8. the last step: register the view by adding a `view` extension to the
|
|
8. the last step: register the view by adding a `view` extension to the
|
|
`plugin.xml` file as follows:
|
|
`plugin.xml` file as follows:
|
|
<code class="xml"><view
|
|
|
|
|
|
<view
|
|
class="org.fortiss.af3.exploration.ui.playground.helloworldfxviewpart"
|
|
class="org.fortiss.af3.exploration.ui.playground.helloworldfxviewpart"
|
|
id="org.fortiss.af3.exploration.ui.playground.helloworldfxviewpart"
|
|
id="org.fortiss.af3.exploration.ui.playground.helloworldfxviewpart"
|
|
name="hello world"
|
|
name="hello world"
|
|
restorable="true">
|
|
restorable="true">
|
|
</view>
|
|
</view>
|
|
```
|
|
|
|
9. now run af3, type “hello world” into the “quick access” and enjoy
|
|
9. now run af3, type “hello world” into the “quick access” and enjoy
|
|
your view!
|
|
your view!
|
|
|
|
|
|
`*` note that the same gui can be created in any other plugin and
|
|
`*` note that the same gui can be created in any other plugin and package as long as it can access the `org.fortiss.tooling.common.ui` kernel plugin. however, in the second part of this example we will use
|
|
package as long as it can access the `org.fortiss.tooling.common.ui`
|
|
another view defined in the `org.fortiss.af3.exploration.ui`. thus, it is recommended to create the view in the same plugin so as to keep things as straightforward as possible in this example.
|
|
kernel plugin. however, in the second part of this example we will use
|
|
|
|
another view defined in the `org.fortiss.af3.exploration.ui`. thus, it
|
|
|
|
is recommended to create the view in the same plugin so as to keep
|
|
|
|
things as straightforward as possible in this example.
|
|
|
|
|
|
|
|
#### let’s compose something.
|
|
#### let’s compose something.
|
|
|
|
|
|
you have decided that you want to add your “hello world” to the dse
|
|
you have decided that you want to add your “hello world” to the dse view, with the same frame containing the “back” and the “help” buttons.
|
|
view, with the same frame containing the “back” and the “help” buttons.
|
|
|
|
here comes the magic:
|
|
here comes the magic:
|
|
|
|
|
|
1. open the `helloworldfxviewpart.java` and instead of passing an
|
|
1. open the `helloworldfxviewpart.java` and instead of passing an instance of the `helloworldfxcontroller` to the super constructor, we now pass a new instance of the `explorationuifxcontroller` - to which we pass the new instance of the `helloworldfxcontroller` as well as a title we want to show in the header bar e.g. “hello world!”. this way
|
|
instance of the `helloworldfxcontroller` to the super constructor,
|
|
|
|
we now pass a new instance of the `explorationuifxcontroller` - to
|
|
|
|
which we pass the new instance of the `helloworldfxcontroller` as
|
|
|
|
well as a title we want to show in the header bar e.g. “hello
|
|
|
|
world!”. this way
|
|
|
|
<code class="java">super(new helloworldfxcontroller(), null);
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
super(new helloworldfxcontroller(), null);
|
|
|
|
|
|
becomes
|
|
becomes
|
|
<code class="java">super(new explorationuifxcontroller(new helloworldfxcontroller(), "hello world!"), null);
|
|
|
|
```
|
|
super(new explorationuifxcontroller(new helloworldfxcontroller(), "hello world!"), null);
|
|
|
|
|
|
2. that’s all. run af3 and open your view!
|
|
2. that’s all. run af3 and open your view!
|
|
|
|
|
|
#### let’s get some action going.
|
|
#### let’s get some action going.
|
... | @@ -218,22 +145,14 @@ you like greetings but want something more? your fancy some buttons? |
... | @@ -218,22 +145,14 @@ you like greetings but want something more? your fancy some buttons? |
|
luckily, we’ve got you covered:
|
|
luckily, we’ve got you covered:
|
|
|
|
|
|
1. open the `helloworldlayout.fxml` using the scenebuilder:
|
|
1. open the `helloworldlayout.fxml` using the scenebuilder:
|
|
1. add a `textfield` with the `fx:id` set to `nametextfield`. the
|
|
1. add a `textfield` with the `fx:id` set to `nametextfield`. the respective setting is located in the `code` tab of the right accordion.
|
|
respective setting is located in the `code` tab of the right
|
|
2. add a `button` with the `fx:id` set to `submitbutton`. in the same `code` tab where you set the `fx:id` look for the `onaction` option and set it to `onsubmit`.
|
|
accordion.
|
|
3. delete the text of the “hello world!” label and set its `fx:id` to `displaylabel`.
|
|
2. add a `button` with the `fx:id` set to `submitbutton`. in the
|
|
4. don’t forget to save your changes!
|
|
same `code` tab where you set the `fx:id` look for the
|
|
|
|
`onaction` option and set it to `onsubmit`.
|
|
|
|
3. delete the text of the “hello world!” label and set its `fx:id`
|
|
|
|
to `displaylabel`.
|
|
|
|
4. don’t forget to save your changes!
|
|
|
|
2. now switch back to eclipse to implement some actions:
|
|
2. now switch back to eclipse to implement some actions:
|
|
1. open the `helloworldfxcontroller` class.
|
|
1. open the `helloworldfxcontroller` class.
|
|
2. reference each ui element by creating a private instance
|
|
2. reference each ui element by creating a private instance variable with the respecive javafx type for each of them. make sure to annotate each of them with the `fxml` annotation and to name them exactly the same as their `fx:id`!
|
|
variable with the respecive javafx type for each of them. make
|
|
|
|
sure to annotate each of them with the `fxml` annotation and to
|
|
|
|
name them exactly the same as their `fx:id`!
|
|
|
|
<code class="java">
|
|
|
|
/** {@link textfield} for inserting names. */
|
|
/** {@link textfield} for inserting names. */
|
|
@fxml
|
|
@fxml
|
|
private textfield nametextfield;
|
|
private textfield nametextfield;
|
... | @@ -246,86 +165,50 @@ luckily, we’ve got you covered: |
... | @@ -246,86 +165,50 @@ luckily, we’ve got you covered: |
|
@fxml
|
|
@fxml
|
|
private label displaylabel;
|
|
private label displaylabel;
|
|
|
|
|
|
```
|
|
3. now we want to make sure that the label we want to display our greetings on is (almost) empty when the view is openend. thus, let’s initialize it with “…”:
|
|
3. now we want to make sure that the label we want to display our
|
|
|
|
greetings on is (almost) empty when the view is openend. thus,
|
|
|
|
let’s initialize it with “…”:
|
|
|
|
<code class="java">
|
|
|
|
/** {@inheritdoc} */
|
|
/** {@inheritdoc} */
|
|
@override
|
|
@override
|
|
public void initialize(icompositefxcontroller[] containments) {
|
|
public void initialize(icompositefxcontroller[] containments) {
|
|
displaylabel.settext("...");
|
|
displaylabel.settext("...");
|
|
}
|
|
}
|
|
|
|
|
|
```
|
|
|
|
4. finally, we want to update the label to show a greeting when the
|
|
4. finally, we want to update the label to show a greeting when the submit button is pressed. for that we need to create a new public method (make sure it’s public!) named exactly the same as the `onaction` property you set in the scenebuilder. as the greeting should contain the user’s name, you can now use `nametextfield.gettext()` to extract the inserted name. to display the greeting, the `displaylabel.settext(string value)` is the way to go. in the end the method should look something like this:
|
|
submit button is pressed. for that we need to create a new
|
|
|
|
public method (make sure it’s public!) named exactly the same as
|
|
|
|
the `onaction` property you set in the scenebuilder. as the
|
|
|
|
greeting should contain the user’s name, you can now use
|
|
|
|
`nametextfield.gettext()` to extract the inserted name. to
|
|
|
|
display the greeting, the `displaylabel.settext(string value)`
|
|
|
|
is the way to go. in the end the method should look something
|
|
|
|
like this:
|
|
|
|
<code class="java
|
|
|
|
/** Displays the greeting when the "Submit" button is pressed. */
|
|
/** Displays the greeting when the "Submit" button is pressed. */
|
|
public void onSubmit() {
|
|
public void onSubmit() {
|
|
displayLabel.setText(format("Hello %s!", nameTextField.getText()));
|
|
displayLabel.setText(format("Hello %s!", nameTextField.getText()));
|
|
}
|
|
}
|
|
|
|
|
|
```
|
|
3. You’re done! Run AF3 and start typing and clicking on your new interactive view!
|
|
3. You’re done! Run AF3 and start typing and clicking on your new
|
|
|
|
interactive view!
|
|
|
|
|
|
|
|
### About JavaFX
|
|
### About JavaFX
|
|
|
|
|
|
JavaFX is a GUI framework and toolkit that allows building GUIs with
|
|
JavaFX is a GUI framework and toolkit that allows building GUIs with less effort compared to SWT. GUIs can be created programmatically or using a layout files in combination with a controller class that is programmed in Java.
|
|
less effort compared to SWT. GUIs can be created programmatically or
|
|
|
|
using a layout files in combination with a controller class that is
|
|
|
|
programmed in Java.
|
|
|
|
|
|
|
|
The integration of JavaFX in AutoFOCUS 3 (AF3) is achieved by using the
|
|
The integration of JavaFX in AutoFOCUS 3 (AF3) is achieved by using the e(fx)clipse plugins developed as an [Eclipse
|
|
e(fx)clipse plugins developed as an [Eclipse
|
|
project](https://www.eclipse.org/efxclipse/index.html) led by Thomas Schindl.
|
|
project](https://www.eclipse.org/efxclipse/index.html) led by Thomas
|
|
|
|
Schindl.
|
|
|
|
|
|
|
|
### How to set up the SceneBuilder
|
|
### How to set up the SceneBuilder
|
|
|
|
|
|
When installing AF3, the platform integration is already shipped.
|
|
When installing AF3, the platform integration is already shipped. However, you may want to install the SceneBuilder to work with FXML layout files to build complex GUIs.
|
|
However, you may want to install the SceneBuilder to work with FXML
|
|
|
|
layout files to build complex GUIs.
|
|
|
|
|
|
|
|
1. Install [SceneBuilder](http://gluonhq.com/products/scene-builder/)
|
|
1. Install [SceneBuilder](http://gluonhq.com/products/scene-builder/) to your machine.
|
|
to your machine.
|
|
2. In your developer installation, navigate to “Window > Preferences” and click “JavaFX”. In the box to the right, please enter the path to the Scenebuilder executable of your local installation. (Note: Mac Users might need to create a wrapper script that calls the executable)
|
|
2. In your developer installation, navigate to “Window >
|
|
3. You can now open FXML layout files in SceneBuilder by right clicking such a file and selecting “Open with Scenebuilder”.
|
|
Preferences” and click “JavaFX”. In the box to the right, please
|
|
|
|
enter the path to the Scenebuilder executable of your local
|
|
|
|
installation. (Note: Mac Users might need to create a wrapper script
|
|
|
|
that calls the executable)
|
|
|
|
3. You can now open FXML layout files in SceneBuilder by right clicking
|
|
|
|
such a file and selecting “Open with Scenebuilder”.
|
|
|
|
|
|
|
|
### Troubleshooting
|
|
### Troubleshooting
|
|
|
|
|
|
If the above procedure is followed, no errors should appear. However,
|
|
If the above procedure is followed, no errors should appear. However, there are typical error patterns which may be hard to debug, but whose cause is easy to identify using the indicators listed in the following. Most of them are easy to identify by systematically placing breakpoints in the controller class. Use the following items also as instruction to perform systematic debugging!
|
|
there are typical error patterns which may be hard to debug, but whose
|
|
|
|
cause is easy to identify using the indicators listed in the following.
|
|
|
|
Most of them are easy to identify by systematically placing breakpoints
|
|
|
|
in the controller class. Use the following items also as instruction to
|
|
|
|
perform systematic debugging!
|
|
|
|
|
|
|
|
- The view is not available in the launched AF3 instance: Ensure that
|
|
- The view is not available in the launched AF3 instance: Ensure that the registration of the view in the plugin.xml file is correct. Please pay special attention to the package and class names.
|
|
the registration of the view in the plugin.xml file is correct.
|
|
|
|
Please pay special attention to the package and class names.
|
|
|
|
- There is an exception when opening the JavaFX view:
|
|
- There is an exception when opening the JavaFX view:
|
|
1. Ensure that the FXML layout file is placed in the same package
|
|
1. Ensure that the FXML layout file is placed in the same package as the controller.
|
|
as the controller.
|
|
2. Ensure that the FXML file is contained in the binary version of the plugins (build.properties of the plugin).
|
|
2. Ensure that the FXML file is contained in the binary version of
|
|
|
|
the plugins (build.properties of the plugin).
|
|
|
|
- NPEs occur in the controller when a layout element is accessed:
|
|
- NPEs occur in the controller when a layout element is accessed:
|
|
1. Ensure that the field has the "`FXML" annotation.
|
|
1. Ensure that the field has the `FXML` annotation. Ensure that the field is only accessed in the `initialize@
|
|
## Ensure that the field is only accessed in the `initialize@
|
|
|
|
method or later.
|
|
method or later.
|
|
2. Ensure that the name of the field in the controller is
|
|
2. Ensure that the name of the field in the controller is equivalent to the one defined in the layout file.
|
|
equivalent to the one defined in the layout file.
|
|
|
|
|
|
|