References
JavaFX
Periodic action
1
2
3
4
5
6
7
8
|
Timeline timeline = new Timeline(
new KeyFrame(
Duration.millis(2500),
ae -> System.out.println("Periodic action")
)
);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
|
FXML controller - constructor vs initialize method
The constructor
is called first, then any @FXML
annotated fields are populated, then initialize()
is called. So the constructor does NOT have access to @FXML
fields referring to components defined in the .fxml file, while initialize()
does have access to them.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public class MyController implements Initializable {
@FXML
TableView<MyModel> tableView;
public MyController() {
tableView.getItems().addAll(getDataFromSource()); // results in NullPointerException, as tableView is null at this point.
}
@FXML
public void initialize(URL url, ResourceBundle rb) {
tableView.getItems().addAll(getDataFromSource()); // Perfectly Ok here, as FXMLLoader already populated all @FXML annotated members.
}
}
|
Scene UserAgentStylesheet
Caspian is the theme that shipped as default in JavaFX 2.x.
1
|
scene.setUserAgentStylesheet(STYLESHEET_CASPIAN);
|
Modena is the default theme for JavaFX 8.x.
1
|
scene.setUserAgentStylesheet(STYLESHEET_MODENA);
|
High Contrast Themes
High contrast themes can be set with a command line option
1
|
-Dcom.sun.javafx.highContrastTheme=yellowOnBlack
|
The valid values are yellowOnBlack
, whiteOnBlack
, or blackOnWhite
.
Virtual keyboard
Virtual keyboard can be enabled with below command line options. You must add these flags to the java VM, not to the application.
1
2
3
|
-Dcom.sun.javafx.isEmbedded=true
-Dcom.sun.javafx.touch=true
-Dcom.sun.javafx.virtualKeyboard=javafx
|
To customize the keyboard layout check /com/sun/javafx/scene/control/skin/caspian/fxvk.css
in ${JRE/JDK_INSTALL}/jre/lib/ext/jfxrt.jar
for the css fields influencing the keyboard.
To run command line options in Netbeans IDE, put VM option inside nbaction.xml
1
|
<runfx.args>-jar -Dcom.sun.javafx.isEmbedded=true -Dcom.sun.javafx.touch=true -Dcom.sun.javafx.virtualKeyboard=javafx ${project.build.directory}/${project.build.finalName}.jar</runfx.args>
|
To have virtual keyboard for a textField use below code snippets. Use properties
1
2
|
TextField textField = new TextField();
textField.getProperties().put(FXVK.VK_TYPE_PROP_KEY, "numeric");
|
VK_TYPE_PROP_KEY
can only get text
, numeric
, url
, email
values.
or use listener
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
textField.focusedProperty().addListener((ObservableValue<? extends Boolean> arg0, Boolean oldPropertyValue, Boolean newPropertyValue) -> {
VirtualKeyboard keyboard = new VirtualKeyboard();
if (newPropertyValue) {
keyboard.show(textField);
} else {
keyboard.hide();
}
});
public class VirtualKeyboard {
public void show(TextField textField) {
textField.getProperties().put(FXVK.VK_TYPE_PROP_KEY, "numeric");
FXVK.init(textField);
FXVK.attach(textField);
}
public void hide() {
FXVK.detach();
}
}
|
To prevent opening virtual keyboard
1
2
3
4
5
6
7
8
|
textField.focusedProperty().addListener(new ChangeListener<Boolean>()
{
public void changed(ObservableValue<? extends Boolean> arg0, Boolean oldPropertyValue, Boolean newPropertyValue)
{
if (newPropertyValue)
FXVK.detach();
}
});
|
Display additional values in Pie Chart
Binding the pie chart data name
1
2
3
4
5
6
7
|
pieChartData.forEach(data ->
data.nameProperty().bind(
Bindings.concat(
data.getName(), " ", data.pieValueProperty(), " Tons"
)
)
);
|
If you want to avoid recomputing the total every time there’s a mouse event, you can create a DoubleBinding
to store it:
1
|
DoubleBinding total = Bindings.createDoubleBinding(() -> pieChartData.stream().collect(Collectors.summingDouble(PieChart.Data::getPieValue)), pieChartData);
|
If you have changing values and/or want to avoid displaying the values in the chart legend, you could modify the text label instead of changing the data names.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
chart = new PieChart(pieChartData) {
@Override
protected void layoutChartChildren(double top, double left, double contentWidth, double contentHeight) {
if (getLabelsVisible()) {
getData().forEach(d -> {
Optional<Node> opTextNode = chart.lookupAll(".chart-pie-label").stream().filter(n -> n instanceof Text && ((Text) n).getText().contains(d.getName())).findAny();
if (opTextNode.isPresent()) {
((Text) opTextNode.get()).setText(d.getName() + " " + d.getPieValue() + " Tons");
}
});
}
super.layoutChartChildren(top, left, contentWidth, contentHeight);
}
};
|