TableView navigates to the last row cell after commit edit when using extractor for TableView ObservableList

huangapple 未分类评论49阅读模式
英文:

TableView navigates to the last row cell after commit edit when using extractor for TableView ObservableList

问题

我有一个Bean类型的TableView,其中包含名称、数量、价格和总价列。这些列可以使用TextFieldTableCell进行更改,除了总列,它负责表示每行的总成本。此外,我定义了一个提取器来观察价格和数量属性的变化。以下是一些代码片段:

public void start(Stage primaryStage) {
    TableView<Bean> table = new TableView<>();
    table.setEditable(true);
    table.getSelectionModel().setCellSelectionEnabled(true);

    TableColumn<Bean, String> nameColumn = new TableColumn<>("名称");
    nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
    nameColumn.setCellFactory(TextFieldTableCell.forTableColumn());
    nameColumn.setOnEditCommit(e -> {
        Bean bean = e.getRowValue();
        bean.setName(e.getNewValue());
    });

    TableColumn<Bean, Integer> quantityColumn = new TableColumn<>("数量");
    quantityColumn.setCellValueFactory(new PropertyValueFactory<>("quantity"));
    quantityColumn.setCellFactory(TextFieldTableCell.forTableColumn(new StringConverter<>() {
        @Override
        public String toString(Integer object) {
            return object.toString();
        }

        @Override
        public Integer fromString(String string) {
            return Integer.parseInt(string);
        }
    }));
    quantityColumn.setOnEditCommit(e -> {
        Bean bean = e.getRowValue();
        bean.setQuantity(e.getNewValue());
    });

    TableColumn<Bean, Integer> priceColumn = new TableColumn<>("价格");
    priceColumn.setCellValueFactory(new PropertyValueFactory<>("price"));
    priceColumn.setCellFactory(TextFieldTableCell.forTableColumn(new StringConverter<>() {
        @Override
        public String toString(Integer object) {
            return object.toString();
        }

        @Override
        public Integer fromString(String string) {
            return Integer.parseInt(string);
        }
    }));
    priceColumn.setOnEditCommit(e -> {
        Bean bean = e.getRowValue();
        bean.setPrice(e.getNewValue());
    });

    TableColumn<Bean, Integer> totalColumn = new TableColumn<>("总价");
    totalColumn.setCellValueFactory(new PropertyValueFactory<>("totalPrice"));

    table.getColumns().addAll(nameColumn, priceColumn, quantityColumn, totalColumn);

    ObservableList<Bean> list = FXCollections.observableArrayList(bean -> new Observable[]{bean.priceProperty(), bean.quantityProperty()});
    list.add(new Bean("西红柿", 20, 100));
    list.add(new Bean("橙子", 10, 200));

    table.setItems(list);

    BorderPane pane = new BorderPane();
    pane.setCenter(table);

    Scene scene = new Scene(pane);
    Stage stage = new Stage();
    stage.setScene(scene);
    stage.show();
}

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

public class Bean {
    private SimpleStringProperty name;
    private SimpleIntegerProperty quantity;
    private SimpleIntegerProperty price;
    private SimpleIntegerProperty totalPrice;

    Bean(String name, Integer quantity, Integer price) {
        this.name = new SimpleStringProperty(name);
        this.quantity = new SimpleIntegerProperty(quantity);
        this.price = new SimpleIntegerProperty(price);
        this.totalPrice = new SimpleIntegerProperty(0);
        this.totalPrice.bind(Bindings.createIntegerBinding(() -> {
            return getQuantity() * getPrice();
        }, quantityProperty(), priceProperty()));
    }

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

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

    public Integer getQuantity() {
        return this.quantity.get();
    }

    public void setQuantity(Integer quantity) {
        this.quantity.set(quantity);
    }

    public SimpleIntegerProperty quantityProperty() {
        return this.quantity;
    }

    public Integer getPrice() {
        return this.price.get();
    }

    public void setPrice(Integer price) {
        this.price.set(price);
    }

    public SimpleIntegerProperty priceProperty() {
        return this.price;
    }

    public Integer getTotalPrice() {
        return this.totalPrice.get();
    }

    public void setTotalPrice(Integer totalPrice) {
        this.totalPrice.set(totalPrice);
    }
}

问题在于,每次我为ObservableList设置提取器后,在对价格或数量列进行编辑提交后,TableView会导航到当前行的最后一个单元格。

英文:

I have a TableView of Bean type that consists of name, quantity, price, and total price columns. These columns have the ability to be changed using TextFieldTableCell except the total column which is responsible for representing total cost of each row. Also, I have defined an extractor to observe price and quantity properties changes. Here is some piece of code:

public void start(Stage primaryStage) {
        TableView&lt;Bean&gt; table = new TableView&lt;&gt;();
        table.setEditable(true);
        table.getSelectionModel().setCellSelectionEnabled(true);
    
        TableColumn&lt;Bean, String&gt; nameColumn = new TableColumn&lt;&gt;(&quot;name&quot;);
        nameColumn.setCellValueFactory(new PropertyValueFactory&lt;&gt;(&quot;name&quot;));
        nameColumn.setCellFactory(TextFieldTableCell.forTableColumn());
        nameColumn.setOnEditCommit(e -&gt; {
            Bean bean = e.getRowValue();
            bean.setName(e.getNewValue());
        });
        
        TableColumn&lt;Bean, Integer&gt; quantityColumn = new TableColumn&lt;&gt;(&quot;quantity&quot;);
        quantityColumn.setCellValueFactory(new PropertyValueFactory&lt;&gt;(&quot;quantity&quot;));
        quantityColumn.setCellFactory(TextFieldTableCell.forTableColumn(new StringConverter&lt;&gt;() {
            @Override
            public String toString(Integer object) {
                return object.toString();
            }
    
            @Override
            public Integer fromString(String string) {
                return Integer.parseInt(string);
            }
        }));
        quantityColumn.setOnEditCommit(e -&gt; {
            Bean bean = e.getRowValue();
            bean.setQuantity(e.getNewValue());
        });
        
        TableColumn&lt;Bean, Integer&gt; priceColumn = new TableColumn&lt;&gt;(&quot;price&quot;);
        priceColumn.setCellValueFactory(new PropertyValueFactory&lt;&gt;(&quot;price&quot;));
        priceColumn.setCellFactory(TextFieldTableCell.forTableColumn(new StringConverter&lt;&gt;() {
            @Override
            public String toString(Integer object) {
                return object.toString();
            }
    
            @Override
            public Integer fromString(String string) {
                return Integer.parseInt(string);
            }
        }));
        quantityColumn.setOnEditCommit(e -&gt; {
            Bean bean = e.getRowValue();
            bean.setQuantity(e.getNewValue());
        });
        
        TableColumn&lt;Bean, Integer&gt; totalColumn = new TableColumn&lt;&gt;(&quot;total&quot;);
        totalColumn.setCellValueFactory(new PropertyValueFactory&lt;&gt;(&quot;totalPrice&quot;));
    
        table.getColumns().addAll(nameColumn, priceColumn, quantityColumn, totalColumn);
    
        ObservableList&lt;Bean&gt; list = FXCollections.observableArrayList(bean -&gt; new Observable[]{bean.priceProperty(), bean.quantityProperty()});
        list.add(new Bean(&quot;Tomato&quot;, 20, 100));
        list.add(new Bean(&quot;Orange&quot;, 10, 200));
        
        table.setItems(list);
    
        BorderPane pane = new BorderPane();
        pane.setCenter(table);
    
        Scene scene = new Scene(pane);
        Stage stage = new Stage();
        stage.setScene(scene);
        stage.show();
    }
    
    
    
    public static void main(String[] args) {
        launch(args);
    }

public class Bean {
    private SimpleStringProperty name;
    private SimpleIntegerProperty quantity;
    private SimpleIntegerProperty price;
    private SimpleIntegerProperty totalPrice;
    
    Bean(String name, Integer quantity, Integer price) {
        this.name = new SimpleStringProperty(name);
        this.quantity = new SimpleIntegerProperty(quantity);
        this.price = new SimpleIntegerProperty(price);
        this.totalPrice = new SimpleIntegerProperty(0);
        this.totalPrice.bind(Bindings.createIntegerBinding(() -&gt; {
            return getQuantity() * getPrice();
        }, quantityProperty(), priceProperty()));
    }
    
    public String getName() {
        return this.name.get();
    }
    
    public void setName(String name) {
        this.name.set(name);
    }
    
    public Integer getQuantity() {
        return this.quantity.get();
    }
    
    public void setQuantity(Integer quantity) {
        this.quantity.set(quantity);
    }
    
    public SimpleIntegerProperty quantityProperty() {
        return this.quantity;
    }
    
    public Integer getPrice() {
        return this.price.get();
    }
    
    public void setPrice(Integer price) {
        this.price.set(price);
    }
    
    public SimpleIntegerProperty priceProperty() {
        return this.price;
    }
    
    public Integer getTotalPrice() {
        return this.totalPrice.get();
    }
    
    public void setTotalPrice(Integer totalPrice) {
        this.totalPrice.set(totalPrice);
    }
}

The problem is every time I set an extractor for ObservableList, TableView navigates to the last cell of the current row after committing an edit on price or quantity column.

huangapple
  • 本文由 发表于 2020年5月4日 08:59:47
  • 转载请务必保留本文链接:https://java.coder-hub.com/61583640.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定