Sunday, February 18, 2018
Dynamically adding JavaFX controls
Dynamically adding JavaFX controls
The JavaFX SceneBuilder works very well for constructing a static GUI; that is, a GUI whose controls are determined entirely at compile-time. But sometimes it is useful to be able to add new controls dynamically at run-time. The example below demonstrates one way to do this.
In this example, the user creates Button objects on-the-fly. They are displayed using a ListViewer and stored in an ObservableList. Each button inverts the capitalization of its label when clicked. The Controller class is given below; constructing the rest of the GUI is an exercise for the reader.
package application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
public class Controller {
@FXML
private Button add;
@FXML
private TextField button;
@FXML
private ListView<Button> visibleList;
private ObservableList<Button> buttons =
FXCollections.observableArrayList();
@FXML
protected void initialize() {
visibleList.setItems(buttons);
}
@FXML
void addName() {
Button b = new Button(button.getText());
buttons.add(b);
b.addEventHandler(MouseEvent.MOUSE_CLICKED,
(event -> b.setText(invertCapitals(b.getText()))));
button.setText("");
}
public static String invertCapitals(String other) {
return other.chars().mapToObj(Controller::flipCap)
.map(c -> Character.toString(c))
.reduce("", (s, c) -> s + c);
}
public static Character flipCap(int c) {
if (c >= A && c <= Z) {
return (char)(c - A + a);
} else if (c >= a && c <= z) {
return (char)(c - a + A);
} else {
return (char)c;
}
}
}
Highlighted in red, the key to making this all work is the
addName()
method, working in combination with the ObservableList buttons
. This method creates a new Button
object in response to every click of the add
button. This object is added to our ObservableList
, which makes it visible in the ListViewer
. Finally, we employ a Java 8 lambda to implement the event handler. There is a pretty long list of event types to which one might respond. Check out the documentation for the MouseEvent and KeyEvent classes to get started.
Heres a sample run of the program: