2016-07-25 49 views
0

我一直在试图使用JavaFX在TableView中格式化Long值。JavaFX格式TableView中的SimpleLongProperty

我有下面的类来存储我要显示在表中的行:

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

    } 

然后我有initialize方法,我一直在试图重写updateItem方法来获取表中的控制器显示逗号作为千个分隔符:

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

         }; 
        } 
       } 
     ); 

这是填充TableView方法:

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

请帮助我通过展示如何做到这一点!我也尝试覆盖updateItem方法Long而不是SimpleLongProperty,并且我的IDE接受了该代码,但该表中的数字仍未格式化。

谢谢各位提前!

+0

什么是要在此列中显示的值。即总共是什么? – yamenk

+0

你没有显示你的单元格价值工厂是什么,或解释你实际看到的。 –

回答

1

LongProperty实现ObservableValue<Number>,不ObservableValue<Long>(或ObservableValue<SimpleLongProperty>)。所以你的表格列需要是TableColumn<DataByCurrencyPair, Number>类型,你的单元工厂需要相应地匹配那些类型。

这里有一个格式化柱与Long个简单的例子:

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

工程就像一个魅力,你评论@ yamenK的解决方案有助于理解cellValueFactory和cellFactory之间的区别。谢谢! – Hiltunea

0

无需设置Cellfactory,只需设置CellValueFactory即可。

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

这可能工作(在一些有限的情况下),但这不是一个好习惯。您正在有效地告诉表列它正在显示一个'String'数据,这与实际模型相矛盾,其中它是一个'Long'。例如,如果您想使其可编辑并使用“TextFieldTableCell”,则在提交编辑时将无法正确更新数据。预期的用途是'cellValueFactory'定义显示的数据,'cellFactory'定义* how *来显示它。对于这个用例,'cellFactory'是预期的解决方案。 –