詳細については、このリンクを参照してください。TableView では、行の削除後に最後の行を選択できない場合があります。この問題は、TableView に正確に 6 行を含める必要がある場合にのみ発生します。4 行目または 5 行目を削除すると、最後の行 (必然的に 5 行目) にアクセスできなくなります (選択できなくなります)。別の回線抑制を行うとすぐに、到達不能ではなかった回線が選択可能になります!!.
私のコントローラーには次のコードがあります:
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);
}}
次のようにプログラムをテストすることをお勧めします。
- 4 行目または 5 行目を削除します。
- マウスを使用して最後の行を選択してみてください。
- 問題がなければ、入力ボタンをクリックして再試行してください。
次のリンクを使用して、プログラムをダウンロードしてテストします。