1

JavaFX2 教程有一个地址簿示例,它是一个表格视图。

教程: http ://docs.oracle.com/javafx/2/fxml_get_started/fxml_tutorial_intermediate.htm#CACFEHBI

增强编辑单元格: http ://docs.oracle.com/javafx/2/ui_controls/table-view.htm

修改添加复选框: http: //download.oracle.com/otndocs/products/javafx/2.2/samples/Ensemble/index.html#SAMPLES/Controls/Table/Table Cell Factory

在文本框中输入数据并单击添加按钮将一行添加到表中。但是,不能删除行。我试图查看是否可以在每个单元格中添加一个删除按钮 - 单击它将删除该行。我修改了现有的示例代码。不知何故,按钮不可见。任何指针表示赞赏。

//FXML_tableview.fxml文件

<?import javafx.collections.*?> 
<?import javafx.geometry.Insets?>
<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.control.cell.*?>
<?import javafx.scene.layout.*?>
<?import fxmltableview.*?> 
 <Scene fx:id="root" width="550" height="550"
    fx:controller="fxmltableview.FXMLTableViewController" 
    xmlns:fx="http://javafx.com/fxml">      
    <GridPane alignment="center" hgap="10" vgap="10">
        <padding>
            <Insets top="10" right="10" bottom="10" left="10"/>
        </padding>

        <TableView fx:id="tableView" GridPane.columnIndex="0" 
                   GridPane.rowIndex="1">
        </TableView>

        <HBox spacing="10" alignment="bottom_right" GridPane.columnIndex="0" 
              GridPane.rowIndex="2">
            <TextField fx:id="firstNameField" promptText="First Name"
                       prefWidth="90"/>
            <TextField fx:id="lastNameField" promptText="Last Name"
                       prefWidth="90"/>
            <TextField fx:id="emailField" promptText="Email"
                       prefWidth="150"/>
            <Button text="Add" onAction="#addPerson"/>
        </HBox>
    </GridPane>
 </Scene>

// FXMLTableView.java

package fxmltableview;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.stage.Stage;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.util.Callback;

public class FXMLTableView extends Application {
   static public ObservableList<Person> data;
   @FXML Scene root;
   @FXML TableView tableView;
    @Override
    public void start(Stage primaryStage) throws Exception {

        primaryStage.setTitle("FXML TableView Example");
        root = (Scene)FXMLLoader.load(getClass().getResource("fxml_tableview.fxml"));
        primaryStage.setScene(root);
                data = FXCollections.observableArrayList(
                new Person(true, "Jacob", "Smith", "jacob.smith@example.com"),
                new Person(false, "Isabella", "Johnson", "isabella.johnson@example.com"),
                new Person(true, "Ethan", "Williams", "ethan.williams@example.com"),
                new Person(true, "Emma", "Jones", "emma.jones@example.com"),
                new Person(false, "Michael", "Brown", "michael.brown@example.com"));

        tableView = (TableView) root.lookup("#tableView");
        TableColumn delCol = new TableColumn<Person, Boolean>();
         delCol.setMinWidth(50);
        delCol.setCellFactory(new Callback<TableColumn<Person, Boolean>, TableCell<Person, Boolean>>() {

            public TableCell<Person, Boolean> call(TableColumn<Person, Boolean> p) {
                return new DeleteTableCell<Person, Boolean>();
            }
        });
        //"Invited" column
        TableColumn invitedCol = new TableColumn<Person, Boolean>();
        invitedCol.setText("Invited");
        invitedCol.setMinWidth(50);
        invitedCol.setCellValueFactory(new PropertyValueFactory("invited"));
        invitedCol.setCellFactory(new Callback<TableColumn<Person, Boolean>, TableCell<Person, Boolean>>() {

            public TableCell<Person, Boolean> call(TableColumn<Person, Boolean> p) {
                return new CheckBoxTableCell<Person, Boolean>();
            }
        });
        //"First Name" column
        TableColumn firstNameCol = new TableColumn();
        firstNameCol.setText("First");
        firstNameCol.setCellValueFactory(new PropertyValueFactory("firstName"));
        //"Last Name" column
        TableColumn lastNameCol = new TableColumn();
        lastNameCol.setText("Last");
        lastNameCol.setCellValueFactory(new PropertyValueFactory("lastName"));
        //"Email" column
        TableColumn emailCol = new TableColumn();
        emailCol.setText("Email");
        emailCol.setMinWidth(200);
        emailCol.setCellValueFactory(new PropertyValueFactory("email"));

        //Set cell factory for cells that allow editing
        Callback<TableColumn, TableCell> cellFactory =
                new Callback<TableColumn, TableCell>() {

                    public TableCell call(TableColumn p) {
                        return new EditingCell();
                    }
                };
        emailCol.setCellFactory(cellFactory);
        firstNameCol.setCellFactory(cellFactory);
        lastNameCol.setCellFactory(cellFactory);

        //Set handler to update ObservableList properties. Applicable if cell is edited
        updateObservableListProperties(emailCol, firstNameCol, lastNameCol);


        tableView.setItems(data);
        //Enabling editing
        tableView.setEditable(true);
        tableView.getColumns().addAll(invitedCol, firstNameCol, lastNameCol, emailCol, delCol);
 //       root.getChildren().add(tableView); 
        primaryStage.show();
    }
   private void updateObservableListProperties(TableColumn emailCol, TableColumn firstNameCol,
            TableColumn lastNameCol) {
        //Modifying the email property in the ObservableList
        emailCol.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Person, String>>() {           
            @Override public void handle(TableColumn.CellEditEvent<Person, String> t) {
                ((Person) t.getTableView().getItems().get(
                        t.getTablePosition().getRow())).setEmail(t.getNewValue());
            }
        });
        //Modifying the firstName property in the ObservableList
        firstNameCol.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Person, String>>() {          
            @Override public void handle(TableColumn.CellEditEvent<Person, String> t) {
                ((Person) t.getTableView().getItems().get(
                        t.getTablePosition().getRow())).setFirstName(t.getNewValue());
            }
        });
        //Modifying the lastName property in the ObservableList
        lastNameCol.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Person, String>>() {           
            @Override public void handle(TableColumn.CellEditEvent<Person, String> t) {
                ((Person) t.getTableView().getItems().get(
                        t.getTablePosition().getRow())).setLastName(t.getNewValue());
            }
        });
    }
   //CheckBoxTableCell for creating a CheckBox in a table cell
    public static class CheckBoxTableCell<S, T> extends TableCell<S, T> {
        private final CheckBox checkBox;
        private ObservableValue<T> ov;

        public CheckBoxTableCell() {
            this.checkBox = new CheckBox();
            this.checkBox.setAlignment(Pos.CENTER);

            setAlignment(Pos.CENTER);
            setGraphic(checkBox);
        } 

        @Override public void updateItem(T item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                setGraphic(checkBox);
                if (ov instanceof BooleanProperty) {
                    checkBox.selectedProperty().unbindBidirectional((BooleanProperty) ov);
                }
                ov = getTableColumn().getCellObservableValue(getIndex());
                if (ov instanceof BooleanProperty) {
                    checkBox.selectedProperty().bindBidirectional((BooleanProperty) ov);
                }
            }
        }
    }
     public static class DeleteTableCell<S, T> extends TableCell<S, T> {
        private final Button del;
        private ObservableValue<T> ov;

        public DeleteTableCell() {
            this.del = new Button("X");
            del.setStyle("-fx-base: red;");
            this.del.setAlignment(Pos.CENTER);

            setAlignment(Pos.CENTER);
            setGraphic(del);
            del.setOnAction(new EventHandler<ActionEvent> () {
                @Override
                public void handle(ActionEvent t) {
                    int i= getIndex();
                    FXMLTableView.data.remove(i);
                }                
            });
        } 

        @Override public void updateItem(T item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                setGraphic(del);
            }
        }
    }
    // EditingCell - for editing capability in a TableCell
    public static class EditingCell extends TableCell<Person, String> {
        private TextField textField;

        public EditingCell() {
        }

        @Override public void startEdit() {
            super.startEdit();

            if (textField == null) {
                createTextField();
            }
            setText(null);
            setGraphic(textField);
            textField.selectAll();
        }

        @Override public void cancelEdit() {
            super.cancelEdit();
            setText((String) getItem());
            setGraphic(null);
        }

        @Override public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);
            if (empty) {
                setText(null);
                setGraphic(null);
            } else {
                if (isEditing()) {
                    if (textField != null) {
                        textField.setText(getString());
                    }
                    setText(null);
                    setGraphic(textField);
                } else {
                    setText(getString());
                    setGraphic(null);
                }
            }
        }

        private void createTextField() {
            textField = new TextField(getString());
            textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
            textField.setOnKeyReleased(new EventHandler<KeyEvent>() {                
                @Override public void handle(KeyEvent t) {
                    if (t.getCode() == KeyCode.ENTER) {
                        commitEdit(textField.getText());
                    } else if (t.getCode() == KeyCode.ESCAPE) {
                        cancelEdit();
                    }
                }
            });
        }

        private String getString() {
            return getItem() == null ? "" : getItem().toString();
        }
    } 

    public static void main(String[] args) {
        launch(args);
    }
}

// FXMLTableViewController.java

package fxmltableview;

import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;

public class FXMLTableViewController {
    @FXML private TableView<Person> tableView;
    @FXML private TextField firstNameField;
    @FXML private TextField lastNameField;
    @FXML private TextField emailField;

    @FXML
    protected void addPerson(ActionEvent event) {
        ObservableList<Person> data = tableView.getItems();
        data.add(new Person(false, firstNameField.getText(),
            lastNameField.getText(),
            emailField.getText()
        ));

        firstNameField.setText("");
        lastNameField.setText("");
        emailField.setText("");   
    }


}

// Person.java

package fxmltableview;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;

//Person object
public class Person {
    private BooleanProperty invited;
    private StringProperty firstName;
    private StringProperty lastName;
    private StringProperty email;

    Person(boolean invited, String fName, String lName, String email) {
        this.invited = new SimpleBooleanProperty(invited);
        this.firstName = new SimpleStringProperty(fName);
        this.lastName = new SimpleStringProperty(lName);
        this.email = new SimpleStringProperty(email);
        this.invited = new SimpleBooleanProperty(invited);

        this.invited.addListener(new ChangeListener<Boolean>() {
            public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
                System.out.println(firstNameProperty().get() + " invited: " + t1);
            }
        });            
    }

    public BooleanProperty invitedProperty() { return invited; }

    public StringProperty firstNameProperty() { return firstName; }

    public StringProperty lastNameProperty() { return lastName; }

    public StringProperty emailProperty() { return email; }

    public void setLastName(String lastName) { this.lastName.set(lastName); }

    public void setFirstName(String firstName) { this.firstName.set(firstName); }

    public void setEmail(String email) { this.email.set(email); }
}
4

1 回答 1

1

缺少 delCol 的单元格值工厂。添加

delCol.setCellValueFactory(new PropertyValueFactory("invited"));

PropertyValueFactory 的参数在这里并不重要。

于 2012-12-13T12:31:31.447 回答