Add a button to a cells in a TableView (JAVAFX)

后端 未结 2 1444
轻奢々
轻奢々 2020-12-11 11:31

i am trying to add an edit Button to my table. when i click the button it will open a window with the item selected,I tried several approaches to add the button but no one

相关标签:
2条回答
  • 2020-12-11 12:05

    Here's one way you can do it.

    package tablebuttoncolumndemo;
    
    import javafx.application.Application;
    import javafx.beans.property.ObjectProperty;
    import javafx.beans.property.SimpleObjectProperty;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.scene.Scene;
    import javafx.scene.control.Alert;
    import javafx.scene.control.Alert.AlertType;
    import javafx.scene.control.Button;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.control.cell.PropertyValueFactory;
    import javafx.scene.layout.StackPane;
    import javafx.stage.Stage;
    
    public class TableButtonColumnDemo extends Application {
    
        @Override
        public void start(Stage primaryStage) {
    
            ObservableList<EditableFileRow> data = FXCollections.observableArrayList(
                    new EditableFileRow("A File"),
                    new EditableFileRow("A Big File"),
                    new EditableFileRow("A Lost File")
            );
    
            TableColumn editColumn = new TableColumn("Edit");
            editColumn.setCellValueFactory(new PropertyValueFactory<>("editButton"));
            TableColumn fileNameColumn = new TableColumn("File Name");
            fileNameColumn.setCellValueFactory(new PropertyValueFactory<>("fileName"));
            TableView table = new TableView();
            table.getColumns().addAll(editColumn, fileNameColumn);
            table.setItems(data);
    
            StackPane root = new StackPane();
    
            root.getChildren().add(table);
    
            Scene scene = new Scene(root, 300, 250);
    
            primaryStage.setTitle("Button Column Demo");
            primaryStage.setScene(scene);
    
            primaryStage.show();
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    
        public static class EditButton extends Button {
    
            public EditButton(String fileName) {
                super("Edit");
                setOnAction((event) -> {
                    Alert alert = new Alert(AlertType.INFORMATION);
                    alert.setTitle("Hey!");
                    alert.setHeaderText(null);
                    alert.setContentText("You're editing \"" + fileName + "\"");
                    alert.showAndWait();
                });
            }
        }
    
        public static class EditableFileRow {
    
            private final SimpleStringProperty fileName;
            private final SimpleObjectProperty<EditButton> editButton;
    
            public EditableFileRow(String fileName) {
                this.fileName = new SimpleStringProperty(fileName);
                editButton = new SimpleObjectProperty(new EditButton(fileName));
            }
    
            public String getFileName() {
                return fileName.get();
            }
    
            public void setFileName(String fName) {
                fileName.set(fName);
            }
    
            public StringProperty fileNameProperty() {
                return fileName;
            }
    
            public EditButton getEditButton() {
                return editButton.get();
            }
    
            public void setEditButton(EditButton editButton) {
                this.editButton.set(editButton);
            }
    
            public ObjectProperty<EditButton> editButtonProperty() {
                return editButton;
            }
    
        }
    }
    

    Another way you can try is to put an image instead of a button, with a listener that detects clicks. I often use that method to indicate what type of file it is using different images for pdf's, excel files, text files, and so on.

    0 讨论(0)
  • 2020-12-11 12:23

    Here is an alternative solution in which the cell value property for the edit column is a ReadOnlyObjectWrapper which wraps the entire "row object". Then it sets a cellFactory on the column to display the button. Since the item property of the cell represents the whole row, the value for the row can easily be accessed using cell.getItem().

    import java.util.function.Function;
    
    import javafx.application.Application;
    import javafx.beans.property.ReadOnlyObjectWrapper;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.beans.property.StringProperty;
    import javafx.beans.value.ObservableValue;
    import javafx.geometry.HPos;
    import javafx.geometry.Insets;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.control.Label;
    import javafx.scene.control.TableCell;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.control.TextField;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.ColumnConstraints;
    import javafx.scene.layout.GridPane;
    import javafx.scene.layout.Priority;
    import javafx.stage.Modality;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
    
    public class TableViewWithEditButton extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            TableView<Person> table = new TableView<>();
            table.getColumns().add(column("First Name", Person::firstNameProperty, 150));
            table.getColumns().add(column("Last Name", Person::lastNameProperty, 150));
            table.getColumns().add(column("Email", Person::emailProperty, 200));
    
            TableColumn<Person, Person> editColumn = column("Edit", ReadOnlyObjectWrapper<Person>::new, 60);
    
            table.getColumns().add(editColumn);
    
            editColumn.setCellFactory(col -> {
                Button editButton = new Button("Edit");
                TableCell<Person, Person> cell = new TableCell<Person, Person>() {
                    @Override
                    public void updateItem(Person person, boolean empty) {
                        super.updateItem(person, empty);
                        if (empty) {
                            setGraphic(null);
                        } else {
                            setGraphic(editButton);
                        }
                    }
                };
    
                editButton.setOnAction(e -> edit(cell.getItem(), primaryStage));
    
                return cell ;
            });
    
            table.getItems().addAll(
                    new Person("Jacob", "Smith", "jacob.smith@example.com"),
                    new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
                    new Person("Ethan", "Williams", "ethan.williams@example.com"),
                    new Person("Emma", "Jones", "emma.jones@example.com"),
                    new Person("Michael", "Brown", "michael.brown@example.com")
            );
    
            primaryStage.setScene(new Scene(new BorderPane(table)));
            primaryStage.show();
        }
    
        private void edit(Person person, Stage primaryStage) {
            TextField firstNameTextField = boundTF(person.firstNameProperty());
            TextField lastNameTextField = boundTF(person.lastNameProperty());
            TextField emailTextField = boundTF(person.emailProperty());
    
            GridPane grid = new GridPane();
            grid.setHgap(10);
            grid.setVgap(10);
            grid.setPadding(new Insets(16));
    
    
            grid.addRow(0, new Label("First name:"), firstNameTextField);
            grid.addRow(1, new Label("Last name:"), lastNameTextField);
            grid.addRow(2, new Label("Email:"), emailTextField);
    
            Button okButton = new Button("OK");
    
            grid.add(okButton, 0, 3, 2, 1);
    
            ColumnConstraints leftCol = new ColumnConstraints();
            leftCol.setHgrow(Priority.NEVER);
            leftCol.setHalignment(HPos.RIGHT);
            ColumnConstraints rightCol = new ColumnConstraints();
            rightCol.setHgrow(Priority.SOMETIMES);
            grid.getColumnConstraints().addAll(leftCol, rightCol);
            GridPane.setHalignment(okButton, HPos.CENTER);
    
            Scene scene = new Scene(grid);
            Stage stage = new Stage();
    
            okButton.setOnAction(e -> stage.hide());
            firstNameTextField.setOnAction(e -> stage.hide());
            lastNameTextField.setOnAction(e -> stage.hide());
            emailTextField.setOnAction(e -> stage.hide());
    
            stage.initModality(Modality.APPLICATION_MODAL);
            stage.initOwner(primaryStage);
            stage.initStyle(StageStyle.UNDECORATED);
            stage.setScene(scene);
            stage.show();
        }
    
        private TextField boundTF(StringProperty binding) {
            TextField textField = new TextField();
            textField.textProperty().bindBidirectional(binding);
            textField.setMinWidth(80);
            return textField ;
        }
    
        private <S,T> TableColumn<S,T> column(String title, Function<S, ObservableValue<T>> property, double width) {
            TableColumn<S,T> col = new TableColumn<>(title);
            col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
            col.setPrefWidth(width);
            return col ;
        }
    
        public static class Person {
            private final StringProperty firstName = new SimpleStringProperty();
            private final StringProperty lastName = new SimpleStringProperty();
            private final StringProperty email = new SimpleStringProperty();
    
            public Person(String firstName, String lastName, String email) {
                setFirstName(firstName);
                setLastName(lastName);
                setEmail(email);
            }
    
            public final StringProperty firstNameProperty() {
                return this.firstName;
            }
    
            public final java.lang.String getFirstName() {
                return this.firstNameProperty().get();
            }
    
            public final void setFirstName(final java.lang.String firstName) {
                this.firstNameProperty().set(firstName);
            }
    
            public final StringProperty lastNameProperty() {
                return this.lastName;
            }
    
            public final java.lang.String getLastName() {
                return this.lastNameProperty().get();
            }
    
            public final void setLastName(final java.lang.String lastName) {
                this.lastNameProperty().set(lastName);
            }
    
            public final StringProperty emailProperty() {
                return this.email;
            }
    
            public final java.lang.String getEmail() {
                return this.emailProperty().get();
            }
    
            public final void setEmail(final java.lang.String email) {
                this.emailProperty().set(email);
            }
    
    
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    
    0 讨论(0)
提交回复
热议问题