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.
Here's a sample run of the program:
in intialize it is showing an error, I don't know why?
ReplyDeleteMake sure visibleList is bound properly to an object in your FXML file.
Deletewhat about deleting. I have taken pieces of this code to do a simple form. I want to add textfeilds dynamically. You code successfully does this. The problem I have is deleting. I can only delete once. If I add again, I can delete again, but only once. How can I add and delete components
ReplyDeletecan you show the fxml file?
ReplyDeleteGreat tutorial . Thank you so much
ReplyDeleteOne thing to note is that when you create the add button in Scene builder , one needs to set the On Action property of the add button to addName for the add button. This part took me a couple of minutes to figure out. In case someone encounters the problem.
Hi! I'm trying to implement your code, but for a reason I don't understand my list view doesn't update at all. I've already bound my FXML object to the .fxml file itself properly but it is not working. I don't know if it has anything to do with the initialize method, because honestly I don't know where that method is being called. Thank you.
ReplyDeleteHow to manage added buttons actions? i.e how do I know the added button id and do assign onAction Listener
ReplyDelete