2012-02-01 59 views
4

我已經搜索了GoogleCode,GWT ShowCase,GWT Developer Notes和Google Groups,瞭解如何獲取/設置CompositeCell的值。沒有一個明確的例子解釋瞭如何在CellTable中使用它。爲什麼在CellTable中沒有使用CompositeCell的體面示例?

讓我們盯着一些代碼...第一個抽象類...

public abstract class ToggleableGrid<T> extends CellTable<T> { 

private static final String DEFAULT_TABLE_WIDTH = "100%"; 
private static final DisplayMode DEFAULT_MODE = DisplayMode.VIEW; 

protected void setDefaults() { 
    setWidth(DEFAULT_TABLE_WIDTH); 
    // Set the message to display when the table is empty. 
    setEmptyTableWidget(new Label(UiMessages.INSTANCE.no_results())); 
    // Add a selection model so we can select cells 
    final SelectionModel<T> selectionModel = new MultiSelectionModel<T>(); 
    setSelectionModel(selectionModel, DefaultSelectionEventManager.<T> createDefaultManager()); 
} 

public void setInput(List<T> content) { 
    setInput(content, DEFAULT_MODE); 
} 

public void setInput(List<T> content, DisplayMode mode) { 
    setDefaults(); 
    resetTableColumns(); 
    final ListDataProvider<T> dataProvider = new ListDataProvider<T>(content); 
    final ListHandler<T> sortHandler = new ListHandler<T>(dataProvider.getList()); 
    addColumnSortHandler(sortHandler); 
    initializeStructure(constructMetadata(), sortHandler, mode); 
    dataProvider.addDataDisplay(this); 
} 

// see http://stackoverflow.com/questions/3772480/remove-all-columns-from-a-celltable 
// concrete classes are forced to maintain a handle on all columns added 
private void resetTableColumns() { 
    for (final Column<T, ?> column: allColumns()) { 
     removeColumn(column); 
    } 
    allColumns().clear(); 
} 

public boolean isInEditMode(DisplayMode currentDisplayMode) { 
    boolean result = false; 
    if (currentDisplayMode == DisplayMode.EDIT) { 
     result = true; 
    } 
    return result; 
} 

protected abstract Set<Column<T, ?>> allColumns(); 

protected abstract TableMetadata constructMetadata(); 

protected abstract void initializeStructure(TableMetadata metadata, ListHandler<T> sortHandler, DisplayMode mode); 

protected void setColumnHorizontalAlignment(Column<T, ?> column, HorizontalAlignmentConstant alignment) { 
    column.setHorizontalAlignment(alignment); 
} 

@Override 
public void addColumn(Column<T, ?> column, String columnHeaderName) { 
    final StringBuffer sb = new StringBuffer(); 
    sb.append("<div align=\"right\">").append(columnHeaderName).append("</div>"); 
    final SafeHtml header = new OnlyToBeUsedInGeneratedCodeStringBlessedAsSafeHtml(sb.toString()); 
    addColumn(column, header); 
    allColumns().add(column); 
} 

}

然後具體的實現......

public class EnergyOfferGrid extends ToggleableGrid<EnergyOfferDTO> { 

private static final int MAX_NUMBER_OF_MW_PRICE_POINTS = 10; 

private Set<Column<EnergyOfferDTO, ?>> columns = new HashSet<Column<EnergyOfferDTO, ?>>(); 

@Override 
protected Set<Column<EnergyOfferDTO, ?>> allColumns() { 
    return columns; 
} 

@Override 
protected TableMetadata constructMetadata() { 
    final TableMetadata metadata = new TableMetadata(); 

    // TODO Consider a predefined set of ReferenceData to be held in a common package 

    // Use Slope 
    metadata.addColumnMetadata(UiMessages.INSTANCE.use_slope(), new String[] {UiMessages.INSTANCE.yes(), UiMessages.INSTANCE.no()}, new String[] {"true", "false"}); 

    return metadata; 
} 

@Override 
protected void initializeStructure(TableMetadata metadata, ListHandler<EnergyOfferDTO> sortHandler, DisplayMode currentDisplayMode) { 
    addHourColumn(sortHandler); 
    addUseSlopeColumn(metadata, sortHandler, currentDisplayMode); 
    for (int i = 1; i <= MAX_NUMBER_OF_MW_PRICE_POINTS; i++) { 
     addPriceMwColumn(i, currentDisplayMode); 
    } 
} 

protected void addHourColumn(ListHandler<EnergyOfferDTO> sortHandler) { 
    final Column<EnergyOfferDTO, String> hourColumn = new Column<EnergyOfferDTO, String>(new TextCell()) { 

     @Override 
     public String getValue(EnergyOfferDTO energyOffer) { 
      String result = ""; 
      final String isoDateTime = energyOffer.getDateTime(); 
      if (isoDateTime != null && !isoDateTime.isEmpty()) { 
       final Date dateTime = TimeUtil.isoToDate(isoDateTime); 
       if (dateTime != null) { 
        result = TimeUtil.dateToHour(dateTime); 
       } 
      } 
      return result; 
     } 

    }; 
    hourColumn.setSortable(true); 
    sortHandler.setComparator(hourColumn, new Comparator<EnergyOfferDTO>() { 
     @Override 
     public int compare(EnergyOfferDTO eo1, EnergyOfferDTO eo2) { 
      return eo1.getDateTime().compareTo(eo2.getDateTime()); 
     } 
    }); 

    addColumn(hourColumn, UiMessages.INSTANCE.hour()); 
    setColumnWidth(hourColumn, 10, Unit.PCT); 
    setColumnHorizontalAlignment(hourColumn, HasHorizontalAlignment.ALIGN_RIGHT); 
} 


protected void addUseSlopeColumn(TableMetadata metadata, ListHandler<EnergyOfferDTO> sortHandler, DisplayMode currentDisplayMode) { 
    final ReferenceData refData = metadata.allColumnMetadata().get(UiMessages.INSTANCE.use_slope()); 
    Column<EnergyOfferDTO, String> useSlopeColumn; 
    Cell<String> cell; 
    if (isInEditMode(currentDisplayMode)) { 
     cell = new ReferenceDataBackedSelectionCell(refData); 
    } else { 
     cell = new TextCell(); 
    } 
    useSlopeColumn = new Column<EnergyOfferDTO, String>(cell) { 

     @Override 
     public String getValue(EnergyOfferDTO energyOffer) { 
      return refData.getDisplayValueForSubmitValue(Boolean.toString(energyOffer.isSlope())); 
     } 

    }; 

    useSlopeColumn.setSortable(true); 
    sortHandler.setComparator(useSlopeColumn, new Comparator<EnergyOfferDTO>() { 
     @Override 
     public int compare(EnergyOfferDTO eo1, EnergyOfferDTO eo2) { 
      return eo1.getDateTime().compareTo(eo2.getDateTime()); 
     } 
    }); 

    addColumn(useSlopeColumn, UiMessages.INSTANCE.use_slope()); 
    setColumnWidth(useSlopeColumn, 10, Unit.PCT); 
    setColumnHorizontalAlignment(useSlopeColumn, HasHorizontalAlignment.ALIGN_RIGHT); 
} 

protected void addPriceMwColumn(final int colIndex, DisplayMode currentDisplayMode) { 

    // Construct a composite cell for energy offers that includes a pair of text inputs 
    final List<HasCell<EnergyOfferDTO, ?>> hasCells = new ArrayList< 
      HasCell<EnergyOfferDTO, ?>>(); 

    // this DTO is passed along so that price and mw values for new entries are kept together 
    final OfferPriceMwPairDTO newOfferPriceMwPairDTO = new OfferPriceMwPairDTO(); 

    // Price 
    final HasCell<EnergyOfferDTO, String> priceCell = generatePriceCell(colIndex, newOfferPriceMwPairDTO, currentDisplayMode); 
    hasCells.add(priceCell); 

    // MW 
    final HasCell<EnergyOfferDTO, String> mwCell = generateMwCell(colIndex, newOfferPriceMwPairDTO, currentDisplayMode); 
    hasCells.add(mwCell); 

    // Composite 
    final CompositeCell<EnergyOfferDTO> priceMwCell = generateCompositeCell(hasCells); 

    final Column<EnergyOfferDTO, EnergyOfferDTO> priceMwColumn = new Column<EnergyOfferDTO, EnergyOfferDTO>(priceMwCell) { 

     @Override 
     public EnergyOfferDTO getValue(EnergyOfferDTO energyOffer) { 
      // we do this to satisfy the anonymous type's contract, 
      // but know that this column's composite cell delegates to its individual cell impls to get a value 
      return null; 
     } 

    }; 

    addColumn(priceMwColumn, String.valueOf(colIndex)); 
    setColumnWidth(priceMwColumn, 8, Unit.PCT); 
    setColumnHorizontalAlignment(priceMwColumn, HasHorizontalAlignment.ALIGN_RIGHT); 
} 

protected HasCell<EnergyOfferDTO, String> generatePriceCell(final int colIndex, final OfferPriceMwPairDTO newOfferPriceMwPair, DisplayMode currentDisplayMode) { 
    HasCell<EnergyOfferDTO, String> priceCell; 

    if (isInEditMode(currentDisplayMode)) { 
     priceCell = new HasCell<EnergyOfferDTO, String>() { 

      private TextInputCell cell = new TextInputCell(); 

      @Override 
      public Cell<String> getCell() { 
       return cell; 
      } 

      @Override 
      public FieldUpdater<EnergyOfferDTO, String> getFieldUpdater() { 
       return new FieldUpdater<EnergyOfferDTO, String>() { 
        @Override 
        public void update(int index, EnergyOfferDTO energyOffer, String value) { 
         if (value != null && !value.isEmpty()) { 
          // number format exceptions should be caught and handled by event bus's handle method 
          final double valueAsDouble = NumberFormat.getDecimalFormat().parse(value); 

          final BigDecimal price = BigDecimal.valueOf(valueAsDouble); 
          final List<OfferPriceMwPairDTO> offerPriceCurve = energyOffer.getOfferPriceCurve(); 
          final OfferPriceMwPairDTO offerPriceMwPairDTO = offerPriceCurve.get(colIndex); 
          if (offerPriceMwPairDTO == null) { // we have a new price value 
           newOfferPriceMwPair.setPrice(price); 
           offerPriceCurve.add(newOfferPriceMwPair); 
          } else { 
           offerPriceMwPairDTO.setPrice(price); 
          } 

         } 
        } 
       }; 
      } 

      @Override 
      public String getValue(EnergyOfferDTO energyOffer) { 
       String result = ""; 
       if (energyOffer != null) { 
        final List<OfferPriceMwPairDTO> offerPriceCurve = energyOffer.getOfferPriceCurve(); 
        final OfferPriceMwPairDTO offerPriceMwPairDTO = offerPriceCurve.get(colIndex); 
        if (offerPriceMwPairDTO != null) { 
         final BigDecimal price = offerPriceMwPairDTO.getPrice(); 
         result = String.valueOf(price.doubleValue()); 
        } 
       } 
       return result; 
      } 
     }; 
    } else { 
     priceCell = new Column<EnergyOfferDTO, String>(new TextCell()) { 

      @Override 
      public String getValue(EnergyOfferDTO energyOffer) { 
       String result = ""; 
       if (energyOffer != null) { 
        final List<OfferPriceMwPairDTO> offerPriceCurve = energyOffer.getOfferPriceCurve(); 
        final OfferPriceMwPairDTO offerPriceMwPairDTO = offerPriceCurve.get(colIndex); 
        if (offerPriceMwPairDTO != null) { 
         final BigDecimal price = offerPriceMwPairDTO.getPrice(); 
         result = String.valueOf(price.doubleValue()); 
        } 
       } 
       return result; 
      } 
     }; 
    } 
    return priceCell; 
} 

protected HasCell<EnergyOfferDTO, String> generateMwCell(final int colIndex, final OfferPriceMwPairDTO newOfferPriceMwPair, DisplayMode currentDisplayMode) { 
    HasCell<EnergyOfferDTO, String> mwCell; 

    if (isInEditMode(currentDisplayMode)) { 
     mwCell = new HasCell<EnergyOfferDTO, String>() { 

      private TextInputCell cell = new TextInputCell(); 

      @Override 
      public Cell<String> getCell() { 
       return cell; 
      } 

      @Override 
      public FieldUpdater<EnergyOfferDTO, String> getFieldUpdater() { 
       return new FieldUpdater<EnergyOfferDTO, String>() { 
        @Override 
        public void update(int index, EnergyOfferDTO energyOffer, String value) { 
         if (value != null && !value.isEmpty()) { 
          // number format exceptions should be caught and handled by event bus's handle method 
          final double valueAsDouble = NumberFormat.getDecimalFormat().parse(value); 

          final BigDecimal mw = BigDecimal.valueOf(valueAsDouble); 
          final List<OfferPriceMwPairDTO> offerPriceCurve = energyOffer.getOfferPriceCurve(); 
          final OfferPriceMwPairDTO offerPriceMwPairDTO = offerPriceCurve.get(colIndex); 
          if (offerPriceMwPairDTO == null) { // we have a new mw value 
           newOfferPriceMwPair.setMw(mw); 
           offerPriceCurve.add(newOfferPriceMwPair); 
          } else { 
           offerPriceMwPairDTO.setMw(mw); 
          } 

         } 
        } 
       }; 
      } 

      @Override 
      public String getValue(EnergyOfferDTO energyOffer) { 
       String result = ""; 
       if (energyOffer != null) { 
        final List<OfferPriceMwPairDTO> offerPriceCurve = energyOffer.getOfferPriceCurve(); 
        final OfferPriceMwPairDTO offerPriceMwPairDTO = offerPriceCurve.get(colIndex); 
        if (offerPriceMwPairDTO != null) { 
         final BigDecimal mw = offerPriceMwPairDTO.getMw(); 
         result = String.valueOf(mw.doubleValue()); 
        } 
       } 
       return result; 
      } 
     }; 
    } else { 
     mwCell = new Column<EnergyOfferDTO, String>(new TextCell()) { 

      @Override 
      public String getValue(EnergyOfferDTO energyOffer) { 
       String result = ""; 
       if (energyOffer != null) { 
        final List<OfferPriceMwPairDTO> offerPriceCurve = energyOffer.getOfferPriceCurve(); 
        final OfferPriceMwPairDTO offerPriceMwPairDTO = offerPriceCurve.get(colIndex); 
        if (offerPriceMwPairDTO != null) { 
         final BigDecimal mw = offerPriceMwPairDTO.getMw(); 
         result = String.valueOf(mw.doubleValue()); 
        } 
       } 
       return result; 
      } 
     }; 
    } 
    return mwCell; 
} 

protected CompositeCell<EnergyOfferDTO> generateCompositeCell(final List<HasCell<EnergyOfferDTO, ?>> hasCells) { 
    final CompositeCell<EnergyOfferDTO> compositeCell = new CompositeCell<EnergyOfferDTO>(hasCells) { 

     @Override 
     public void render(Context context, EnergyOfferDTO value, SafeHtmlBuilder sb) { 
      sb.appendHtmlConstant("<table><tbody><tr>"); 
      for (final HasCell<EnergyOfferDTO, ?> hasCell : hasCells) { 
       render(context, value, sb, hasCell); 
      } 
      sb.appendHtmlConstant("</tr></tbody></table>"); 
     } 

     @Override 
     protected Element getContainerElement(Element parent) { 
      // Return the first TR element in the table. 
      return parent.getFirstChildElement().getFirstChildElement().getFirstChildElement(); 
     } 

     @Override 
     protected <X> void render(Context context, EnergyOfferDTO value, 
       SafeHtmlBuilder sb, HasCell<EnergyOfferDTO, X> hasCell) { 
      final Cell<X> cell = hasCell.getCell(); 
      sb.appendHtmlConstant("<td>"); 
      cell.render(context, hasCell.getValue(value), sb); 
      sb.appendHtmlConstant("</td>"); 
     } 
    }; 
    return compositeCell; 
} 

}

我有能源報價(EnergyOfferDTO)。它有一個MW /價格點列表(OfferPriceMWPairDTO)。我想渲染一個網格,在一天中的幾個小時內,我可以看到10條曲線(曲線是當天MW /價格點的集合)。我希望每個曲線列都包含一對輸入字段(一個用於價格,另一個用於mw值)。我想,嘿,爲每個創建列和單元格,然後將它們放在CompositeCell中。那有多難?

我決定擴展CellTable(即ToggleableGrid),以便封裝鍋爐板設置,樣式和行爲;以及設置顯示模式。當列正在構建時(請參閱isInEditMode)來查看該模式以呈現TextCell或AbstractInputCell的具體衍生物(如TextInputCell)。我還創建了SelectionCell的擴展(即ReferenceDataBackedSelectionCell),以便我可以使用ReferenceData設置選項的值。單輸入列工作!我可以將它們顯示爲文本或輸入欄或選擇列表。這是CompositeCell讓我頭痛。

雖然此代碼將正確呈現輸入字段對,但值都是空白(null),即空白文本或空白輸入字段對。

請在addPriceMwColumn方法上有一個幫助。也許你可以看到我不喜歡的東西?

回答

2

難道這就像在您的列中返回EnergyOfferDTO而不是null一樣簡單嗎? (您可能想要使用IdentityColumn

您在代碼中評論說複合單元將委託給它的單元格,但是列的責任是首先將值賦予複合單元格,那麼複合單元將調用每個HasCell以從傳遞給複合單元的值提取內部單元的值。

作爲一個側面說明,你的組合單元的render方法應在hasCells列表不循環,它應該僅僅是調用super.render(context, value, sb)(當然你appendHtmlConstant電話仍然裝飾它),這將做的工作。

+0

糟糕!在addPriceMwColumn(int,DisplayMode)中,如你所建議的,我選擇構造一個返回energyOffer的IndentityColumn。在generateCompositeCell(List)中,我對渲染邏輯進行了更改。然後我必須更新initializeStructure中的for循環以0開始,即int i = 0;我 2012-02-01 17:26:00

+0

接下來...... a)介紹客戶端驗證和b)數據庫的往返更新。 – 2012-02-01 17:26:22

相關問題