TableView - How to update a running balance column after any other column in the view is re-sorted

To keep this simple and to illustrate a problem that I am trying to solve let's say we have
a domain class that contains an income per day.
This class has two persistent properties - populated from a database table - date and income.
And there is one transient property - running balance - that shows the accumulated income
starting from the first record. This property is not persisted and it is used only to show
the running/accumulated income in a table view.
This domain object is shown in a table view with three columns:
     - date
     - income
     - running balance
The first two columns - date and income - are sortable. When the user clicks on the column
heading these can will be sorted in ascending or descending order. The running balance
column needs to reflect this change and be correctly updated.
So the question is : how would you implement the running balance update after the data in
the table has been updated by the user?
Take 1)
=============
The obvious approach is to use "setOnSort" method to consume the SortEvent event and re-sort the
data but the sort-event does not contain any useful information that would tell from which column
the sort event originated.
Take 2)
=============
Found a possible solution:
     - TableView.getSortOrder() returns a list that defines the order in which TableColumn instances are sorted after the user clicked one or more column headings.
     - TableColumn.getSortType() returns the sort type - ascending/descending.
     - This info can be used in the TableView.setOnSort() event handler to re-sort the data and update the balance at the same time.
Take 3)
=============
When the TableView.setOnSort() event handler is called the data is already sorted therefore the only thing that needs to be done is to update the running balance.

I  think I understand what you're trying to do. If I've missed it, apologies, but I think this will provide you with something you can work from anyway.
I would listen to the data instead of watching specifically for sorting. This will be much more robust if you add new functionality later (such as adding and removing rows, editing the data that's there, etc).
Specifically, for the runningBalance column, create a cellValueFactory that provides a DoubleBinding; this binding should listen for changes to the data and compute the value by running through the table's items up to the point of the item for which it's displaying the value. (Hope you can untangle that sentence.)
Example. The important part is the cellValueFactory for the cumulativeAmountCol. I guess I should mention that you shouldn't try this exact approach with very large tables as the performance might be pretty bad (computations of the order of n x m on changing data, where n is the number of rows in the table and m is the number of visible rows in the table).
import java.text.DateFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.binding.DoubleBinding;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.Callback;
public class CumulativeTableColumnExample extends Application {
  private final static int NUM_ITEMS = 20 ;
@Override
  public void start(Stage primaryStage) {
  final TableView<LineItem> table = new TableView<>();
  // using the extractor here makes sure the table item list fires a list changed event if any amounts change
  // this enables the cumulative amount column to keep up to date when the amount in a different row changes.
  table.setItems(FXCollections.observableList(createRandomData(), new Callback<LineItem, Observable[]>() {
      @Override
      public Observable[] call(LineItem item) {
        return new Observable[] {item.amountProperty()};
  final TableColumn<LineItem, Date> dateCol = new TableColumn<>("Date");
  final TableColumn<LineItem, Number> amountCol = new TableColumn<>("Amount");
  final TableColumn<LineItem, Number> cumulativeAmountCol = new TableColumn<>("Cumulative Amount");
  table.getColumns().addAll(Arrays.asList(dateCol, amountCol, cumulativeAmountCol));
  dateCol.setCellValueFactory(new PropertyValueFactory<LineItem, Date>("date"));
    amountCol.setCellValueFactory(new PropertyValueFactory<LineItem, Number>("amount"));
    cumulativeAmountCol.setCellValueFactory(new PropertyValueFactory<LineItem, Number>("amount"));
    cumulativeAmountCol.setSortable(false); // otherwise bad things might happen
  final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
  dateCol.setCellFactory(new Callback<TableColumn<LineItem, Date>, TableCell<LineItem, Date>>() {
      @Override
      public TableCell<LineItem, Date> call(TableColumn<LineItem, Date> col) {
        return new TableCell<LineItem, Date>() {
          @Override
          public void updateItem(Date date, boolean empty) {
            super.updateItem(date, empty);
            if (empty) {
              setText(null);
            } else {
              setText(dateFormat.format(date));
  cumulativeAmountCol.setCellValueFactory(new Callback<CellDataFeatures<LineItem, Number>, ObservableValue<Number>> () {
      @Override
      public ObservableValue<Number> call(CellDataFeatures<LineItem, Number> cellData) {
        final LineItem currentItem = cellData.getValue() ;
        DoubleBinding value = new DoubleBinding() {
            super.bind(table.getItems());
          @Override
          protected double computeValue() {
            double total = 0 ;
            LineItem item = null ;
            for (Iterator<LineItem> iterator = table.getItems().iterator(); iterator.hasNext() && item != currentItem; ) {
              item = iterator.next() ;
              total = total + item.getAmount() ;
            return total ;
        return value;
    final NumberFormat currencyFormat = NumberFormat.getCurrencyInstance();
  // generics hell.. can't wait for lambdas...
  final Callback<TableColumn<LineItem, Number>, TableCell<LineItem, Number>> currencyCellFactory = new Callback<TableColumn<LineItem, Number>, TableCell<LineItem, Number>>() {
      @Override
      public TableCell<LineItem, Number> call(TableColumn<LineItem, Number> column) {
        return new TableCell<LineItem, Number>() {
          @Override
          public void updateItem(Number amount, boolean empty) {
            if (empty) {
              setText(null) ;
            } else {
              setText(currencyFormat.format(amount));
    amountCol.setCellFactory(currencyCellFactory);
    cumulativeAmountCol.setCellFactory(currencyCellFactory);
    BorderPane root = new BorderPane();
  root.setCenter(table);
  primaryStage.setScene(new Scene(root, 600, 400));
  primaryStage.show();
  public List<LineItem> createRandomData() {
    Random rng = new Random();
    List<LineItem> items = new ArrayList<>();
    for (int i=0; i<NUM_ITEMS; i++) {
      Calendar cal = Calendar.getInstance();
      cal.add(Calendar.DAY_OF_YEAR, rng.nextInt(365)-365);
      double amount = (rng.nextInt(90000)+10000)/100.0 ;
      items.add(new LineItem(cal.getTime(), amount));
    return items ;
  public static void main(String[] args) {
  launch(args);
public static class LineItem {
    private final ObjectProperty<Date> date ;
    private final DoubleProperty amount ;
    public LineItem(Date date, double amount) {
      this.date = new SimpleObjectProperty<>(this, "date", date);
      this.amount = new SimpleDoubleProperty(this, "amount", amount);
    public final ObjectProperty<Date> dateProperty() {
      return date;
    public final Date getDate() {
      return date.get();
    public final void setDate(Date date) {
      this.date.set(date);
    public final DoubleProperty amountProperty() {
      return amount ;
    public final double getAmount() {
      return amount.get();
    public final void setAmount(double amount) {
      this.amount.set(amount);

Similar Messages

  • Checking; How do I get a balance computed after each entry?

    Checking: How do I get a balance posted after each entry?

    Specific answer depends on how you've set up the checkbook table.
    Assumed:
    Dates in column A
    Cheque numbers in B
    Cheques/withdrawls in C
    Deposits in D
    Running total in E.
    Opening balance in E1 (a Header row cell)
    in E2:
    =IF(C+D=0,"",E1-C+D)
    The first part of the IF statement keeps the cell (vusually) empty until an amount is entered into either column C or D. If either column has an amount entered, the current balance is calculated and displayed on that row.
    Fill the formula down through the rest of column E.
    Regards,
    Barry

  • How to update my mac book pro from 10.5.8 to the leatest version

    how to update my mac book pro from 10.5.8 to the leatest version

    Upgrading to Snow Leopard, Lion, or Mountain Lion
    Upgrading to Snow Leopard
    You can purchase Snow Leopard by contacting Customer Service: Contacting Apple for support and service - this includes international calling numbers. The price is $19.99 plus tax. You will receive physical media - DVD - by mail.
    Third-party sources for Snow Leopard are:
    Snow Leopard from Amazon.com
    Snow Leopard from eBay
    After you install Snow Leopard you will have to download and install the Mac OS X 10.6.8 Update Combo v1.1 to update Snow Leopard to 10.6.8 and give you access to the App Store.
    Before upgrading check that you computer meets the minimum requirements:
    Snow Leopard General requirements
      1. Mac computer with an Intel processor
      2. 1GB of memory
      3. 5GB of available disk space
      4. DVD drive for installation
      5. Some features require a compatible Internet service provider; fees may
          apply.
      6. Some features require Apple’s MobileMe service; fees and terms apply.
    Upgrading to Lion
    First, you need to upgrade to Snow Leopard 10.6.8 as stated above.
    You can purchase Lion by contacting Customer Service: Contacting Apple for support and service - this includes international calling numbers. The cost is $19.99 (as it was before) plus tax.  It's a download. You will get an email containing a redemption code that you then use at the Mac App Store to download Lion. Save a copy of that installer to your Downloads folder because the installer deletes itself at the end of the installation.
    Before upgrading check that you computer meets the minimum requirements:
    Lion System Requirements
      1. Mac computer with an Intel Core 2 Duo, Core i3, Core i5, Core i7, or
          Xeon processor
      2. 2GB of memory
      3. OS X v10.6.6 or later (v10.6.8 recommended)
      4. 7GB of available space
      5. Some features require an Apple ID; terms apply.
    Upgrading to Mountain Lion
    Be sure your computer meets the minimum requirements:
    Apple - OS X Mountain Lion - Read the technical specifications.
    Macs that can be upgraded to OS X Mountain Lion
      1. iMac (Mid 2007 or newer)
      2. MacBook (Late 2008 Aluminum, or Early 2009 or newer)
      3. MacBook Pro (Mid/Late 2007 or newer)
      4. MacBook Air (Late 2008 or newer)
      5. Mac mini (Early 2009 or newer)
      6. Mac Pro (Early 2008 or newer)
      7. Xserve (Early 2009)
    Are my applications compatible?
    See App Compatibility Table - RoaringApps - App compatibility and feature support for OS X & iOS.
    Am I eligible for the free upgrade?
    See Apple - Free OS X Mountain Lion upgrade Program.
    For a complete How-To introduction from Apple see Apple - Upgrade your Mac to OS X Mountain Lion.

  • App updates not running on ipad2 after upgrade to iOS 5 - anybody know or a solution or have same problem?

    App updates not running on ipad2 after upgrade to iOS 5 - anybody know or a solution or have same problem?

    Operator error! The mute button was on.

  • Hi, how can my store credit balance be removed so I can change the country

    hi, how can my store credit balance be removed so I can change the country?

    Click here and ask the iTunes Store staff to zero your account balance.
    (124934)

  • HT1461 Win 7 set up and running OK,but after go back from OSX the wireless net work stuck at identification cause the window working without Internet.Can we fix it or I must use Windows off line all the time? I already contact Microsoft 2 times for activa

    Win 7 set up and running OK,but after go back from OSX the wireless net work stuck at identification cause the window working without Internet.Can we fix it or I must use Windows off line all the time?
    I already contact Microsoft 2 times for activations.Hope I can fix from Apple instead.

    Ok....Got "Problem 2 and 4" solved....still trying to figure out this pop up everytime I click something...it's crazy how fast the pop up blinks...maybe once or 3 blinks then nothing till you close the window, then pop up then disappears...then click something
    else and pop up then gone....never seen this before...ive seen it when you tried to get online which turned out to be a virus on a customers cpu I worked on some years ago, I think it has something to do with the deleted files that I spoke of on last
    post...I notice it does it on start up as well.....think something is trying to install but not sure. Need to figure out where the appdata or start up folder and see whats in there....maybe it's in there.......so I might wait to see how it acts in the next
    couple days for "Problem 1"...but other than that it's running like a champ...so right now I just want to get the pop up windows to stop........thx again for everyone's help on this.
    John

  • How do I share photos in I photos with other users on the I mac

    How do I share photos in I photos with other users on the I mac

    iPhoto: Sharing libraries among multiple users

  • For iTunes Match, how come some songs "match" on an album and other songs on the same album "upload" without matching?

    For iTunes Match, how come some songs "match" on an album and other songs on the same album "upload" without matching?  All songs are available on iTunes.  I don't get it!  Any way to manually match songs that iTunes apparently can't match?  I have hundreds in this unmatched state.

    gsl wrote:
    Shazam has NO problem determining what these songs are. Maybe Apple needs to consider licensing their technology as it seems MUCH more accurate than what they are doing.
    You aren't comparing like with like.
    The main task that Shazam has is to identify the name or a track and the artist. I believe that it suggests the album as well, but if it gets that wrong then it doesn't really matter too much.
    With iTunes Match, getting the album (i.e. identifying which version it is) is much more important. If it gets that wrong then it breaks up the flow of an album. This makes the task that match has very much harder.
    In fact, there is a strong argument to say that currently the problem iTunes has is that it is matching too many songs, resulting in matches from different albums.
    I'm sure that match is not struggling to identify whether it has a song or not, but whether it has the correct version of a song. When you introduce different masterings into the process then, depending on the thresholds set, it is probably correct in concluding that it hasn't got a particular version, even if you think it has.
    The solution would appear to me to be a tweaking of the matching thresholds along with the ability to force an upload, but we just don't know what restrictions they have (remember that if Shazam gets it wrong the it doesn't present you with a copy of a new track that you didn't have previously). It is almost certainly not just a case of improving their technology.

  • Could u plz help me to find simple example for how to save data file in a spread sheet or any other way in the real time controller for Sbrio 9642 using memory or usb flash memory

    Could u plz help me to find simple example for how to save data file in a spread sheet or any other way in the real time controller for Sbrio 9642 using memory or usb flash memory

    Here are a few Links to a helpful Knowledge Base article and a White Paper that should help you out: http://digital.ni.com/public.nsf/allkb/BBCAD1AB08F1B6BB8625741F0082C2AF and http://www.ni.com/white-paper/10435/en/ . The methods for File IO in Real Time are the same for all of the Real Time Targets. The White Paper has best practices for the File IO and goes over how to do it. 
    Alex D
    Applications Engineer
    National Instruments

  • How do I get my contacts back after they've disappeared? the contacts are still stored in my phone

    how do I get my contacts back after they've disappeared? the contacts are still stored in my phone I just can't access them through my address book; only through Siri. I've restored my phone & that didn't work so what should I do?

    Re-enter them.
    Once they have been deleted from iCloud they are gone from all devices that sync to that iCloud account.

  • When trying to upload a PDF to an interactive site I get the announcement:"The attached PDF file references a non-embedded font Tahoma. Please remove file, embed the font and reattach." How do I embed this, or in fact any other font ?

    When trying to upload a PDF to an interactive site I get the announcement: "The attached PDF file references a non-embedded font Tahoma. Please remove file, embed the font and reattach."
    I could not get rid of the Tahoma font in the WORD file.
    How do I embed this, or in fact any other font ?

    Thank you very much !
    Indeed, I was unaware of the enormous number of options that can be selected when converting a WORD file to PDF.
    I went thru the settings and found the right one for embedding the fonts.
    Thanks again !
    Oren

  • When I try to use Mac Help or any other help menu, the help window opens up but it is empty.  How do I resolve this issue?

    When I try to use Mac Help or any other help menu, the help window opens up but it is empty.  How do I resolve this issue?

    Try moving these files to the Trash one at a time and test (but don't empty yet.)
    /Users/yourusername/Library/Preferences/com.apple.helpviewer.plist
    /Users/yourusername/Library/Preferences/com.apple.helpviewer.LSSharedFileList.pl ist
    If doing this doesn't help, then navigate to this location and delete the cache (but not the enclosing folder.)
    /Users/yourusername/Library/Caches/com.apple.helpviewer
    All are located in your home folder Library.

  • How I forward text from one iphone 4 to other, only forward the calls

    how I forward text from one iphone 4 to other, only forward the calls

    you can't forward incoming texts to another phone automatically.

  • I cannot Play Youtube or any other Videos in the Browser? It says Update FLASH Player though I have updated the Flash Player to latest version

    I cannot Play Youtube or any other Videos in the Browser. It says Update FLASH Player though I have updated the Flash Player to latest version. The Videos work fine in IE/Safari/Google Chrome
    == URL of affected sites ==
    http://
    == User Agent ==
    Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.1.249.1064 Safari/532.5

    Application Basics
    Name
    Firefox
    Version
    3.6.3
    Profile Directory
    Open Containing Folder
    Installed Plugins
    about:plugins
    Build Configuration
    about:buildconfig
    Extensions
    Name
    Version
    Enabled
    ID
    Dealio Toolbar Plugin
    4.0.2
    true
    [email protected]
    Search Settings Plugin
    1.2.3
    true
    [email protected]
    Skype extension for Firefox
    2.2.0.102
    false
    Java Console
    6.0.02
    true
    Java Console
    6.0.20
    true
    RealPlayer Browser Record Plugin
    1.1.4
    true
    Veoh Web Player Video Finder
    1.4
    true
    [email protected]
    Modified Preferences
    Name
    Value
    accessibility.typeaheadfind.flashBar
    0
    browser.places.importBookmarksHTML
    false
    browser.places.smartBookmarksVersion
    2
    browser.startup.homepage_override.mstone
    rv:1.9.2.3
    dom.max_script_run_time
    0
    extensions.lastAppVersion
    3.6.3
    network.cookie.prefsMigrated
    true
    places.last_vacuum
    1274198820
    privacy.popups.showBrowserMessage
    false
    privacy.sanitize.migrateFx3Prefs
    true
    security.warn_viewing_mixed
    false

  • How to get a running balance on a report

    How do I get a running balance for one customer. Please look at the data set as a example and advise. 
    Customer A  Apples
    1.00 Paid
    Customer A Pears
    2.00 Paid
    Customer A Oranges
    2.50 Open
    Balance  2.50
    What expression am I to use in report builder 
    Thanks

    Hi,
    Here is the example for getting running Value:
    http://gerryhubi.wordpress.com/2010/03/16/ssrs-tips-runningvalue/
    SSRS Tips – RunningValue
    Posted on March
    16, 2010by gerryhu2000
    Running value is a very generic and useful function.  All
    the 3 parameters can be manipulated for different purpose.
    ·         Expression
    the target on which the aggregation is applied. Most of the time it’s the column name in a dataset, or a combination of a few columns, e.g. “Group1 & Group2”.
    ·         Function
    Aggregate functions, and the most often used functions include
    Avg
    Returns the average of all non-null numeric values specified by the expression
    Count
    Returns a count of non-null values specified by the expression
    CountDistinct
    Returns a count of all distinct non-null values specified by the expression
    Max
    Returns the maximum value of all non-null numeric values specified by the expression.
    You can use this for specifying a chart axis maximum value to control the scale.
    Min
    Returns the minimum value of all non-null numeric values specified by the expression.
    You can use this for specifying a chart axis minimum value to control the scale.
    Sum
    Returns the sum of all the non-null numeric values specified by the expression
    ·         Scope
    The scope can be dataset, table or table groups.
    The sample report below shows some applications of RunningValue. The dataset uses this query
    SELECT Company, Product, InvoiceNumber, InvoiceAmount from InvoiceTable
    The table (SSRS table control) is configured to have 2 groups, “gCompany” and “gProduct”.
    Here is a report featured with Running Value tips
    Alternate
    color for Product Group
    Normally the “green-bar” (green background color for alternate rows) is implemented by setting
    the back ground color of the detail row to
      =IIF(RowNumber(Nothing)
    Mod 2,"Green","White")
    To set color for alternate groups, use the expression below for background color
    =IIF(RunningValue(Fields!Product.Value,CountDistinct,Nothing)
    Mod 2, "LightBlue", "White")
    The RunningValue function works like a counter/index for the product group.
    Running
    Sum value
    Cumulative sum is calculated in this expression:
    =RunningValue(Fields!Amount.Value,
    SUM, Nothing)
    “Scope = Nothing” means the outermost data region. And for Running Sum by Company or Product,
    the scope if set to the corresponding group name.
    =RunningValue(Fields!Amount.Value,
    SUM, “gCompany”) or
    =RunningValue(Fields!Amount.Value,
    SUM, “gProduct”)
    Group
    Running Number
    The summary table uses the same dataset as the details table. Normally the row number uses the
    function
    = RowNumber(“table1”)
    For this case, the row number is using the CountDistinct function. The expression is
    =RunningValue ( Fields!Company.Value +
    Fields!Product.Value,
    CountDistinct, Nothing)
    Notice that the 2 groups are both used, to prevent mixing products
    from different company.
    Thanks Shiven:) If Answer is Helpful, Please Vote

Maybe you are looking for

  • Save Image size setting in Save for Web

    I'm using Save for Web (CS3) and scaling the file to different sizes with "scale image". I'm wanting to use the same scale settings for many images but when I save the pre-set the image size settings don't get saved. I'm wanting to use it as part of

  • Can you copy music and apps from one iTunes account to another?

    My nephew got an iPod touch for Christmas and for some reason my husband decided to add it as a new device to my iTunes account and purchased games and music and put these onto the iPod.  So now he has access to my password, etc. What I really want t

  • Reg:Sales order datamigration

    Hi, we are currentely doing data migration from peoplesoft to  SAP SAP ECC 6.0. The migration include masterdata and salesorder with billing plan Can u please advice me releated to this topic. [email protected] Thanks, Senthil Edited by: Senthil Vadi

  • Only want exception cookies. I uncheck 'Accept cookies' & close & exit FF. Next time FireFox opens, the Accept cookies checked again. What gives?

    I set privacy options - Tell sites I do not want to be tracked - Use custom settings for history - Clear history when Firefox closes (I specify sites to accept cookies in Exceptions) When Firefox starts again, the 'Accept cookies from sites' is check

  • Aperture and Iphoto for Building Books

    I have purchased Aperture to streamline my digital processing for my new business. But I plan to produce lots of books for my clients. Will Aperture be as easy to produce books as iphoto? It is not for quickly sending an email. I hate the thought of