这个问题是特定于Codename One的,它与我的以下代码是否是好的代码或是否有更好的策略有关。
这是我的用例:
List<SportTypeDAO>
; SportTypeDAO
被实现为PropertyBusinessObject
; Form
对象和一个Table
对象,该对象允许用户查看所有表并修改某些字段(并添加行,但是我尚未实现) ; Table
将被序列化为JSON,以将修改后的表发送到服务器。问题:
Property
绑定到TextField
或InputComponent
,但是我不知道任何将PropertyBusinessObject
绑定到行的默认简便方法Table
...甚至将List<PropertyBusinessObject>
绑定到Table
; Table
内部使用createCell
方法,该方法使用传递给TableModel
的数据将每个单元格创建为Label
或TextField
(根据单元格是否可编辑这一事实),因此我无法直接在绑定到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);
}
}
答案 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);
}
}