RadioButtons unable to load from javafx subclass - java

Am trying to load a new scene from another class into the main javafx page and this is the main javafx page
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import javafx.scene.control.Button;
import javafx.scene.control.Hyperlink;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.HBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Cbt extends Application {
Stage stageCbt;
Scene staffMainPage;
BorderPane border;
FlowPane addFlowPane;
Hyperlink SQuestions, setParameters;
public void start(Stage theMainStage){
stageCbt = theMainStage;
border = new BorderPane();
SQuestions.setOnAction(ae -> createQuestionsLinkClicked(ae));
}
private FlowPane addFlowPaneLO() {
addFlowPane = new FlowPane();
addFlowPane.getStyleClass().addAll("pane", "vbox");
Hyperlink options[] = new Hyperlink[]{
setParameters = new Hyperlink("set Questions Parameters"),
SQuestions = new Hyperlink("Select past jamb questions")
};
for (int i = 0; i < 2; i++) {
addFlowPane.setMargin(options[i], new Insets(0, 0, 0, 8));
addFlowPane.getChildren().add(options[i]);
}
addFlowPane.getStyleClass().addAll("pane", "flow");
addFlowPane.setPrefWrapLength(170);
return addFlowPane;
}
public void createQuestionsLinkClicked(ActionEvent ae) {
if (ae.getSource() == SQuestions) {
//Questions ques = new Questions();
stageCbt.setScene(staffMainPage);
borderpane.setCenter(new Questions().getAnchor());
}
}
public static void main(String[] args) {
launch(args);
}
}
and this is the the subclass(Questions.java)
import javafx.beans.property.StringProperty;
import javafx.geometry.Pos;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ListView;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextArea;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
public class Questions {
TextArea putQues;
Button end, edit, review, next;
BorderPane bpane;
GridPane gdQues;
AnchorPane anchor;
ToggleGroup oneSelected;
Text msg, option;
public static String lvo[] = new String[]{
"Option A",
"Option B",
"Option C",
"Option D",
"Option E"
};
public static String rbo[] = new String[]{
"A",
"B",
"C",
"D",
"E"
};
RadioButton rbs[] = new RadioButton[rbo.length];
ListView lvs [] = new ListView[lvo.length];
public Questions(){
gdQues = new GridPane();
gdQues.setHgap(10);
gdQues.setVgap(10);;
gdQues.setAlignment(Pos.TOP_LEFT);
gdQues.getStyleClass().add("grid");
msg = new Text("Questions should be put below");
msg.setFont(Font.font("Arial", FontWeight.BOLD, 20));
gdQues.add(msg, 3, 3);
putQues = new TextArea();
putQues.setPromptText("Type question here");
gdQues.add(putQues, 4, 0);
option = new Text("Options");
option.setFont(Font.font("Monotype Corsiva", FontWeight.BOLD, 10));
gdQues.add(option, 6, 0);
//options = new ListView();
//ListView optionAll = new ListView();
for(int i = 0; i < rbo.length; i++){
RadioButton rb = rbs[i] = new RadioButton(rbo[i]);
ListView lv = lvs[i];
rbs[i].setToggleGroup(oneSelected);
}
//gdQues.getChildren().addAll(rbs);
//gdQues.getChildren().addAll(lvs);
anchor = new AnchorPane();
anchor.getStyleClass().add("pane");
end = new Button("End");
edit = new Button("Edit");
review = new Button("Review");
next = new Button("Next");
HBox hb = new HBox();
hb.getStyleClass().add("hb");
hb.getChildren().addAll(end, edit, review, next);
anchor.getChildren().addAll(gdQues, hb);
}
public Parent getGdQues(){
return gdQues;
}
public Parent getAnchor(/*GridPane gdQues*/){
return anchor;
}
public Parent getPutQues(){
return putQues;
}
public Text getMsg(){
return msg;
}
/*public Parent getRbs(){
return rbo;
}
public Parent getLvs(){
return lvs;
}*/
}
all other controls display except the radiobuttons(of which I guess is because the function wasn't move into the constructor).
My question now is how get the radiobuttons to display?

I do not know the format your are using while in instantiating your radio button, see:
RadioButton rb = rbs[i] = new RadioButton(rbo[i]);
See also this question: initialize multiple variables in a same line in java
Maybe are the instantiation in the other oder as you think done. Or you simply forget to delete the fisrt part. Whatever, it seams, you do not use the rb variable, so prefer:
rbs[i] = new RadioButton(rbo[i]);
Or separate it into 2 lines.

Related

why JOptionPane.showMessageDialog just working in main?

I'm using NetBeans last version and macOS. I try this is my code and JOptionPane.showMessageDialog not working. It's working if I put the syntax in the main. Please tell me why. I try vscode, and I have same problem
import javax.swing.*;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.control.TextInputDialog;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class App extends Application {
TextField txt;
public void start(Stage primaryStage) {
Label lb1 = new Label();
TextField txt = new TextField("Type here");
RadioButton rb1 = new RadioButton();
RadioButton rb2 = new RadioButton();
Button bt = new Button("click");
Button bt1 = new Button("anas aljaghbeer");
MyHandlerClass handler1 = new MyHandlerClass();
bt.setOnAction(handler1);
txt.setPrefSize(10, 10);
lb1.setText("Enter here");
txt.getText();
VBox box = new VBox();
Scene scene = new Scene(box, 1000, 1000);
box.getChildren().addAll(lb1, txt, bt);
primaryStage.setTitle("anas");
primaryStage.setScene(scene);
primaryStage.show();
}
class MyHandlerClass implements EventHandler<ActionEvent> {
#Override
public void handle(ActionEvent e) {
JOptionPane.showMessageDialog(null, " Hello");
}
}
public static void main(String[] args) {
Application.launch(args);
}
}
JOptionPane.showMessageDialog()…It's working if I put the syntax in the main. Please tell me why.
When you invoke JOptionPane.showMessageDialog() in main(), it executes on the initial thread. In a Swing program, you would invoke it from main() like this:
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JOptionPane.showMessageDialog(null, "Click to continue…");
…
});
}
In a JavaFX program you are well advised not to "mix Swing and JavaFX," unless you account for JavaFX-Swing Interoperability. Instead, evoke an Alert as shown here and below:
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class App extends Application {
TextField txt;
#Override
public void start(Stage primaryStage) {
Label label = new Label();
TextField text = new TextField("Type here");
Button button = new Button("Click");
MyHandlerClass handler = new MyHandlerClass();
button.setOnAction(handler);
text.setPrefSize(10, 10);
label.setText("Enter here");
text.getText();
VBox box = new VBox();
box.getChildren().addAll(label, text, button);
Scene scene = new Scene(box, 320, 240);
primaryStage.setScene(scene);
primaryStage.setTitle("anas");
primaryStage.show();
}
class MyHandlerClass implements EventHandler<ActionEvent> {
#Override
public void handle(ActionEvent e) {
Alert alert = new Alert(Alert.AlertType.INFORMATION, "You clicked the button.");
alert.showAndWait();
}
}
public static void main(String[] args) {
Application.launch(args);
}
}

JavaFX - Weird Behavior When Adding Node To Parent

I have created a simple app to simulate dynamic node creation with JAVAFX.
This app has the ability to create a new window whenever user want it by clicking the "New" button.
User can add a new node which is TitledPane to the window by clicking "Add Task" button and then clicking "Add" button on the dialog window.
There are an unexpected behavior which I want to fix. This app is only add new node (TitledPane in this case) to the last created window.
And the all of the nodes on the previous window will vanish.
You can see the following video to better understand what I mean.
VIDEO
https://youtu.be/eaWmu3zuuhE
NETBEANS PROJECT
Just in case you want to play with it.
https://drive.google.com/file/d/0B4Sbb8Ym-lcZLUIyWHV5ZXRSZE0/view?usp=sharing
CODES:
TasksList.java
package taskslist;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.stage.Stage;
public class TasksList extends Application {
DisplayWhich display = new DisplayWhich();
Stage primaryStage;
Parent startWindow;
#Override
public void start(Stage primaryStage) throws Exception {
this.primaryStage = primaryStage;
initStart();
}
private void initStart(){
display.showDialogWindow();
}
public static void main(String[] args) {
launch(args);
}
}
TheList.java
package taskslist.view;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Modality;
import javafx.stage.Stage;
import taskslist.DisplayWhich;
public class TheList extends BorderPane {
public static VBox listWrapper;
public static ScrollPane listScroller;
public ObservableList<TitledPane> tasks;
private List<String> titles = new ArrayList<>();
public TheList(){
tasks = FXCollections.observableArrayList();
listWrapper = new VBox(5);
listScroller = new ScrollPane(listWrapper);
}
public void setTitles(String... title){
titles = Arrays.asList(title);
}
public List<String> getTitles(){
return titles;
}
public void loadSavedList(){
for(int i=0; i<getTitles().size();i++){
String ttlString = getTitles().get(i);
this.createTask(ttlString);
}
// Display Tasks
listWrapper.getChildren().addAll(this.tasks);
}
// Dialong for adding a new task and also editing a task
private void addTaskDialog(){
GridPane container = new GridPane();
Scene scene = new Scene(container, 150, 50);
Stage addNewTask = new Stage();
addNewTask.initModality(Modality.APPLICATION_MODAL);
addNewTask.setTitle("Add Task");
TextField title = new TextField();
Button confirm = new Button("Add");
// Create Task
confirm.setOnAction((ev) -> {
String ttlString = title.getText();
this.createTask(ttlString);
listWrapper.getChildren().clear();
listWrapper.getChildren().addAll(this.tasks);
addNewTask.close();
});
container.add(title, 0, 1);
container.add(confirm, 0, 5);
addNewTask.setScene(scene);
addNewTask.showAndWait();
}
// Assemble all this.tasks list components
public void render(){
setCenter(listScroller);
loadSavedList();
Button newProject = new Button("New");
Button addTask = new Button("Add Task");
BorderPane listBottom = new BorderPane();
HBox bottomLeft = new HBox();
bottomLeft.getChildren().add(newProject);
listBottom.setLeft(bottomLeft);
HBox bottomRight = new HBox();
bottomRight.getChildren().add(addTask);
listBottom.setRight(bottomRight);
newProject.setOnAction((evt) -> {
DisplayWhich display = new DisplayWhich();
display.showDialogWindow();
});
addTask.setOnAction((e) -> {
addTaskDialog();
});
setBottom(listBottom);
}
// Cteate task from strings
private void createTask(String... strings){
String taskTitle = strings.length > 0 ? strings[0] : "";
TitledPane task = new TitledPane();
task.setPrefWidth(647);
task.setExpanded(false);
task.setText(taskTitle);
this.tasks.add(task);
}
}
NewDialog.java
package taskslist.view;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.Parent;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;
import taskslist.DisplayWhich;
public class NewDialog {
DisplayWhich display = new DisplayWhich();
Stage stage = new Stage();
Parent startWindow = new AnchorPane();
#FXML
private Button cancelNew;
#FXML
private Button confirmCreation;
/**
* Initializes the controller class.
*/
#FXML
private void initialize() {
}
#FXML
private void cancelNewCreation(ActionEvent event) {
((Stage)cancelNew.getScene().getWindow()).close();
}
#FXML
private void confirmCreateNew(ActionEvent event) {
((Stage)confirmCreation.getScene().getWindow()).close();
TheList wrap = new TheList();
TheWindow window = new TheWindow();
window.makeWindow(wrap);
wrap.setTitles("one", "two", "three", "four");
wrap.render();
}
}
DisplayWhich.java
package taskslist;
import java.io.IOException;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import taskslist.view.TheList;
public class DisplayWhich {
Stage stage = new Stage();
Parent startWindow = new AnchorPane();
public DisplayWhich(){}
public Stage showDialogWindow(){
try {
stage.initModality(Modality.APPLICATION_MODAL);
stage.setTitle("Create New Project");
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/taskslist/view/newDialog.fxml"));
startWindow = loader.load();
Scene scene = new Scene(startWindow);
stage.setScene(scene);
stage.setOnCloseRequest((event) -> {
System.out.println("test");
});
stage.showAndWait();
} catch (IOException ex) {
ex.printStackTrace();
}
return stage;
}
}
TheWindow.java
package taskslist.view;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class TheWindow {
public TheWindow(){}
public void makeWindow(BorderPane group) {
Stage mainWindow = new Stage();
Scene scene = new Scene(group, 650, 550);
mainWindow.setScene(scene);
mainWindow.setTitle("Task List");
mainWindow.centerOnScreen();
mainWindow.show();
}
}
Why that weird behavior happening and how to fix it so it only adds new node to the same window where the clicked "Add Task" button is located?
These fields should not be static:
public static VBox listWrapper;
public static ScrollPane listScroller;

Binding to value of ObservableMap by key

Does JavaFX have a binding type where i supply an observable map with a key and the computed value will always update as the key/value pair changes? Removing that key the key from the map will result to a null value, adding it back will track that value back.
I've been looking around the JavaDoc and found MapProperty, MapBinding and ObservableMapValue, but nothing seems to serve this purpose.
I've already designed my own variant, but would like to use a rather failsafe and tested version.
You can just do
someObjectProperty.bind(Bindings.createObjectBinding(
() -> myObservableMap.get(key), myObservableMap);
or, as #VGR points out in the comments
someObjectProperty.bind(Bindings.valueAt(someObservableMap, key));
Here is a SSCCE using the second approach:
import java.util.Arrays;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableMap;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class BindToObservableMap extends Application {
private static final String[] keys = {"key1", "key2", "key3"};
#Override
public void start(Stage primaryStage) {
ObservableMap<String, String> map = FXCollections.observableHashMap();
for (String k : keys) map.put(k, k.replaceAll("key", "value"));
GridPane grid = new GridPane();
grid.setHgap(5);
grid.setVgap(5);
grid.setPadding(new Insets(10));
for (int i = 0 ; i < keys.length; i++) {
grid.add(new Label(keys[i]), 0, i);
Label boundLabel = new Label();
boundLabel.textProperty().bind(Bindings.valueAt(map, keys[i]));
grid.add(boundLabel, 1, i);
}
ComboBox<String> keyCombo = new ComboBox<>();
keyCombo.getItems().setAll(keys);
TextField valueField = new TextField();
Button update = new Button("Update");
EventHandler<ActionEvent> handler = e -> {
map.put(keyCombo.getValue(), valueField.getText());
valueField.clear();
keyCombo.requestFocus();
};
valueField.setOnAction(handler);
update.setOnAction(handler);
grid.addRow(keys.length, keyCombo, valueField);
grid.add(update, 0, keys.length + 1);
Scene scene = new Scene(grid);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Binding between Label and HashMap not updating [duplicate]

Does JavaFX have a binding type where i supply an observable map with a key and the computed value will always update as the key/value pair changes? Removing that key the key from the map will result to a null value, adding it back will track that value back.
I've been looking around the JavaDoc and found MapProperty, MapBinding and ObservableMapValue, but nothing seems to serve this purpose.
I've already designed my own variant, but would like to use a rather failsafe and tested version.
You can just do
someObjectProperty.bind(Bindings.createObjectBinding(
() -> myObservableMap.get(key), myObservableMap);
or, as #VGR points out in the comments
someObjectProperty.bind(Bindings.valueAt(someObservableMap, key));
Here is a SSCCE using the second approach:
import java.util.Arrays;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableMap;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class BindToObservableMap extends Application {
private static final String[] keys = {"key1", "key2", "key3"};
#Override
public void start(Stage primaryStage) {
ObservableMap<String, String> map = FXCollections.observableHashMap();
for (String k : keys) map.put(k, k.replaceAll("key", "value"));
GridPane grid = new GridPane();
grid.setHgap(5);
grid.setVgap(5);
grid.setPadding(new Insets(10));
for (int i = 0 ; i < keys.length; i++) {
grid.add(new Label(keys[i]), 0, i);
Label boundLabel = new Label();
boundLabel.textProperty().bind(Bindings.valueAt(map, keys[i]));
grid.add(boundLabel, 1, i);
}
ComboBox<String> keyCombo = new ComboBox<>();
keyCombo.getItems().setAll(keys);
TextField valueField = new TextField();
Button update = new Button("Update");
EventHandler<ActionEvent> handler = e -> {
map.put(keyCombo.getValue(), valueField.getText());
valueField.clear();
keyCombo.requestFocus();
};
valueField.setOnAction(handler);
update.setOnAction(handler);
grid.addRow(keys.length, keyCombo, valueField);
grid.add(update, 0, keys.length + 1);
Scene scene = new Scene(grid);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

How to set a font to a Timeline in javafx

I am making an alarm clock kind of program and I need a way to make the clock face a specific font. I have tried multiple times in multiple ways. If that is not possible can you please provide another solution? Thank you in advance!
import java.util.Calendar;
import java.util.GregorianCalendar;
import javax.print.DocFlavor.URL;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Menu extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
//Frame stuff (works)
GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(10);
grid.setVgap(10);
//Frame Size
Scene scene = new Scene(new DigitalClock(),1080, 720);
//Icon
primaryStage.getIcons().add(new Image(getClass().getResourceAsStream(("/lib/logo.png"))));
primaryStage.setTitle("Clock: 140 Edition");
//Necessities
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String args[]) {
launch(args);
}
}
class Util {
public static String pad(int fieldWidth, char padChar, String s) {
StringBuilder sb = new StringBuilder();
for (int i = s.length(); i < fieldWidth; i++) {
sb.append(padChar);
}
sb.append(s);
return sb.toString();
}
}
class DigitalClock extends Label {
public DigitalClock() {
bindToTime();
}
// the digital clock updates once a second.
private void bindToTime() {
Timeline timeline = new Timeline(
new KeyFrame(Duration.seconds(0),
new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent actionEvent) {
Calendar time = Calendar.getInstance();
String hourString = Util.pad(2, ' ', time.get(Calendar.HOUR) == 0 ? "12" : time.get(Calendar.HOUR) + "");
String minuteString = Util.pad(2, '0', time.get(Calendar.MINUTE) + "");
String secondString = Util.pad(2, '0', time.get(Calendar.SECOND) + "");
String ampmString = time.get(Calendar.AM_PM) == Calendar.AM ? "AM" : "PM";
setText(hourString + ":" + minuteString + ":" + secondString + " " + ampmString);
}
}
),
new KeyFrame(Duration.seconds(1))
);
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}
I also know some of the imports are not used, I would prefer to keep them. Thanks again!
🍒The Font has to do with the Label you are using in the example.
Must
read:http://www.guigarage.com/2014/10/integrate-custom-fonts-javafx-application-using-css/
<-----------------Ways to do----------------->
1)Using external css:
/*The font path*/
#font-face{
src: url("../fonts/Younger than me Bold.ttf");
}
/* An element which has this id*/
#LabelID{
-fx-font-family:"Younger than me";
-fx-font-size:18.0;
}
//or for all labels
.label{
-fx-font-family:"Younger than me";
-fx-font-size:18.0;
}
2)Using setStyle(...):
`label.setStyle("-fx-font-family:monospace; -fx-font-size:16px; -fx-text-fill:black; -fx-border-color:red;");`
3)Using setFont(...):
b.setFont(new Font("Arial", 24));
4)Tricky and not recommended ( not included in JavaFX docs) : here
Relative posts:
How to set custom fonts in JavaFX Scene Builder using CSS
https://blog.idrsolutions.com/2014/04/use-external-css-files-javafx/
Have a look at https://gist.github.com/jewelsea/2658491

Categories

Resources