2

我需要创建一个具有以下特征的表:

  • 13 列:第一列包含不可编辑的文本,其他列包含可编辑或不可编辑的数值,具体取决于行索引
  • 3 行:第 1 行包含 int,第 2 行包含双格式为 #,##0.00,第 3 行包含双格式为 #,#0.0%

该表还必须具有可编辑单元格的以下数据验证选项:

  • boolean positive:如果允许正数,则为 true
  • 布尔负数:如果允许负数则为真
  • boolean maxEnabled:如果单元格的值必须小于 maxValue,则为 true
  • double maxValue:最大允许值(如果 maxEnabled==true;)

我设法让桌子按照我的意愿行事,我唯一没能开始工作的是:

  • 输入成功后,使用我的数字格式格式化新值
  • 当用户点击重绘按钮时,获取要重绘的表格

对此的任何帮助将不胜感激。

这是我正在使用的代码:

单元格、列和 FieldUpdater

public class DataCell2 extends EditTextCell{
private TableDTO tableData;

public DataCell2(TableDTO tableData){
    this.tableData=tableData;
}

@Override
public void render(com.google.gwt.cell.client.Cell.Context context, String value, SafeHtmlBuilder sb){
    super.render(context,value,sb);

}

@Override
public void onBrowserEvent(Context context, Element parent, String value, NativeEvent event,
        ValueUpdater<String> valueUpdater){

    // If cell non editable exit
    if(!isEditable(context)){
        return;
    }else{
        super.onBrowserEvent(context,parent,value,event,valueUpdater);

    }

}

private boolean isEditable(Context context){
    int row=context.getIndex();
    // int column=context.getColumn();
    return tableData.isRowEditable(row);
}




public class DataColumn2<DataCell2> extends Column<RowDTO,String>{
public int col;

public DataColumn2(int col, Cell<String> cell){
    super(cell);
    this.col=col;
}

@Override
public String getValue(RowDTO object){
    // TODO Auto-generated method stub
    return null;
}




public class LabelColumn2 extends TextColumn<RowDTO>{
public LabelColumn2(){
    super();
}

@Override
public String getValue(RowDTO object){
    return object.getLabel();
}





public class DataUpdater2 implements FieldUpdater<RowDTO,String>{

private CellTable<RowDTO> table;
private DataCell2 dataCell;
// private ProvidesKey<DataItem> KEY_PROVIDER;
protected int col=0;

public DataUpdater2(int col, CellTable<RowDTO> table, DataCell2 dataCell){
    this.dataCell=dataCell;
    this.table=table;
    this.col=col;
}

public void clear(int index){
    // Clear invalid input
    dataCell.clearViewData(index);
    // Redraw the table.
    table.redraw();
}

@Override
public void update(int index, RowDTO object, String value){
    // TODO Auto-generated method stub

}

包含标签的行类和行数据及其数据验证类

public class RowDTO{
private final int index;
private Vector<Object> rowData;
private RowValidation validation;
private boolean editable;

public RowDTO(int index, Vector<Object> rowData, int type){
    this.index=index;
    this.rowData=rowData;
    this.validation=buildValidation(index,type);
}

public int getIndex(){
    return index;
}

public Vector<Object> getRowData(){
    return rowData;
}

public RowValidation getValidation(){
    return validation;
}

public String getRowData(int column){
    return rowData.get(column).toString();
}

public String getLabel(){
    return rowData.get(0).toString();
}

public void setRowData(int column, String newVal){
    this.rowData.set(column,newVal);
}

/** Assign a vaildation and editing strategy based on the table type and the row */
private RowValidation buildValidation(int index, int type){
    switch(type){
        case TableDTO.FIXEDCOST:
            switch(index){
                case 0:
                    editable=true;
                    return RowValidation.getPositiveDouble();
                case 1:
                    editable=true;
                    return RowValidation.getPositiveInt();
                case 2:
                    editable=true;
                    return RowValidation.getPositivePercent();
                default:
                    editable=true;
                    return RowValidation.getPositiveDouble();
            }
        default:
            editable=true;
            return RowValidation.getPositiveDouble();
    }
}

public boolean isEditable(){
    return editable;
}




public class RowValidation{

/* Is double (else is int) */
private boolean digit=true;
/* Values permitted */
private boolean positive=true;
private boolean negative=true;
private boolean zero=true;
private boolean maxEnabled=false;
private double maxValue=2;

/** Default constructor: double number, can be positive, negative or zero, no maximum */
public RowValidation(){}

/**
 * @param digit: true if double, false if int
 * @param positive: true if can be positive
 * @param negative: true if can be negative
 * @param zero: true if can be zero
 * @param maxEnabled: true if can has maximum
 * @param maxValue: maximum value if has maximum
 */
public RowValidation(boolean digit, boolean positive, boolean negative, boolean zero, boolean maxEnabled,
        double maxValue){
    this.digit=digit;
    this.positive=positive;
    this.negative=negative;
    this.zero=zero;
    this.maxEnabled=maxEnabled;
    this.maxValue=maxValue;
}

public boolean isDigit(){
    return digit;
}

public boolean isPositive(){
    return positive;
}

public boolean isNegative(){
    return negative;
}

public boolean isZero(){
    return zero;
}

public boolean isMaxEnabled(){
    return maxEnabled;
}

public double getMaxValue(){
    return maxValue;
}

/** Positive or zero Integer */
public static RowValidation getPositiveInt(){
    return new RowValidation(false,true,false,true,false,2);
}

/** Positive or zero double */
public static RowValidation getPositiveDouble(){
    return new RowValidation(true,true,false,true,false,2);
}

/** Positive double belonging to [0,1] */
public static RowValidation getPositivePercent(){
    return new RowValidation(true,true,false,true,true,1);
}

包含行列表的 Table 类:

public class TableDTO{
public static final int FIXEDCOST=0;
private ArrayList<RowDTO> rows;
private Vector<String> headers;

public TableDTO(Vector<Vector<Object>> roughData, Vector<String> headers, int type){
    this.headers=headers;
    rows=buildRows(roughData,type);
}

private ArrayList<RowDTO> buildRows(Vector<Vector<Object>> roughData, int type){
    int nb=roughData.size();
    ArrayList<RowDTO> result=new ArrayList<RowDTO>(nb);
    for(int i=0;i<nb;i++){
        result.add(new RowDTO(i,roughData.get(i),type));
    }

    return result;
}

public ArrayList<RowDTO> getRows(){
    return rows;
}

public RowDTO getRow(int index){
    return rows.get(index);
}

public boolean isRowEditable(int index){
    return getRow(index).isEditable();
}

public String getHeader(int column){
    return headers.get(column);
}

将所有东西结合在一起的面板

public class TablePanel extends Composite{
private VerticalPanel main=new VerticalPanel();
private HorizontalPanel btns=new HorizontalPanel();
private Button commitButton=new Button("commit");
private Button redrawButton=new Button("redraw");
private List<DataChange> pendingChanges=new ArrayList<DataChange>();
private CellTable<RowDTO> table;
private TableDTO dataDTO;
/**
 * The key provider that allows us to identify data points even if a field changes.
 */
private static final ProvidesKey<RowDTO> KEY_PROVIDER=new ProvidesKey<RowDTO>(){
    @Override
    public Object getKey(RowDTO item){
        return item.getIndex();
    }
};

@SuppressWarnings({"unchecked"})
public TablePanel(Vector<Vector<Object>> roughData, Vector<String> headers, int type){
    dataDTO=new TableDTO(roughData,headers,type);

    // Create a CellTable with a key provider.
    table=new CellTable<RowDTO>(KEY_PROVIDER);
    table.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);

    // Label
    LabelColumn2 nameColumn=new LabelColumn2();
    table.addColumn(nameColumn,"Label");

    redrawButton.addClickHandler(new ClickHandler(){
        @Override
        public void onClick(ClickEvent event){
            // Delete temporary changes
            pendingChanges.clear();
            // Redraw table
            table.setRowData(0,dataDTO.getRows());
            table.redraw();
        }
    });
    commitButton.addClickHandler(new ClickHandler(){
        @Override
        public void onClick(ClickEvent event){
            // Commit the changes.
            for(DataChange pendingChange: pendingChanges){
                pendingChange.doCommit();
            }
            pendingChanges.clear();

            // Push the changes to the views.
            table.setRowData(0,dataDTO.getRows());

            table.redraw();
        }
    });

    // myData.getCol();
    for(int i=1;i<5;i++){
        // Create cell
        DataCell2 dataCell=new DataCell2(dataDTO);
        // Add a column for every data points.

        @SuppressWarnings({"rawtypes"})
        DataColumn2<DataCell2> dataColumn=new DataColumn2(i,dataCell){
            @Override
            public String getValue(RowDTO object){
                String newVal=object.getRowData(col);
                return format(object,newVal);
            }
        };

        // Add a field updater to be notified when the user enters a new value.
        dataColumn.setFieldUpdater(new DataUpdater2(i,table,dataCell){

            @Override
            public void update(int index, RowDTO object, String value){
                // Called when the user changes the value.
                if(isValidValue(index,value)){
                    pendingChanges.add(new DataChange(this.col,object,value));

                    // TODO kill once ok
                    int s=pendingChanges.size();
                    String ss=object.getRowData(col);
                    Window.alert("Value in myData="+ss+", nb pending changes="+s);
                }else{
                    /* clear the view data and redraw the table */
                    this.clear(index);
                    // Alert user: TODO restablish once ok
                    // Window.alert("Invalid input");

                    // TODO kill once ok
                    int s=pendingChanges.size();
                    String ss=object.getRowData(col);
                    Window.alert("Value in myData="+ss+", nb pending changes="+s);
                }
            }
        });
        table.addColumn(dataColumn,dataDTO.getHeader(i));

    }

    // Set the total row count. This isn't strictly necessary, but it affects
    // paging calculations, so its good habit to keep the row count up to date.
    table.setRowCount(dataDTO.getRows().size(),true);

    // Push the data into the widget.
    table.setRowData(0,dataDTO.getRows());

    // Add it to the root panel.
    main.add(table);
    btns.add(commitButton);
    btns.add(redrawButton);
    main.add(btns);
    initWidget(main);
}

/* Formatting */

private String format(RowDTO row, String value){
    RowValidation rv=row.getValidation();
    if(rv.isDigit()){
        if(rv.isMaxEnabled()){
            return formatAsPercent(value);

        }else{
            return formatAsDouble(value);
        }
    }else{
        return formatAsInt(value);
    }
}

private static String formatAsDouble(String val){
    try{
        double value=Double.parseDouble(val);
        NumberFormat fmt=NumberFormat.getDecimalFormat();
        fmt.overrideFractionDigits(2,2);
        String formatted=fmt.format(value);
        return formatted;
    }catch(NumberFormatException e){
        // TODO
        return val;
    }
}

private static String formatAsInt(String val){
    try{
        double value=Double.parseDouble(val);
        NumberFormat fmt=NumberFormat.getDecimalFormat();
        fmt.overrideFractionDigits(0,0);
        String formatted=fmt.format(value);
        return formatted;
    }catch(NumberFormatException e){
        // TODO
        return val;
    }
}

private static String formatAsPercent(String val){
    try{
        double value=Double.parseDouble(val);
        NumberFormat fmt=NumberFormat.getPercentFormat();
        fmt.overrideFractionDigits(2,2);
        String formatted=fmt.format(value);
        return formatted;
    }catch(NumberFormatException e){
        // TODO
        return val;
    }
}

private boolean isValidValue(int index, String data){
    /* if data formatted as pct, convert into double */
    if(data.endsWith("%")){
        data=data.substring(0,data.length()-2);
        try{
            double v=Double.parseDouble(data);
            v=v/100;
            data=Double.toString(v);
        }catch(NumberFormatException e){
            return false;
        }
    }
    RowDTO row=dataDTO.getRow(index);
    RowValidation validation=row.getValidation();
    if(validation.isDigit()){
        double val;
        try{
            val=Double.parseDouble(data);
        }catch(Exception e){
            return false;
        }

        if(val>0&&!validation.isPositive()){ return false; }
        if(val<0&&!validation.isNegative()){ return false; }
        if(val==0&&!validation.isZero()){ return false; }
        if(validation.isMaxEnabled()&&val>validation.getMaxValue()){ return false; }
    }else{
        int val;
        try{
            val=Integer.parseInt(data);
        }catch(Exception e){
            return false;
        }

        if(val>0&&!validation.isPositive()){ return false; }
        if(val<0&&!validation.isNegative()){ return false; }
        if(val==0&&!validation.isZero()){ return false; }
        if(validation.isMaxEnabled()&&val>validation.getMaxValue()){ return false; }
    }

    return true;
}

private class DataChange{
    private final RowDTO object;
    private final String value;
    private final int col;

    public DataChange(int col, RowDTO object, String value){
        this.object=object;
        this.value=value;
        this.col=col;
    }

    public void doCommit(){
        object.setRowData(col,value);
    }
}

以及入口点方法:

public class Mpp implements EntryPoint{

/** Entry point method. */

@Override
public void onModuleLoad(){
    int a=3;
    int b=13;

    Vector<Vector<Object>> roughData=new Vector<Vector<Object>>(a);
    Vector<String> headers=new Vector<String>(b);
    Vector<Object> r0=new Vector<Object>(b);
    Vector<Object> r1=new Vector<Object>(b);
    Vector<Object> r2=new Vector<Object>(b);

    r0.add("Amount (double)");
    r1.add("Credit (int)");
    r2.add("Advance (%)");
    headers.add("Col ");

    for(int i=1;i<b;i++){
        headers.add("Col "+(i));
        r0.add(i*1.2);
        r1.add(i);
        r2.add(i/100);
    }
    roughData.add(r0);
    roughData.add(r1);
    roughData.add(r2);

    TablePanel panel=new TablePanel(roughData,headers,TableDTO.FIXEDCOST);
    RootPanel.get().add(panel);

}
4

1 回答 1

0

据我所知,您的任务不是显示来自数据库之类的数据,您只是想要一个漂亮的 13 x 3 表中的数据,对吧?在这种情况下,我建议根本不要使用CellTable,而只是制作一堆小部件,然后你可以使用,比如FlexTable;这应该更容易控制。

于 2013-06-30T21:05:41.313 回答