2016-07-25 6 views
0

Ich bin mit dem Versuch fest, Long Werte in einem TableView mit JavaFX zu formatieren.JavaFX-Format SimpleLongProperty in TableView

Ich habe folgende Klasse die Zeilen zu speichern, die ich auf dem Tisch angezeigt werden soll:

import java.text.DecimalFormat; 

    import javafx.beans.property.SimpleDoubleProperty; 
    import javafx.beans.property.SimpleLongProperty; 
    import javafx.beans.property.SimpleStringProperty; 

    public class DataByCurrencyPairRow { 

     private DecimalFormat integerFormat = new DecimalFormat("#,###"); 

     private SimpleStringProperty currencyPair = new SimpleStringProperty(""); 
     private SimpleDoubleProperty shareOfTotalVolume = new SimpleDoubleProperty(0); 
     private SimpleLongProperty totalVolume = new SimpleLongProperty(0); 
     private SimpleLongProperty currencyBought = new SimpleLongProperty(0); 
     private SimpleLongProperty currencySold = new SimpleLongProperty(0); 
     private SimpleLongProperty monthlyAverage = new SimpleLongProperty(0); 

     public DataByCurrencyPairRow() { 
      currencyPair.set(""); 
      shareOfTotalVolume.set(0); 
      totalVolume.set(0); 
      currencyBought.set(0); 
      currencySold.set(0); 
      monthlyAverage.set(0); 
     } 

     public String getCurrencyPair() { 
      return currencyPair.getValue(); 
     } 

     public void setCurrencyPair(String currencyPair) { 
      this.currencyPair.setValue(currencyPair); 
     } 

     public Long getMonthlyAverage() { 
      return monthlyAverage.getValue(); 
     } 

     public void setMonthlyAverage(Long monthlyAverage) { 
      this.monthlyAverage.setValue(monthlyAverage); 
     } 

     public Long getCurrencySold() { 
      return currencySold.getValue(); 
     } 

     public void setCurrencySold(Long currencySold) { 
      this.currencySold.setValue(currencySold); 
     } 

     public Long getCurrencyBought() { 
      return currencyBought.getValue(); 
     } 

     public void setCurrencyBought(Long currencyBought) { 
      this.currencyBought.setValue(currencyBought); 
     } 

     public Long getTotalVolume() {  
      return totalVolume.getValue(); 
     } 

     public void setTotalVolume(Long totalVolume) { 
      this.totalVolume.setValue(totalVolume); 
     } 

     public Double getShareOfTotalVolume() { 
      return shareOfTotalVolume.getValue(); 
     } 

     public void setShareOfTotalVolume(Double shareOfTotalVolume) { 
      this.shareOfTotalVolume.setValue(shareOfTotalVolume); 
     } 

    } 

Dann habe ich die Steuerung mit initialize Methode, wo ich die updateItem Methode außer Kraft zu setzen versucht haben, den Tisch zu bekommen Komma als Tausendertrennzeichen zu zeigen:

public class MainController { 

    private static final String DEFAULT_TIME_HORIZON = new String("0"); 
    private final NumberFormat integerFormat = new DecimalFormat("#,###"); 


    @FXML 
    TableView<DataByCurrencyPairRow> tableTransactionsByCurrencyPair; 

    @FXML 
    TableColumn<DataByCurrencyPairRow, Long> columnTotal; 


    @FXML 
    void initialize() { 

     columnTotal.setCellFactory(
       new Callback<TableColumn<DataByCurrencyPairRow, SimpleLongProperty>, TableCell<DataByCurrencyPairRow, SimpleLongProperty>>() { 

        @Override 
        public TableCell<DataByCurrencyPairRow, SimpleLongProperty> call(TableColumn<DataByCurrencyPairRow, SimpleLongProperty> param 
        ) { 
         return new TableCell<DataByCurrencyPairRow, SimpleLongProperty>() { 

          @Override 
          protected void updateItem(SimpleLongProperty item, boolean empty) { 
           super.updateItem(item, empty); 
           if (item == null || empty) { 
            setText("0"); 
            setStyle(""); 
           } else { 
            setText(integerFormat.format(item.longValue())); 
           } 
          } 

         }; 
        } 
       } 
     ); 

Und das ist die Methode, die die TableView auffüllt:

public void updateByCurrencyPairTable() { 
     System.out.println("#MainController: Updating data in table view Markets volumes by currency pair"); 

     ObservableList<DataByCurrencyPairRow> data = tableTransactionsByCurrencyPair.getItems(); 
     data.clear(); 

     // Add row items to the table view Markets volume by currency 
     for (DataByCurrencyPairRow row : customer.getDataByCurrencyPairR12m().getDataByCurrencyPair()) { 
      data.add(row); 
     } 
    } 

Bitte helfen Sie mir, indem Sie zeigen, wie dies zu tun ist !! Ich habe auch versucht, die updateItem Methode als anstelle von SimpleLongProperty zu überschreiben und meine IDE akzeptierte den Code, aber immer noch ist die Nummer nicht in der Tabelle formatiert.

Vielen Dank im Voraus !!!

+0

Was ist der Wert, den Sie in dieser Spalte angezeigt werden soll. d. h. insgesamt was? – yamenk

+0

Sie haben nicht gezeigt, was Ihre Zellenwertfabrik ist oder was Sie tatsächlich sehen. –

Antwort

1

LongPropertyObservableValue<Number> implementiert, nicht ObservableValue<Long> (oder ObservableValue<SimpleLongProperty>). Daher müssen Ihre Tabellenspalten vom Typ TableColumn<DataByCurrencyPair, Number> sein, und Ihre Zellenfabrik muss diese Typen entsprechend anpassen.

Hier ist ein einfaches Beispiel einer formatierten Spalte mit Long s:

import java.text.DecimalFormat; 
import java.text.NumberFormat; 
import java.util.Random; 

import javafx.application.Application; 
import javafx.beans.property.LongProperty; 
import javafx.beans.property.SimpleLongProperty; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 
import javafx.scene.Scene; 
import javafx.scene.control.TableCell; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableView; 
import javafx.stage.Stage; 

public class TableWithFormattedLong extends Application { 

    private final NumberFormat integerFormat = new DecimalFormat("#,###"); 

    @Override 
    public void start(Stage primaryStage) { 
     TableView<Item> table = new TableView<>(); 
     TableColumn<Item, String> itemColumn = new TableColumn<>("Item"); 
     itemColumn.setCellValueFactory(cellData -> cellData.getValue().nameProperty()); 

     TableColumn<Item, Number> valueColumn = new TableColumn<>("Value"); 
     valueColumn.setCellValueFactory(cellData -> cellData.getValue().valueProperty()); 

     valueColumn.setCellFactory(tc -> new TableCell<Item, Number>() { 
      @Override 
      protected void updateItem(Number value, boolean empty) { 
       super.updateItem(value, empty); 
       if (value == null || empty) { 
        setText(""); 
       } else { 
        setText(integerFormat.format(value)); 
       } 
      } 
     }); 

     table.getColumns().add(itemColumn); 
     table.getColumns().add(valueColumn); 

     Random rng = new Random(); 

     for (int i = 1 ; i <= 20 ; i++) { 
      table.getItems().add(new Item("Item "+i, rng.nextLong())); 
     } 

     primaryStage.setScene(new Scene(table, 600, 600)); 
     primaryStage.show(); 
    } 

    public static class Item { 
     private final StringProperty name = new SimpleStringProperty(); 
     private final LongProperty value = new SimpleLongProperty(); 

     public Item(String name, long value) { 
      setName(name); 
      setValue(value); 
     } 

     public final StringProperty nameProperty() { 
      return this.name; 
     } 


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


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


     public final LongProperty valueProperty() { 
      return this.value; 
     } 


     public final long getValue() { 
      return this.valueProperty().get(); 
     } 


     public final void setValue(final long value) { 
      this.valueProperty().set(value); 
     } 



    } 

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

Funktioniert wie ein Zauber und Sie kommentieren @ yamenKs Lösung, um den Unterschied zwischen cellValueFactory und cellFactory zu verstehen. Vielen Dank! – Hiltunea

0

Sie müssen Cellfactory nicht einstellen, sondern CellValueFactory setzen.

TableColumn<DataByCurrencyPairRow, String> columnTotal; 
columnTotal.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<DataByCurrencyPairRow,String>, ObservableValue<String>>() { 

      @Override 
      public ObservableValue<String> call(CellDataFeatures<DataByCurrencyPairRow, String> param) { 
       DataByCurrencyPairRow value = param.getValue(); 
       return new ReadOnlyStringWrapper(NumberFormat.getNumberInstance(Locale.US).format(123123)); //replace the number with the calculated total 
      } 
     }); 
+1

Dies könnte funktionieren (unter bestimmten Umständen), aber es ist keine gute Übung. Sie teilen der Tabellenspalte effektiv mit, dass sie Daten anzeigt, die eine "Zeichenkette" sind, was im Widerspruch zum tatsächlichen Modell steht, in dem es sich um eine "Lange" handelt. Wenn Sie dies beispielsweise bearbeiten möchten und eine 'TextFieldTableCell' verwenden möchten, ist es nicht möglich, die Daten bei der Übergabe von Änderungen korrekt zu aktualisieren. Die beabsichtigte Verwendung besteht darin, dass die 'cellValueFactory' die Daten definiert, die angezeigt werden, und die' cellFactory' definiert * how *, um sie anzuzeigen. Für diesen Anwendungsfall ist eine 'cellFactory' die beabsichtigte Lösung. –