sclass SimpleCRUD { Class cc; JTable table; JPanel buttons, panel; *(Class *cc) {} SimpleCRUD show() { make(); showFrame(plural(shortClassName(cc)), panel); this; } JPanel make() { db(); swing { table = makeConceptsTable(cc); panel = centerAndSouth(table, buttons = jRightAlignedLine( jbutton("Add...", r { newConcept() }), tableDependButton(table, jbutton("Edit", r { editConcept(selectedConcept()) })), tableDependButton(table, jbutton("Delete", r { final A c = selectedConcept(); withDBLock(r { c.delete() }); })))); tablePopupMenuItem(table, "Edit...", voidfunc(int row) { editConcept((A) getConcept(toLong(getTableCell(table, row, 0)))) }); } ret panel; } void newConcept { final Map map = makeComponents(null); Runnable r = r { saveData(cnew(cc), map) }; showFormTitled("New " + shortClassName(cc), arrayPlus(mapToObjectArray(map), r)); } void editConcept(final A c) { if (c == null) ret; final Map map = makeComponents(c); Runnable r = r { saveData(c, map) }; showFormTitled("Edit " + shortClassName(cc) + " #" + c.id, arrayPlus(mapToObjectArray(map), r)); } A selectedConcept() { ret (A) getConcept(toLong(selectedTableCell(table, 0))); } Map makeComponents(A c) { Map map = litorderedmap(); makeComponents(c, map); ret map; } JComponent fieldComponent(A c, S field) { Class type = getFieldType(cc, field); O value = getOpt(c, field); //print("Field type: " + field + " => " + type); if (type == bool.class) ret jCheckBox(isTrue(value)); else ret jTextField(structureOrText_crud(value)); } void saveComponent(A c, S field, JComponent comp) { if (comp instanceof JTextField) cset(c, field, convertToField(getTextTrim((JTextField) comp), cc, field)); else if (comp instanceof JCheckBox) cset(c, field, isChecked((JCheckBox) comp)); ifclass ImageChooser else if (comp instanceof ImageChooser) cUpdatePNGFile(c, field, comp/ImageChooser.getImage()); endif } // override the following two methods to customize edit window void makeComponents(A c, Map map) { for (S field : conceptFieldsInOrder(cc)) map.put(field, fieldComponent(c, field)); } void saveData(A c, Map components) { for (S field : keys(components)) saveComponent(c, field, components.get(field)); } }