代号一个表绑定到属性对象列表以显示和修改数据库表

时间:2018-08-09 23:06:19

标签: codenameone

这个问题是特定于Codename One的,它与我的以下代码是否是好的代码或是否有更好的策略有关。

这是我的用例:

  • 通过REST请求,我得到了一个数据库表,作为由JSON序列化的DAO列表(每个DAO是行);
  • 客户端具有ServerAPI类,该类的方法返回服务器响应为List<SportTypeDAO>;
  • 每个SportTypeDAO被实现为PropertyBusinessObject
  • 我想显示一个Form对象和一个Table对象,该对象允许用户查看所有表并修改某些字段(并添加行,但是我尚未实现) ;
  • Table将被序列化为JSON,以将修改后的表发送到服务器。

问题:

  • 可以轻松地将Property绑定到TextFieldInputComponent,但是我不知道任何将PropertyBusinessObject绑定到行的默认简便方法Table ...甚至将List<PropertyBusinessObject>绑定到Table
  • Table内部使用createCell方法,该方法使用传递给TableModel的数据将每个单元格创建为LabelTextField(根据单元格是否可编辑这一事实),因此我无法直接在绑定到TextFields的表Properties中插入。

我试图通过以下方式解决问题...但是有很多代码可以完成简单的概念性任务(将List<PropertyBusinessObject>绑定到Table ...还有更好的方法吗?我必须对许多表执行相同的任务,并且我担心要找到一个可以广泛推广的好的解决方案。

public class FormSportType extends BaseForm {

    private static List<SportTypeDAO> listToShow = null;

    public FormSportType() {
        super("FormSportType", BoxLayout.y());
        fillForm();
    }

    public FormSportType(Form backForm) {
        super("FormSportType", BoxLayout.y());
        addBackCommand(backForm);
        fillForm();
    }

    private void fillForm() {

        add(new Label("FormSportType"));
        UiBinding uib = new UiBinding();

        if (listToShow == null) {
            listToShow = serverAPI.readSportType();
        }

        int rows = listToShow.size();
        int colums = 5;
        Object[][] dataArray = new Object[rows][colums];
        for (int row = 0; row < rows; row++) {
            for (int column = 0; column < colums; column++) {
                String cell = "";
                switch (column) {
                    case 0:
                        cell = listToShow.get(row).keyword.get();
                        break;
                    case 1:
                        cell = listToShow.get(row).text_IT.get();
                        break;
                    case 2:
                        cell = listToShow.get(row).text_EN.get();
                        break;
                    case 3:
                        cell = listToShow.get(row).position.get().toString();
                        break;
                    case 4:
                        cell = listToShow.get(row).dbAction.get().toString();
                        break;
                }

                dataArray[row][column] = cell;
            }
        }

        TableModel model = new DefaultTableModel(new String[]{"Keyword", "Text_IT", "Text_EN", "Position", "DbAction"}, dataArray) {

            @Override
            public boolean isCellEditable(int row, int col) {
                return (row > -1 && col != 0 && col != 4);
            }

            @Override
            public void setValueAt(int row, int column, Object o) {
                if (DEBUG) {
                    Log.p("Executing setValueAt \"" + o + "\" at row " + row + ", column " + column);
                }
                super.setValueAt(row, column, o);
                try {
                    String value;
                    if (o instanceof String) {
                        value = (String) o;
                    } else if (o instanceof Integer) {
                        Integer num = (Integer) o;
                        value = num.toString();
                    } else {
                        if (DEBUG) {
                            Log.p("ERROR in setValueAt row " + row + ", column " + column + " because wrong object class");
                        }
                        throw new IllegalArgumentException("Object o is not a String or an Integer");
                    }
                    switch (column) {
                        case 0:
                            listToShow.get(row).keyword.set(value);
                            break;
                        case 1:
                            listToShow.get(row).text_IT.set(value);
                            break;
                        case 2:
                            listToShow.get(row).text_EN.set(value);
                            break;
                        case 3:
                            listToShow.get(row).position.set(Integer.valueOf(value));
                            break;
                        case 4:
                            listToShow.get(row).dbAction.set(Integer.valueOf(value));
                            break;
                        default:
                            if (DEBUG) {
                                Log.p("ERROR in setValueAt row " + row + ", column " + column + ", because wrong column number");
                            }
                    }
                } catch (Exception ex) {
                    if (DEBUG) {
                        Log.p("ERROR in setValueAt row " + row + ", column " + column);
                        Log.e(ex);
                    }
                }
                if (DEBUG) {
                    List<Map<String, Object>> listMaps = new LinkedList<>();
                    for (SportTypeDAO dao : listToShow) {
                        listMaps.add(dao.getPropertyIndex().toMapRepresentation());
                    }
                    Map<String, List<Map<String, Object>>> toConvert = new HashMap<>();
                    toConvert.put("root", listMaps);
                    Log.p("--- New JSON content:\n" + JSONParser.mapToJson(toConvert));
                }
            }

            @Override
            public Object getValueAt(int row, int column) {
                // if(DEBUG) Log.p("Executing getValueAt row " + row + ", column " + column);
                try {
                    switch (column) {
                        case 0:
                            return listToShow.get(row).keyword.get();
                        case 1:
                            return listToShow.get(row).text_IT.get();
                        case 2:
                            return listToShow.get(row).text_EN.get();
                        case 3:
                            return listToShow.get(row).position.get();
                        case 4:
                            return listToShow.get(row).dbAction.get();
                        default:
                            if (DEBUG) {
                                Log.p("ERROR: cannot get value at row " + row + ", column: " + column);
                            }
                            return "";
                    }
                } catch (Exception err) {
                    if (DEBUG) {
                        Log.p("ERROR: cannot get value at row " + row + ", column: " + column);
                        Log.e(err);
                    }
                    return "";
                }
            }

        };

        Table table = new Table(model) {
            @Override
            protected Component createCell(Object value, int row, int column, boolean editable) {
                Component cell = super.createCell(value, row, column, editable);
                if (row > -1) {
                    cell.setUIID("TableCell");
                }
                if (row > -1 && row % 2 == 0) {
                    // pinstripe effect 
                    cell.getAllStyles().setBgColor(0xeeeeee);
                    cell.getAllStyles().setBgTransparency(255);
                }

                return cell;
            }

            @Override
            protected TableLayout.Constraint createCellConstraint(Object value, int row, int column) {
                TableLayout.Constraint con = super.createCellConstraint(value, row, column);
                con.setWidthPercentage(100 / model.getColumnCount());
                return con;
            }

        };

        table.setSortSupported(true);

        try {
            table.sort(3, false); // order by position
            if (DEBUG) {
                Log.p("table.sort executed successfully");
            }
        } catch (Exception ex) {
            if (DEBUG) {
                Log.p("ERROR: cannot order table, maybe there are null values");
                Log.e(ex);
            }
        }

        add(table);

    }
}

1 个答案:

答案 0 :(得分:1)

现在,我们没有可用于表绑定的属性列表。我对此尝试了一下,我认为这很容易。我将其添加到下一个更新中,但是您应该已经可以使用它:

/**
 * Implements table model binding, this is implemented as a class to allow
 * additional features such as adding/removing rows
 */
public class BoundTableModel implements TableModel {
    private List<PropertyBusinessObject> objects;
    private PropertyBusinessObject prototype;
    private Set<String> exclude = new HashSet<String>();
    private PropertyBase[] columnOrder;
    private Set<String> uneditable = new HashSet<String>();
    private EventDispatcher listeners = new EventDispatcher();

    /**
     * Creates a table model with the business objects
     * @param objects the objects of the model
     * @param prototype the type by which we determine the structure of the table
     */
    public BoundTableModel(List<PropertyBusinessObject> objects, 
        PropertyBusinessObject prototype) {
        this.objects = objects;
    }

    /**
     * The properties that are ignored
     * @param b the property to ignore
     */
    public void excludeProperty(PropertyBase b) {
        exclude.add(b.getName());
    }

    /**
     * Sets the order of the columns explicitly
     * @param columnOrder the order of the columns based on the prototype
     */
    public void setColumnOrder(PropertyBase... columnOrder) {
        this.columnOrder = columnOrder;
    }

    /**
     * Makes the property editable or uneditable
     * @param pb the property base
     * @param editable true for editable (the default)
     */
    public void setEditable(PropertyBase pb, boolean editable) {
        if(editable) {
            uneditable.remove(pb.getName());
        } else {
            uneditable.add(pb.getName());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int getRowCount() {
        return objects.size();
    }

    /**
     * Adds a new business object to the table
     * @param index the index of the addition
     * @param b the business object
     */
    public void addRow(int index, PropertyBusinessObject b) {
        objects.add(index, b);
        for(int col = 0 ; col < getColumnCount() ; col++) {
            listeners.fireDataChangeEvent(col, index);
        }
    }

    /**
     * Removes the row at the given index
     * @param index the position in the table
     */
    public void removeRow(int index) {
        objects.remove(index);
       listeners.fireDataChangeEvent(Integer.MIN_VALUE, Integer.MIN_VALUE);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int getColumnCount() {
        if(columnOrder != null) {
            return columnOrder.length;
        }
        return prototype.getPropertyIndex().getSize() - exclude.size();
    }

    @Override
    public String getColumnName(int i) {
        if(columnOrder != null) {
            return columnOrder[i].getLabel();
        }
        return prototype.getPropertyIndex().get(i).getName();
    }

    @Override
    public boolean isCellEditable(int row, int column) {
        return !uneditable.contains(prototype.getPropertyIndex().get(column).getName());
    }

    @Override
    public Object getValueAt(int row, int column) {
        PropertyBusinessObject pb = objects.get(row);
        String n;
        if(columnOrder != null) {
            n = columnOrder[column].getName();
        } else {
            n = pb.getPropertyIndex().get(column).getName();
        }
        return pb.getPropertyIndex().get(n).get();
    }

    @Override
    public void setValueAt(int row, int column, Object o) {
        PropertyBusinessObject pb = objects.get(row);
        String n;
        if(columnOrder != null) {
            n = columnOrder[column].getName();
        } else {
            n = pb.getPropertyIndex().get(column).getName();
        }
        pb.getPropertyIndex().get(n).setImpl(o);
        listeners.fireDataChangeEvent(column, row);
    }

    @Override
    public void addDataChangeListener(DataChangedListener d) {
        listeners.addListener(d);
    }

    @Override
    public void removeDataChangeListener(DataChangedListener d) {
        listeners.removeListener(d);
    }
}