ventanas ventana usar una secundarias que pasar manejo entre desde datos controladores como botones boton abrir java button javafx tableview

usar - manejo de ventanas javafx



Cómo agregar botón en la vista de tabla de JavaFX (2)

He buscado en Google y Stackoverflow para esto y simplemente no obtengo los ejemplos dados. Puede alguien explicarmelo.

Quiero agregar un botón a la última columna de una vista de tabla y cuando se haga clic en él, debería activar un oyente y pasar el objeto de la fila de botones. Simplemente no recibo el siguiente ejemplo de gist.github.com :

Este es mi código actual completo:

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<Task> 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<Task, Boolean>, ObservableValue<Boolean>>() { @Override public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<Task, Boolean> p) { return new SimpleBooleanProperty(p.getValue() != null); } }); col_action.setCellFactory( new Callback<TableColumn<Task, Task>, TableCell<Task, Task>>() { @Override public TableCell<Task, Task> call(TableColumn<Task, Task> p) { return new ButtonCell(); } } ); c1.setCellValueFactory( new PropertyValueFactory<Task,Date>("date") ); c2.setCellValueFactory( new PropertyValueFactory<Task,Task.TaskType>("type") ); c3.setCellValueFactory( new PropertyValueFactory<Task,Double>("hours") ); c4.setCellValueFactory( new PropertyValueFactory<Task,Boolean>("done") ); c5.setCellValueFactory( new PropertyValueFactory<Task,Employee>("employee") ); c6.setCellValueFactory( new PropertyValueFactory<Task,Car>("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<Task, Task> { private Button cellButton; ButtonCell(){ cellButton = new Button("jjhjhjh"); cellButton.setOnAction(new EventHandler<ActionEvent>(){ @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); } } } }

Ahora, la parte en la que tengo que crear un ButtonCell extends TableCell es comprensible. Pero, ¿cómo asignar esto a la columna?

Entiendo esto:

c1.setCellValueFactory( new PropertyValueFactory<Task,Date>("date") );

Pero no esto:

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


Aquí está mi ejemplo usando la impresionante funcionalidad de Java 8 y extendiendo la clase TableCell.

Déjame darte una explicación rápida de lo que estoy haciendo: creé una clase ActionButtonTableCell que extiende TableCell. Y luego puedes usar las funciones java 8 lamda para crear una acción para el botón.

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<S> extends TableCell<S, Button> { 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 <S> Callback<TableColumn<S, Button>, TableCell<S, Button>> 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); } } }

La implementación es tan simple como esto. Este es un botón de muestra para eliminar el elemento de la tabla:

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


Para poder representar la columna, TableColumn necesita cellValueFactory. Pero la columna "acción" no existe en el modelo de datos subyacente. En este caso, solo le doy un valor ficticio a cellValueFactory y continúo:

public class JustDoIt extends Application { private final TableView<Person> table = new TableView<>(); private final ObservableList<Person> 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<TableColumn<Person, String>, TableCell<Person, String>> cellFactory = // new Callback<TableColumn<Person, String>, TableCell<Person, String>>() { @Override public TableCell call(final TableColumn<Person, String> param) { final TableCell<Person, String> cell = new TableCell<Person, String>() { 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); } } }