如何在JavaFX表视图中添加按钮

我已经在谷歌和Stackoverflow上搜索了这个,我只是没有得到给定的例子。 有人可以向我解释一下。

我想在表视图的最后一列添加一个按钮,当它被单击时,它应该触发一个监听器并传递按钮行的对象。 我只是没有从gist.github.com获得以下示例:

这是我当前的完整代码:

public class SchermdeelWerkplaats extends BorderPane{ //ATD moeder klasse met alle collecties etc. private ATD $; TableView tabel = new TableView(); Button nieuwTaak = new Button("Nieuwe taak inboeken"); final ObservableList data = FXCollections.observableArrayList(); public SchermdeelWerkplaats(ATD a) { $ = a; data.addAll($.agenda); tabel.setEditable(false); tabel.setPlaceholder(new Label("Geen taken")); TableColumn c1 = new TableColumn("datum"); c1.setMinWidth(200); TableColumn c2 = new TableColumn("type"); c2.setMinWidth(100); TableColumn c3 = new TableColumn("uren"); c3.setMinWidth(100); TableColumn c4 = new TableColumn("klaar"); c4.setMinWidth(200); TableColumn c5 = new TableColumn("Werknemer"); c5.setMinWidth(100); TableColumn c6= new TableColumn("Auto"); c6.setMinWidth(400); TableColumn c7= new TableColumn("Actie"); c7.setMinWidth(400); TableColumn col_action = new TableColumn("Action"); col_action.setCellValueFactory( new Callback<TableColumn.CellDataFeatures, ObservableValue>() { @Override public ObservableValue call(TableColumn.CellDataFeatures p) { return new SimpleBooleanProperty(p.getValue() != null); } }); col_action.setCellFactory( new Callback<TableColumn, TableCell>() { @Override public TableCell call(TableColumn p) { return new ButtonCell(); } } ); c1.setCellValueFactory( new PropertyValueFactory("date") ); c2.setCellValueFactory( new PropertyValueFactory("type") ); c3.setCellValueFactory( new PropertyValueFactory("hours") ); c4.setCellValueFactory( new PropertyValueFactory("done") ); c5.setCellValueFactory( new PropertyValueFactory("employee") ); c6.setCellValueFactory( new PropertyValueFactory("car") ); tabel.getColumns().addAll(c1, c2, c3, c4, c5, c6, c7); tabel.setItems(data); setCenter(tabel); setBottom(nieuwTaak); } //letterlijk van internet geplukt en datatype aangepast private class ButtonCell extends TableCell { private Button cellButton; ButtonCell(){ cellButton = new Button("jjhjhjh"); cellButton.setOnAction(new EventHandler(){ @Override public void handle(ActionEvent t) { // do something when button clicked Task record = getItem(); // do something with record.... } }); } //Display button if the row is not empty @Override protected void updateItem(Task record, boolean empty) { super.updateItem(record, empty); if(!empty){ cellButton.setText("Something with "+record); setGraphic(cellButton); } else { setGraphic(null); } } } } 

现在,我必须创建一个ButtonCell extends TableCell是可以理解的。 但是如何将其分配给列?

我理解这一点:

 c1.setCellValueFactory( new PropertyValueFactory("date") ); 

但不是这个:

  TableColumn col_action = new TableColumn("Action"); col_action.setCellValueFactory( new Callback<TableColumn.CellDataFeatures, ObservableValue>() { @Override public ObservableValue call(TableColumn.CellDataFeatures p) { return new SimpleBooleanProperty(p.getValue() != null); } }); col_action.setCellFactory( new Callback<TableColumn, TableCell>() { @Override public TableCell call(TableColumn p) { return new ButtonCell(); } } ); 

为了能够呈现列, TableColumn需要cellValueFactory。 但是底层数据模型中不存在“action”列。 在这种情况下,我只是给cellValueFactory一些虚拟值并继续:

 public class JustDoIt extends Application { private final TableView table = new TableView<>(); private final ObservableList data = FXCollections.observableArrayList( new Person("Jacob", "Smith"), new Person("Isabella", "Johnson"), new Person("Ethan", "Williams"), new Person("Emma", "Jones"), new Person("Michael", "Brown") ); public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { stage.setWidth(450); stage.setHeight(500); TableColumn firstNameCol = new TableColumn("First Name"); firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName")); TableColumn lastNameCol = new TableColumn("Last Name"); lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName")); TableColumn actionCol = new TableColumn("Action"); actionCol.setCellValueFactory(new PropertyValueFactory<>("DUMMY")); Callback, TableCell> cellFactory = // new Callback, TableCell>() { @Override public TableCell call(final TableColumn param) { final TableCell cell = new TableCell() { final Button btn = new Button("Just Do It"); @Override public void updateItem(String item, boolean empty) { super.updateItem(item, empty); if (empty) { setGraphic(null); setText(null); } else { btn.setOnAction(event -> { Person person = getTableView().getItems().get(getIndex()); System.out.println(person.getFirstName() + " " + person.getLastName()); }); setGraphic(btn); setText(null); } } }; return cell; } }; actionCol.setCellFactory(cellFactory); table.setItems(data); table.getColumns().addAll(firstNameCol, lastNameCol, actionCol); Scene scene = new Scene(new Group()); ((Group) scene.getRoot()).getChildren().addAll(table); stage.setScene(scene); stage.show(); } public static class Person { private final SimpleStringProperty firstName; private final SimpleStringProperty lastName; private Person(String fName, String lName) { this.firstName = new SimpleStringProperty(fName); this.lastName = new SimpleStringProperty(lName); } 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); } } } 

这是我使用awesome Java 8function和扩展TableCell类的示例。

让我快速解释一下我在做什么:我创建了一个扩展TableCell的ActionButtonTableCell类。 然后你可以使用java 8 lamda函数为按钮创建一个Action。

 import java.util.function.Function; import javafx.event.ActionEvent; import javafx.scene.control.Button; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.util.Callback; public class ActionButtonTableCell extends TableCell { private final Button actionButton; public ActionButtonTableCell(String label, Function< S, S> function) { this.getStyleClass().add("action-button-table-cell"); this.actionButton = new Button(label); this.actionButton.setOnAction((ActionEvent e) -> { function.apply(getCurrentItem()); }); this.actionButton.setMaxWidth(Double.MAX_VALUE); } public S getCurrentItem() { return (S) getTableView().getItems().get(getIndex()); } public static  Callback, TableCell> forTableColumn(String label, Function< S, S> function) { return param -> new ActionButtonTableCell<>(label, function); } @Override public void updateItem(Button item, boolean empty) { super.updateItem(item, empty); if (empty) { setGraphic(null); } else { setGraphic(actionButton); } } } 

然后实现就像这样简单,这是一个从表中删除项目的示例按钮:

 column.setCellFactory(ActionButtonTableCell.forTableColumn("Remove", (Person p) -> { table.getItems().remove(p); return p; }));