问题:当选择表中的多行并选择了行时,在更新数据时,所有选择的行都被取消选择,除了那一行是最后选择的行。
我做了什么:选择一行,按住Shift,选择另一行以选择多行。单击添加按钮。(出于测试目的,姓氏,姓氏和电子邮件被硬编码在添加按钮中。
我希望实现的目标:当用户选择多行时,该表将继续反映更新后的值,而不会取消选择我选择的行。
public class ObservableJFXTableView extends Application {
private final TableView<Person> table = new TableView<>();
private FilterMatcherEditor filterMatcherEditor = new FilterMatcherEditor();
private EventList<Person> people;
private ObservableList<Person> data;
final HBox hb = new HBox();
public static void main(String[] args){
launch(args);
}
private void setupGlazedList(){
people = new BasicEventList<Person>();
ObservableElementList.Connector<Person> personCOnnector = GlazedLists.beanConnector(Person.class);
EventList<Person> observedPeople = new ObservableElementList<Person>(people, personConnector);
EventList<Person> filtered_list = new FilterList<Person(observedPeople, filterMatcherEditor);
data = new EventObservableList<Person>(filtered_list);
}
private void populatedList(){
people.add(new Person("Jacob", "Smith", "a@example.com"));
people.add(new Person("James", "Johnson", "b@example.com"));
people.add(new Person("Christopher", "Lim", "c@example.com"));
people.add(new Person("Emma", "Jones", "d@example.com"));
people.add(new Person("Michael", "Brown", "a@example.com"));
}
@Override
public void start(Stage stage){
Scene scene = new Scene(new Group());
stage.setTitle("Table View Example");
stage.setWidth(450);
stage.setHeight(550);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial"), 20);
table.setEditable(true);
table.getSelectionModel().setSeletionMode(SelectionMode.MULTIPLE);
TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(new PropertyValueFactory<>("firstName"));
TableColumn<Person, String> lastNameCol = new TableColumn<>("Last Name");
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(new PropertyValueFactory<>("lastName"));
TableColumn<Person, String> emailCol = new TableColumn<>("Email");
emailCol.setMinWidth(100);
emailCol.setCellValueFactory(new PropertyValueFactory<>("email"));
setupGlazedList();
populatedList();
table.setItems(data);
table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
final Button editButton = new Button("Edit -> people.get(2)");
editButton.setOnAction((ActionEvent e) -> {
people.get(2).setFirstName("NewFirst");
people.get(2).setLastName("NewLast");
people.get(2).setEmail("NewEmail");
});
hb.getChildren().add(editButton);
hb.setSpacing(3);
final VBox vbox = new VBox();
vbox.setSpaceing(5);
vbox.setPadding(new Insets(10,0,0,10));
vbox.getChildren().addAll(filterMatcherEditor.getTextField(), label, table, hb);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
private static class FilterMatcherEditor extends AbstractMatcherEditor<Person>{
private TextField tf;
public FilterMatcherEditor(){
tf = new TextField();
tf.textProperty().addListener((observable, oldValue, newValue) -> filterChanged());
}
public TextField getTextField(){
return tf;
}
public void filterChanged(){
if (tf.getText().isEmpty())
this.fireMatchAll();
else
this.fireChanged(new FilterMatcher(tf.getText()));
}
private static class FilterMatcher implements Matcher {
private final String textFieldInput;
public FilterMatcher(String text){
this.textFieldInput = text;
}
public boolean matched(Object obj){
final Person person = (Person) obj;
for (Object obj: person.getAll()){
String str = ((String) obj).toUpperCase();
if ( str.contains(textFieldInput.toUpperCase()))
return true;
}
return false;
}
}
}
public class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProeprty lastName;
private final SimpleStringProperty email;
private final PropertyChangeSupport support = new PropertyChangeSupport(this);
private Person(String fName, String lName, String email){
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public void addPropertyChangeListener(PropertyChangeListener l){
support.addPropertyChangeListener(l);
}
public void removePropertyChangeListener(PropertyChangeListener l){
support.removePropertyChangeListener(l);
}
public String getFirstName(){
return firstName.get();
}
public void setFirstName(String str){
final String old = firstName.get();
firstName.set(str);
support.firePropertyCHange("firstName", old, str);
}
public String getLastName(){
return lastName.get();
}
public void setLastName(String str){
final String old = lastName.get();
lastName.set(str);
support.firePropertyCHange("lastName", old, str);
}
public String getEmail(){
return email.get();
}
public void setEmail(String str){
final String old = email.get();
email.set(str);
support.firePropertyCHange("email", old, str);
}
public List<String> getAll(){
List<String> strList = new ArrayList<String>();
strList.add(firstName.get());
strList.add(lastName.get());
strList.add(email.get());
return strList;
}
}
}