2015-04-13 4 views
0

У меня есть Tableview здесь, что позволяет мне умножить цену и количество и поместить это в колонку промежуточного итога. Мой вопрос: я хочу получить сумму всех промежуточных итогов для всех элементов в таблице, благодаряjavafx, добавляя все промежуточные итоги всех столбцов в tableview

private TableView<Product> table = new TableView<Product>(); 
private final ObservableList<Product> data = 
     FXCollections.observableArrayList(
       new Product("Notebook", 10, 12), 
       new Product("Eraser", 20, 12), 
       new Product("Pencil", 30, 12), 
       new Product("Pen", 40, 12), 
       new Product("Glue", 50, 12)); 
final HBox hb = new HBox(); 

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

@Override 
public void start(Stage stage) { 
    Scene scene = new Scene(new Group()); 
    stage.setTitle("Book Store Sample"); 
    stage.setWidth(650); 
    stage.setHeight(550); 

    final Label label = new Label("Book Store"); 
    label.setFont(new Font("Arial", 20)); 

    table.setEditable(true); 


    TableColumn name = new TableColumn("Name"); 
    name.setMinWidth(100); 
    name.setCellValueFactory(
      new PropertyValueFactory<Product, String>("name")); 
    name.setCellFactory(TextFieldTableCell.forTableColumn()); 
    name.setOnEditCommit(
      new EventHandler<CellEditEvent<Product, String>>() { 
       @Override 
       public void handle(CellEditEvent<Product, String> t) { 
        ((Product) t.getTableView().getItems().get(
          t.getTablePosition().getRow()) 
        ).setName(t.getNewValue()); 
       } 
      } 
    ); 


    TableColumn priceCol = new TableColumn("Price"); 
    priceCol.setMinWidth(100); 
    priceCol.setCellValueFactory(
      new PropertyValueFactory<Product, String>("price")); 
    priceCol.setCellFactory(TextFieldTableCell.<Product, Number>forTableColumn(new NumberStringConverter())); 
    priceCol.setOnEditCommit(
      new EventHandler<CellEditEvent<Product, Number>>() { 
       @Override 
       public void handle(CellEditEvent<Product, Number> t) { 
        ((Product) t.getTableView().getItems().get(
          t.getTablePosition().getRow()) 
        ).setPrice(t.getNewValue().intValue()); 
       } 
      } 
    ); 

    TableColumn quantityCol = new TableColumn("Quantity"); 
    quantityCol.setMinWidth(200); 
    quantityCol.setCellValueFactory(
      new PropertyValueFactory<Product, Number>("quantity")); 
    quantityCol.setCellFactory(TextFieldTableCell.<Product, Number>forTableColumn(new NumberStringConverter())); 
    quantityCol.setOnEditCommit(
      new EventHandler<CellEditEvent<Product, Number>>() { 
       @Override 
       public void handle(CellEditEvent<Product, Number> t) { 
        ((Product) t.getTableView().getItems().get(
          t.getTablePosition().getRow()) 
        ).setQuantity(t.getNewValue().intValue()); 
       } 
      } 
    ); 

    TableColumn subTotalCol = new TableColumn("Sub Total"); 
    subTotalCol.setMinWidth(200); 
    subTotalCol.setCellValueFactory(
      new PropertyValueFactory<Product, String>("subTotal")); 


    table.setItems(data); 
    table.getColumns().addAll(name, priceCol, quantityCol, subTotalCol); 

    final TextField addName = new TextField(); 
    addName.setPromptText("Name"); 
    addName.setMaxWidth(name.getPrefWidth()); 
    final TextField addPrice = new TextField(); 
    addPrice.setMaxWidth(priceCol.getPrefWidth()); 
    addPrice.setPromptText("Price"); 
    final TextField addQuantity = new TextField(); 
    addQuantity.setMaxWidth(quantityCol.getPrefWidth()); 
    addQuantity.setPromptText("Quantity"); 

    final Button addButton = new Button("Add"); 
    addButton.setOnAction(new EventHandler<ActionEvent>() { 
     @Override 
     public void handle(ActionEvent e) { 
      data.add(new Product(
        name.getText(), 
        Integer.parseInt(addPrice.getText()), 
        Integer.parseInt(addQuantity.getText()))); 
      addName.clear(); 
      addPrice.clear(); 
      addQuantity.clear(); 
     } 
    }); 

    hb.getChildren().addAll(addName, addPrice, addQuantity, addButton); 
    hb.setSpacing(3); 

    final VBox vbox = new VBox(); 
    vbox.setSpacing(5); 
    vbox.setPadding(new Insets(10, 0, 0, 10)); 
    vbox.getChildren().addAll(label, table, hb); 

    ((Group) scene.getRoot()).getChildren().addAll(vbox); 

    stage.setScene(scene); 
    stage.show(); 
} 

public static class Product { 

    private final SimpleStringProperty name; 
    private final SimpleIntegerProperty price; 
    private final SimpleIntegerProperty quantity; 
    private final SimpleIntegerProperty subTotal; 

    private Product(String name, int price, int quantity) { 
     this.name = new SimpleStringProperty(name); 
     this.price = new SimpleIntegerProperty(price); 
     this.quantity = new SimpleIntegerProperty(quantity); 
     this.subTotal = new SimpleIntegerProperty(); 
     NumberBinding multiplication = Bindings.multiply(this.priceProperty(), this.quantityProperty()); 
     this.subTotalProperty().bind(multiplication); 
    } 

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

    public SimpleStringProperty nameProperty() { 
     return name; 
    } 

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

    public int getPrice() { 
     return price.get(); 
    } 

    public SimpleIntegerProperty priceProperty() { 
     return price; 
    } 

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

    public int getQuantity() { 
     return quantity.get(); 
    } 

    public SimpleIntegerProperty quantityProperty() { 
     return quantity; 
    } 

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

    public int getSubTotal() { 
     return subTotal.get(); 
    } 

    public SimpleIntegerProperty subTotalProperty() { 
     return subTotal; 
    } 

    public void setSubTotal(int subTotal) { 
     this.subTotal.set(subTotal); 
    } 
} 

}

+0

Я не совсем понимаю «все промежуточные итоги, если я помещаю более одного списка промежуточных итогов»? Вы говорите, что у вас есть дополнительные свойства в классе 'Product', которые не показаны, и вы хотите получить итоговые значения? Или вы хотите получить сумму всех промежуточных итогов для всех элементов таблицы? –

+0

Я имею в виду, что хочу получить сумму всех промежуточных итогов для всех элементов в таблице. я сожалею о моем сложном вопросе. – unknown

+0

Пожалуйста, отредактируйте этот вопрос, чтобы сделать его более понятным. Таким образом, это будет более полезно для других людей. (У вас нет «более одного списка промежуточных итогов», что бы это ни значило.) –

ответ

0

Вы можете создать привязку, которая отслеживает общее количество всех субтотальных значений:

IntegerBinding total = Bindings.createIntegerBinding(() -> 
    table.getItems().stream().collect(Collectors.summingInt(Product::getSubTotal)), 
    table.getItems()); 

Первый ра rameter to this - это функция, которая вычисляет общее количество результатов вызова product.getSubTotal() для каждого элемента в table.getItems(). Второй аргумент гарантирует, что эта привязка отмечена как недействительная (поэтому ее можно пересчитать) в любое время table.getItems() является недействительным.

Использование механизма по умолчанию для построения списка, как и в случае с ObservableList<Product> data = FXCollections.observableArrayList(...), список будет признан недействительным, когда элементы будут добавлены, удалены или заменены, но не будет изменен, если изменяется subTotal существующего элемента. Чтобы это произошло, необходимо изменить эту строку, чтобы использовать extractor в:

private final ObservableList<Product> data = FXCollections.observableList(Arrays.asList(
    new Product("Notebook", 10, 12), 
    new Product("Eraser", 20, 12), 
    new Product("Pencil", 30, 12), 
    new Product("Pen", 40, 12), 
    new Product("Glue", 50, 12)), 
    product -> new Observable[] {product.subTotalProperty()}); 

Теперь вы можете сделать что-то вроде

Label totalLabel = new Label(); 
totalLabel.textProperty().bind(Bindings.format("Total: %d", total)); 

Update

Вот что IntegerBinding код выглядит как и без лямбда-выражения, хотя он гораздо менее ясен, и я не рекомендую это делать:

IntegerBinding total = Bindings.createIntegerBinding(new Callable<Integer>() { 
    @Override 
    public Integer call() { 
     return table.getItems().stream().collect(Collectors.summingInt(
      new ToIntFunction<Product>() { 
       @Override 
       public int applyAsInt(Product product) { 
        return product.getSubTotal(); 
       } 
      })); 
    } 
}, table.getItems()); 
+0

- это выражение лямбда? – unknown

+0

'product -> new Observable [] {...}' - это лямбда-выражение. –

+0

и IntegerBinding total = Bindings.createIntegerBinding (() -> «right?» Я имею в виду, что я еще не знаю, что является полностью лямбда-выражением, и то, что я знаю в выражении лямбда, - это когда вы делаете код короче чем обычный. Я прав? Можете ли вы показать код, который не написан в выражении лямбда? – unknown

Смежные вопросы