问题描述
我搜索了GoogleCode,GWT ShowCase,GWT Developer Notes和Google Groups,了解如何获取/设置CompositeCell的值。没有一个明确的例子解释了如何在CellTable中使用它。
让我们盯着一些代码...首先是一个抽象类...
public abstract class ToggleableGrid< T>扩展CellTable< T> {
private static final String DEFAULT_TABLE_WIDTH =100%;
private static final DisplayMode DEFAULT_MODE = DisplayMode.VIEW;
保护无效setDefaults(){
setWidth(DEFAULT_TABLE_WIDTH);
//设置消息在表格为空时显示。
setEmptyTableWidget(new Label(UiMessages.INSTANCE.no_results()));
//添加一个选择模型,以便我们可以选择单元
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);
}
//见http://stackoverflow.com/questions/3772480/remove-all-columns-from-a-celltable
//具体类被强制为维护所有列上的句柄
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;
}
返回结果;
}
protected abstract Set< Column< T,?>> allColumns();
protected abstract TableMetadata constructMetadata();
protected abstract initializeStructure(TableMetadata metadata,ListHandler< T> sortHandler,DisplayMode mode);
protected void setColumnHorizontalAlignment(Column< T,?> column,HorizontalAlignmentConstant alignment){
column.setHorizontalAlignment(alignment);
$ b @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);
}
}
然后一个具体的实现...
$ b $ pre-class =lang -java prettyprint-override> 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(){
返回列;
$ b @Override
protected TableMetadata constructMetadata(){
final TableMetadata metadata = new TableMetadata();
// TODO考虑一个预定义的ReferenceData集合,它将存放在一个通用包中
//使用斜率
metadata.addColumnMetadata(UiMessages.INSTANCE.use_slope( ),new String [] {UiMessages.INSTANCE.yes(),UiMessages.INSTANCE.no()},new String [] {true,false});
返回元数据;
$ b @Override
protected void initializeStructure(TableMetadata metadata,ListHandler< EnergyOfferDTO> sortHandler,DisplayMode currentDisplayMode){
addHourColumn(sortHandler);
addUseSlopeColumn(metadata,sortHandler,currentDisplayMode);
for(int i = 1; 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();如果(isoDateTime!= null&&!isoDateTime.isEmpty()){
final date dateTime = TimeUtil.isoToDate(isoDateTime);
if(dateTime!= null){
result = TimeUtil.dateToHour(dateTime);
}
}
返回结果;
}
};
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);
$ b protected void addUseSlopeColumn(TableMetadata metadata,ListHandler< EnergyOfferDTO> sortHandler,DisplayMode currentDisplayMode){
final ReferenceData refData = metadata.allColumnMetadata()。get UiMessages.INSTANCE.use_slope());
Column< EnergyOfferDTO,String> useSlopeColumn;
单元格< String>细胞;
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){
//构造一个包含一对文本输入的能量优化复合单元
final List< HasCell< EnergyOfferDTO,>>> hasCells = new ArrayList<
HasCell< EnergyOfferDTO,?>>();
//这个DTO被传递,以便新条目的价格和mw值保持在一起
final OfferPriceMwPairDTO newOfferPriceMwPairDTO = new OfferPriceMwPairDTO();
//价格
最终HasCell< EnergyOfferDTO,字符串> priceCell = generatePriceCell(colIndex,newOfferPriceMwPairDTO,currentDisplayMode);
hasCells.add(priceCell);
// MW
最终HasCell< EnergyOfferDTO,字符串> mwCell = generateMwCell(colIndex,newOfferPriceMwPairDTO,currentDisplayMode);
hasCells.add(mwCell);
//复合
最终CompositeCell< EnergyOfferDTO> priceMwCell = generateCompositeCell(hasCells);
最后一栏< EnergyOfferDTO,EnergyOfferDTO> priceMwColumn = new Column< EnergyOfferDTO,EnergyOfferDTO>(priceMwCell){
@Override
public EnergyOfferDTO getValue(EnergyOfferDTO energyOffer){
//我们这样做是为了满足匿名类型的合约,
//但知道该列的复合单元委托给它的单个单元格impls以获得值
返回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>(){
$ b $ private TextInputCell cell = new TextInputCell();
@Override
public Cell< String> getCell(){
return cell;
}
@Override
public FieldUpdater< EnergyOfferDTO,String> getFieldUpdater(){
返回新的FieldUpdater< EnergyOfferDTO,String>(){
@Override
public void update(int index,EnergyOfferDTO energyOffer,String value){
if != null&&!value.isEmpty()){
//数字格式异常应该被事件总线的句柄方法捕获和处理
final double valueAsDouble = NumberFormat.getDecimalFormat()。parse(值);
final BigDecimal price = BigDecimal.valueOf(valueAsDouble);
final List< OfferPriceMwPairDTO> offerPriceCurve = energyOffer.getOfferPriceCurve();
final OfferPriceMwPairDTO offerPriceMwPairDTO = offerPriceCurve.get(colIndex);
if(offerPriceMwPairDTO == null){//我们有一个新的价格值
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());
}
}
返回结果;
}
};
} 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 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>(){
$ b $ private TextInputCell cell = new TextInputCell();
@Override
public Cell< String> getCell(){
return cell;
}
@Override
public FieldUpdater< EnergyOfferDTO,String> getFieldUpdater(){
返回新的FieldUpdater< EnergyOfferDTO,String>(){
@Override
public void update(int index,EnergyOfferDTO energyOffer,String value){
if != null&&!value.isEmpty()){
//数字格式异常应该被事件总线的句柄方法捕获和处理
final double valueAsDouble = NumberFormat.getDecimalFormat()。parse(值);
final BigDecimal mw = BigDecimal.valueOf(valueAsDouble);
final List< OfferPriceMwPairDTO> offerPriceCurve = energyOffer.getOfferPriceCurve();
final OfferPriceMwPairDTO offerPriceMwPairDTO = offerPriceCurve.get(colIndex);
if(offerPriceMwPairDTO == null){//我们有一个新的mw值
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());
}
}
返回结果;
}
};
} 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());
}
}
返回结果;
}
};
}
返回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(<表>< TBODY>< TR>中); (final HasCell< EnergyOfferDTO,?> hasCell:hasCells){
render(context,value,sb,hasCell);
。
}
sb.appendHtmlConstant(< / tr>< / tbody>< / table>);
}
@Override
protected Element getContainerElement(Element parent){
//返回表中的第一个TR元素。
返回parent.getFirstChildElement()。getFirstChildElement()。getFirstChildElement();
}
@覆盖
保护< 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导致我头痛的问题。
虽然此代码将正确呈现输入字段对,但值都是空白(空白),无论是空白文本还是空白输入字段对。
请在addPriceMwColumn方法中使用gander。也许你可以看到我不知道的东西?
它可以像返回 EnergyOfferDTO
而不是 null
? (您可能想要使用 IdentityColumn
)
您在代码中评论说复合单元会委托给它的单元格,但是列的职责是首先将值赋予复合单元,然后复合单元将调用每个 HasCell
来提取内部单元格的值来自传递给复合单元格的值。
请注意,复合单元格的 render
方法应该'循环遍历 hasCells
列表,它应该简单地调用 super.render(context,value,sb)
当然还是用你的 appendHtmlConstant
调用装饰它),它将完成这项工作。
I have scoured GoogleCode, GWT ShowCase, GWT Developer Notes, and Google Groups for some inkling as to how to get/set values of a CompositeCell. There is no one definitive example that explains how to use it within a CellTable.
Let's stare at some code... first an abstract class...
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);
}
}
And then a concrete implementation...
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;
}
}
I have an energy offer (EnergyOfferDTO). It has a list of MW/Price points (OfferPriceMWPairDTO). I want to render a grid where for hours of a day I can see up to 10 curves (curves being the collection of MW/Price points for the day). I want each of these curve columns to contain a pair of input fields (one for price and one for mw value). I figure, hey, create columns and cells for each, then bring them together in a CompositeCell. How hard could that be?
I decided to extend CellTable (i.e., ToggleableGrid) so that I could encapsulate boiler-plate setup, style and behavior; as well to set a display mode. The mode is consulted as columns are being built (see isInEditMode) to render either a TextCell or a concrete derivative of AbstractInputCell, like TextInputCell. I also created an extension for SelectionCell (i.e., ReferenceDataBackedSelectionCell) so that I could set the value of an option using ReferenceData. Single input columns work! I can display them as text or as input field or select list. It's the CompositeCell that's causing me headaches.
While this code will render pairs of input fields correctly, values are all blank (null), either blank text or blank input field pairs.
Please have a gander at the addPriceMwColumn method. Maybe you can see something I don't?
Could it be as simple as returning the EnergyOfferDTO
in your column instead of null
? (you might want to use an IdentityColumn
)
You say in a comment in your code that the composite cell will delegate to its cells, but it's the responsibility of the column to give the value to the composite cell in the first place, then the composite cell will call each HasCell
to extract the inner cell's value from the value passed to the composite cell.
As a side note, your composite cell's render
method shouldn't loop over the hasCells
list, it should simply call super.render(context, value, sb)
(of course still decorating it with your appendHtmlConstant
calls) which will do the job.
这篇关于为什么没有在CellTable中使用CompositeCell的体面示例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!