I have a swing project that uses many JTables to display all sorts of things from text to panels to a mix of buttons and check boxes. I was able to do this by overwriting the table cell renderer to return generic JComponents. My question is can a similar table be made using JavaFx?
I want to update all my tables in the project to use JavaFx to support gestures mostly. It seems that TableView is the JavaFx component to use and I tried adding buttons to it but when displayed it shows the string value of the button, not the button itself. It looks like I have to overwrite the row factory or cell factory to do what I want but there are not a lot of examples. Here is the code I used as an example that displays the button as a string.
import javax.swing.JButton;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class GestureEvents extends Application {
private TableView<Person> table = new TableView<Person>();
private final ObservableList<Person> data =
FXCollections.observableArrayList(
new Person("Jacob", "Smith", "jacob.smith@example.com","The Button"),
new Person("Isabella", "Johnson", "isabella.johnson@example.com","The Button"),
new Person("Ethan", "Williams", "ethan.williams@example.com","The Button"),
new Person("Emma", "Jones", "emma.jones@example.com","The Button"),
new Person("Michael", "Brown", "michael.brown@example.com","The Button")
);
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(450);
stage.setHeight(500);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
table.setEditable(true);
TableColumn firstNameCol = new TableColumn("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("firstName"));
TableColumn lastNameCol = new TableColumn("Last Name");
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("lastName"));
TableColumn emailCol = new TableColumn("Email");
emailCol.setMinWidth(200);
emailCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("email"));
TableColumn btnCol = new TableColumn("Buttons");
btnCol.setMinWidth(100);
btnCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("btn"));
table.setItems(data);
table.getColumns().addAll(firstNameCol, lastNameCol, emailCol, btnCol);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(label, table);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty email;
private final JButton btn;
private Person(String fName, String lName, String email, String btn) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
this.btn = new JButton(btn);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
public JButton getBtn(){
return btn;
}
public void setBtn(String btn){
}
}
public static class ButtonPerson{
private final JButton btn;
private ButtonPerson(){
btn = new JButton("The Button");
}
public JButton getButton(){
return btn;
}
}
}
Edit: After investigating further I've found examples that override cell graphics using predefined cell types like text and checks. It is not clear if any generic jfx component can be placed in a cell like a JFXPanel. This is unlike JTable, since using a JTable I can place anything that inherits from JComponent as long as I setup the render class correctly. If someone knows how (or if it's even possible) to place a JFXPanel in a cell or a other generic JFx component like a Button that would be very helpful.