GWT CellTable


December 5, 2013 Maithilish

6.7. FactTable

This section uses GWT CellTable to display the data in a table. FactTable displays facts of a category for a specific date. FactTable may be nested within another FactTable, and inner FactTable can display facts of another category. Figure shows a nested FactTable where outer FactTable shows Facts as on Mar 2012 for category PL and inner FactTable displays Facts for category Cash Flow. On load, Snapshot displays Facts for the latest available date for each category.

FactTable
Figure 6.9. FactTable


Following UI declaration adds FactTable to Snapshot.
in.fins.client.content/Snapshot.ui.xml

        <g:customCell>
                <f:FactTable captionText="BS" category="BS">
                        <f:FactTable captionText="Holding" category="Shareholding" />
                </f:FactTable>
        </g:customCell>
        <g:customCell>
                <f:FactTable captionText="PL" category="PL">
                        <f:FactTable captionText="Cash Flow" category="Cash Flow" />
                </f:FactTable>
        </g:customCell>
        <g:customCell>
                <f:FactTable captionText="Q" category="Quarterly">
                </f:FactTable>
        </g:customCell>

So far, we were adding GWT widgets to custom widgets, but here we are adding a FactTable to another FactTable.
FactTable uses CaptionPanel, to displays category name with a stylish border, and a VerticalPanel to hold other widgets. VerticalPanel has a HorizontalPanel for header Label and a tool bar, a CellTable to display Facts in two column rows and a blank label at the bottom to have some gap to separate the child FactTable if there is one. FactTable dimensions are dynamic as all size are in PCT.
in.fins.client.widget/FactTable.ui.xml

        <g:CaptionPanel ui:field="captionPanel">
                <g:VerticalPanel ui:field="vPanel" width="100%">
                        <g:cell horizontalAlignment="right">
                                <g:HorizontalPanel ui:field="toolbar">
                                        <g:Label ui:field="header" width="100px" 
                                                 height="12px" />
                                </g:HorizontalPanel>
                        </g:cell>
                        <g:cell horizontalAlignment="left">
                                <c:CellTable ui:field="cellTable" width="100%" />
                        </g:cell>
                        <g:Label height="4px" styleName="fins-Spacer-Label" />
                </g:VerticalPanel>
        </g:CaptionPanel>

Next section adds a Toolbar to HorizontalPanel, and at present it contains just a Label to display the date. Cell attribute, horizontalAlignment aligns HorizontalPanel to right and CellTable to left.
CellTable displays the facts through a couple of TextColumn<Fact>, first one shows Fact.key and the second one, Fact.value. GWT TextColumn displays its contents in a TextCell, and all we have to do is to override its abstract getValue() method to display the Fact.
in.fins.client.widget/FactTable.java

        public void addColumns() {
                TextColumn<Fact> labelColumn = new TextColumn<Fact>() {
                        @Override
                        public String getValue(Fact fact) {
                                return fact.getKey();
                        }
                };
                TextColumn<Fact> valueColumn = new TextColumn<Fact>() {
                        @Override
                        public String getValue(Fact fact) {
                                return fact.getRoundoff();
                        }
                };
                cellTable.addColumn(labelColumn);
                cellTable.addColumn(valueColumn);

                valueColumn.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
        }

FactTable implements HasWidgets interface to manage the inner FactTable. Overridden add() method adds the inner FactTable if it is an instance of FactTable.
in.fins.client.widget/FactTable.java

        @Override
        public void add(Widget w) {
                if (w instanceof FactTable) {
                        vPanel.add(w);
                }
        }

        @Override
        public void clear() {
                vPanel.clear();
        }

        @Override
        public Iterator<Widget> iterator() {
                return vPanel.iterator();
        }

        @Override
        public boolean remove(Widget w) {
                return vPanel.remove(w);
        }

FactTable displays facts of a category and hence we can reuse the SymbolEvent fired by SymbolAction by implementing SymbolHandler.
in.fins.client.widget/FactTable.java

        @Override
        public void onSymbolChange(SymbolEvent symbolEvent) {
                log.fine("SymbolEvent received. " + symbolEvent.getSymbol());
                Symbol symbol = symbolEvent.getSymbol();
                Date date = SymbolHelper.getPositionDate(symbol, category);
                if (date != null) {
                        DateTimeFormat fmt = DateTimeFormat.getFormat("MMM yy");
                        setHeaderText(fmt.format(date));
                        dataProvider.setList(SymbolHelper.getFacts(symbol, 
                                              category,date));
                }
                setVisible(true);
        }

Instead of changing the data in CellTable directly, we are adding CellTable as data display to a ListDataProvider which is an adapter. In onSymbolChange() method, we call ListDataProvider.setList() to add list of required facts.
in.fins.client.widget/FactTable.java

        private ListDataProvider<Fact> dataProvider;

        @UiConstructor
        public FactTable(String captionText, String category) {
                initWidget(binder.createAndBindUi(this));

               ....

                dataProvider = new ListDataProvider<Fact>();
                dataProvider.addDataDisplay(cellTable);
                setVisible(false);
        }

All that is left is to add UiFactory method in snapshot where FactTable is added as handler to SymbolEvent fired by SymbolAction. Methods getFilterMap() and getFilter() are modified to add other categories like BS, PL,Shareholding, Cash Flow and Quarterly.
in.fins.client.content/Snapshot.java

        @UiFactory
        public FactTable factTableFactory(String captionText, String category) {
                FactTable ft = new FactTable(captionText, category);
                EventBus.get().addHandlerToSource(SymbolEvent.TYPE, this, ft);
                return ft;
        }

       private static Map<String, String[]> getFilterMap() {
                Map<String, String[]> filterMap = new HashMap<String, String[]>();
                filterMap.put("Quote", getFilter("Quote"));
                filterMap.put("BS", getFilter("BS"));
                filterMap.put("PL", getFilter("PL"));
                filterMap.put("Shareholding", getFilter("Shareholding"));
                filterMap.put("Cash Flow", getFilter("Cash Flow"));
                filterMap.put("Quarterly", getFilter("Quarterly"));
                return filterMap;
        }

        private static String[] getFilter(String cat) {
....
                if (cat.equals("BS")) {
                        return new String[] { "Capital", "Reserves", "Debt", "Cash", "FD",
                                        "Investment", "Gross Block", "Net Block", 
                                        "Cap. WIP" };
                }

                // other cats like PL, Shareholding etc

Events
Figure 6.10. Events


FactTable is bit simple when compared to the previous widget FactDisclosePanel, but things are going to get complicated when we add a Toolbar with click-able icons to navigate the Data in the next section.