TableView:删除行后最后一行变得无法选择 - 这是一个错误

时间:2015-03-29 20:52:28

标签: tableview mouse javafx-8 rowdeleting

有关详细信息,请参阅此链接Sometimes TableView cannot select last row after row deletion。 只有在TableView必须包含6行时才会出现此问题。如果我删除第四行或第五行,则最后一行(必须是第五行)变得不可访问(不可选)。一旦我进行另一次线路抑制,那么无法到达的线路就会变得可以选择!!。

我的控制器具有以下代码:

public class FXMLIssueController implements Initializable {

@FXML
private TableView<User> userTable;
@FXML
private TableColumn<User, String> nameCol;
@FXML
private TableColumn<User, LocalDate> birthdayCol;
@FXML
private TableColumn<User, String> emailCol;
@FXML
private TextField name;
@FXML
private TextField email;
@FXML
private DatePicker birthday;
private ObservableList<User> data;
private LocalDate birth;

/**
 * Initializes the controller class.
 */
@Override
public void initialize(URL url, ResourceBundle rb) {
    // TODO
    data = FXCollections.observableArrayList();
    birthday.setOnAction((ActionEvent evnt) -> {
        birth = birthday.getValue();

    });
    userTable.getSelectionModel().selectedItemProperty().addListener(userListener);
    configureColumn();
    fill_in();
}

@FXML
private void newUser(ActionEvent event) {
    userTable.getSelectionModel().clearSelection();
    userTable.getSelectionModel().selectedItemProperty().removeListener(userListener);
    name.clear();
    birthday.valueProperty().set(null);
    email.clear();
    userTable.getSelectionModel().selectedItemProperty().addListener(userListener);
}

@FXML
private void addUser(ActionEvent event) {
    User u = new User();
    u.setName(name.getText());
    u.setEmail(email.getText());
    u.setBirthday(birthday.getValue());
    data.add(u);
}

@FXML
private void deleteUser(ActionEvent event) {
    User u = userTable.getSelectionModel().selectedItemProperty().getValue();
    if (u != null) {
        data.remove(u);
    }
}

@FXML
private void populate() {
data.clear();
fill_in();

}

private void configureColumn() {
    nameCol.setCellValueFactory(new PropertyValueFactory<User, String>("name"));
    emailCol.setCellValueFactory(new PropertyValueFactory<User, String>("email"));
    birthdayCol.setCellValueFactory(new PropertyValueFactory<User, LocalDate>("birthday"));
    birthdayCol.setCellFactory(p -> {
        return new TableCell<User, LocalDate>() {
            @Override
            protected void updateItem(LocalDate item, boolean empty) {
                super.updateItem(item, empty);
                if (item == null || empty) {
                    setText(null);
                } else {
                    final DateTimeFormatter format = DateTimeFormatter.ofPattern("dd/MM/yyyy");
                    setText(item.format(format));

                }
            }
        };
    });

}

private final ChangeListener<User> userListener = (value, oldV, newV) -> {
    if (oldV != null) {
        name.textProperty().unbindBidirectional(oldV.nameProperty());
        email.textProperty().unbindBidirectional(oldV.emailProperty());
        birthday.valueProperty().unbindBidirectional(oldV.birthdayProperty());

    }
    if (newV != null) {
        name.textProperty().bindBidirectional(newV.nameProperty());
        email.textProperty().bindBidirectional(newV.emailProperty());
        birthday.valueProperty().bindBidirectional(newV.birthdayProperty());

    }

};
private void fill_in(){
     for (int i = 0; i < 6; i++) {
        User u = new User();
        u.setName("u"+i);
        u.setBirthday(LocalDate.now().plusDays(i));
        u.setEmail("mail"+i+"@gmail.com");
        data.addAll(u);
    }
    userTable.setItems(data);
    userTable.getSelectionModel().select(0);

}

}

我的FXML文件:

<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="300.0" prefWidth="381.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="issue.FXMLIssueController">
   <bottom>
      <TableView fx:id="userTable" prefHeight="141.0" prefWidth="381.0" BorderPane.alignment="CENTER">
        <columns>
          <TableColumn fx:id="nameCol" prefWidth="75.0" text="Name" />
          <TableColumn fx:id="birthdayCol" prefWidth="163.0" text="Birthday" />
            <TableColumn fx:id="emailCol" prefWidth="141.0" text="Email" />
        </columns>
      </TableView>
   </bottom>
   <top>
      <HBox alignment="CENTER_RIGHT" prefHeight="40.0" prefWidth="381.0" spacing="10.0" BorderPane.alignment="CENTER">
         <children>
            <HBox alignment="CENTER_LEFT" prefHeight="30.0" prefWidth="213.0">
               <children>
                  <Button mnemonicParsing="false" onAction="#populate" text="Populate" />
               </children>
            </HBox>
            <Button mnemonicParsing="false" onAction="#newUser" text="New" />
            <Button mnemonicParsing="false" onAction="#addUser" text="Add" />
            <Button mnemonicParsing="false" onAction="#deleteUser" text="Delete" />
         </children>
         <padding>
            <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
         </padding>
      </HBox>
   </top>
   <center>
      <GridPane prefHeight="100.0" prefWidth="600.0" BorderPane.alignment="CENTER">
        <columnConstraints>
          <ColumnConstraints hgrow="SOMETIMES" maxWidth="294.0" minWidth="10.0" prefWidth="91.0" />
          <ColumnConstraints hgrow="SOMETIMES" maxWidth="477.0" minWidth="10.0" prefWidth="387.0" />
        </columnConstraints>
        <rowConstraints>
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
          <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
        </rowConstraints>
         <children>
            <Label text="Name:" />
            <Label text="Birthday" GridPane.rowIndex="1" />
            <Label text="email" GridPane.rowIndex="2" />
            <TextField fx:id="name" prefHeight="25.0" prefWidth="375.0" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" />
            <TextField fx:id="email" GridPane.columnIndex="1" GridPane.hgrow="ALWAYS" GridPane.rowIndex="2" />
            <DatePicker fx:id="birthday" prefHeight="25.0" prefWidth="346.0" GridPane.columnIndex="1" GridPane.rowIndex="1" />
         </children>
         <padding>
            <Insets bottom="7.0" left="7.0" right="7.0" top="7.0" />
         </padding>
      </GridPane>
   </center>
</BorderPane>

以下是用户类的代码:

public class User {

private final StringProperty name = new SimpleStringProperty();
private final StringProperty email = new SimpleStringProperty();
private final ObjectProperty<LocalDate> birthday = new SimpleObjectProperty<>();

public StringProperty nameProperty() {
    return name;
}

public String getName() {
    return name.get();
}

public void setName(String name) {
    this.name.set(name);
}

public StringProperty emailProperty() {
    return email;
}

public String getEmail() {
    return email.get();
}

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

public ObjectProperty<LocalDate> birthdayProperty() {
    return birthday;
}

public LocalDate getBirthday() {
    return birthday.get();
}

public void setBirthday(LocalDate birthday) {
    this.birthday.set(birthday);
} 


}

班级主要:

public class Test extends Application {

@Override
public void start(Stage stage) throws IOException {
    Parent root = FXMLLoader.load(getClass().getResource("/issue/FXMLIssue.fxml"));
    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.setResizable(false);
    stage.show();
}

/**
 * @param args the command line arguments
 */
public static void main(String[] args) {
    launch(args);
}}

我邀请您按如下方式测试该程序:

  • 删除第四行或第五行。
  • 尝试使用鼠标选择最后一行。
  • 如果没问题,请点击填充按钮,然后重试。

使用以下链接下载并测试该程序:

  1. complete project
  2. executable file

0 个答案:

没有答案