2015-04-12 13 views
7

Ho un TableView in JavaFX. Ha un campo subTotal che dipende dal valore dei campi quantity e price. Ho aggiunto una nuova colonna per lo subTotal.Vista tabella JavaFX - il valore della colonna dipende da altre colonne

Sono presenti campi di testo per aggiungere una nuova riga alla tabella. Tuttavia, il pulsante Aggiungi desidera disporre di un altro textfield per subTotal, sebbene non sia realmente necessario per la colonna del totale parziale.

Quello che ho provato finora:

TableColumn columnCodeProduct = new TableColumn("Product Code"); 
columnCodeProduct.setMinWidth(100); 
columnCodeProduct.setCellValueFactory(new PropertyValueFactory<Data , Integer>("productname ")); 

TableColumn columnProductName = new TableColumn("Product Name"); 
columnProductName.setMinWidth(140); 
columnProductName.setCellValueFactory(new PropertyValueFactory<Data , String>("codeproduct")); 

TableColumn columnPrice = new TableColumn("Price"); 
columnPrice.setMinWidth(100); 
columnPrice.setCellValueFactory(new PropertyValueFactory<Data , Integer>("price")); 

TableColumn columQuantity = new TableColumn("Quantity"); 
columQuantity.setMinWidth(100); 
columQuantity.setCellValueFactory(new PropertyValueFactory<Data , Integer>("quantity")); 


TableColumn columnTotal = new TableColumn("Sub Total"); 
columnTotal.setMinWidth(100); 
columQuantity.setCellValueFactory(new PropertyValueFactory<Data , Integer>("sub")); 

tableData.getColumns().addAll(columnCodeProduct , columnProductName , columnPrice , columQuantity); 

tableData.setItems(data); 


addButton = new Button("Add Item"); 


addButton.setOnAction(new EventHandler<ActionEvent>() { 

    @Override 
    public void handle(ActionEvent event) 
    { 
     if(addproCodeTextfield.getText().isEmpty() || addproNameTextfield.getText().isEmpty() 
      || addPriceTextfield.getText().isEmpty() || quantityTextField.getText().isEmpty()) 
     { 
      System.out.println("Please Add information to all the fields"); 
     } else { 
      data.add(new Data (

          addproCodeTextfield.getText(), 
          addproNameTextfield.getText(), 
       addPriceTextfield.getText(),        
          quantityTextField.getText()));        
      methodTotal(); 
     } 
    } 
}); 

dati Classe

public class Data 
{ 
    private final SimpleStringProperty codeproduct; 
    private final SimpleStringProperty productname; 
    private final SimpleStringProperty price ; 
    private final SimpleStringProperty quantity; 



    public Data (String code , String proname , String presyo , String quant) 
    { 
     this.codeproduct = new SimpleStringProperty(code); 
     this.productname = new SimpleStringProperty(proname); 
     this.price = new SimpleStringProperty(presyo); 
     this.quantity = new SimpleStringProperty(quant); 

    } 

    public String getcodeProduct() 
    { 
     return codeproduct.get(); 
    } 

    public String getproductName() 
    { 
     return productname.get(); 
    } 

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

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

} 

risposta

5

Si può prendere beneficio dal potere di JavaFX per bind valore.

pochi punti di prendersi cura di, mentre l'attuazione di uno scenario come sopra:

  • La classe POJO (nel tuo caso Data) campi devono avere i tipi corretti. Ad esempio, il prezzo e la quantità devono essere di SimpleIntegerProperty anziché SimpleStringProperty. Questo ci aiuterà nell'uso di Bindings.
  • SubTotal il campo dipende dai valori di prezzo e quantità. Il modo migliore per raggiungere questo obiettivo è bindsubTotalProperty to a multiply Binding of price and quantity.

ho creato un (non così) semplice esempio di base modificabile Tableview per mostrare l'approccio. Ha caratteristiche aggiuntive, come le cellule modificabili, che voi (o altri che cercano lo stesso problema) potrebbe aver bisogno;)

import javafx.application.Application; 
import javafx.beans.binding.Bindings; 
import javafx.beans.binding.NumberBinding; 
import javafx.beans.property.SimpleIntegerProperty; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.geometry.Insets; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.control.*; 
import javafx.scene.control.TableColumn.CellEditEvent; 
import javafx.scene.control.cell.PropertyValueFactory; 
import javafx.scene.control.cell.TextFieldTableCell; 
import javafx.scene.layout.HBox; 
import javafx.scene.layout.VBox; 
import javafx.scene.text.Font; 
import javafx.stage.Stage; 
import javafx.util.converter.NumberStringConverter; 

public class TableViewSample extends Application { 

    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); 
     } 
    } 
} 

Schermata

enter image description here

Nota-ho definito setCellFactory e setOnCommit a ciascuna delle colonne. Questo perché le colonne nome, prezzo e quantità sono editable. Sei il benvenuto a rimuoverli nel caso in cui non cerchi proprietà modificabili.

+0

grazie :) è lavoro da parte del modo in cui aggiungere tutti i subtotali? – unknown

+0

Questo può essere in realtà una domanda separata :) – ItachiUchiha

3

Vorrei ristrutturare la classe del modello come suggerisce @ItachiUchiha. Se sentite il bisogno di mantenere i dati memorizzati con String rappresentazioni, si può semplicemente creare un'associazione per la colonna subtotal:

TableColumn<Data, Number> subtotalColumn = new TableColumn<>("Sub Total"); 
subTotalColumn.setCellValueFactory(cellData -> { 
    Data data = cellData.getValue(); 
    return Bindings.createDoubleBinding(
      () -> { 
       try { 
        double price = Double.parseDouble(data.getPrice()); 
        int quantity = Integer.parseInt(data.getQuantity()); 
        return price * quantity ; 
       } catch (NumberFormatException nfe) { 
        return 0 ; 
       } 
      }, 
      data.priceProperty(), 
      data.quantityProperty() 
    ); 
}); 
+0

Grazie, così facile! :) L'ho usato per aggiornare una colonna String con un valore calcolato da una stringa esadecimale nel mio modello. Per ciascuno da considerare: non volevo mostrare uno 0 valido per i dati non validi. Quindi ho usato una colonna String. Può mostrare una stringa vuota o "ERR" se l'analisi fallisce. Afaik, questo non è possibile con una colonna Numero. – Arjan

Problemi correlati