!7 concept AIConcept { S globalID = aGlobalID(); S name; S comment; } static JTable table; p-substance { conceptsAndBot(); table = showConceptsTable("Your A.I. Concepts", AIConcept, func(AIConcept c) { litorderedmap("Concept ID" := c.globalID, "Short Name" := c.name, "Comments" := c.comment) }); addToWindow(table, jRightAlignedLine( jbutton("Add...", f newConcept))); tablePopupMenu(table, voidfunc(JPopupMenu menu, final int row) { addMenuItem(menu, "Edit...", r { final S globalID = (S) getTableCell(table, row, 0); editConcept(findConcept(AIConcept, +globalID)); }); addMenuItem(menu, "Delete", r { final S globalID = (S) getTableCell(table, row, 0); withDBLock(r { deleteConceptsWhere(AIConcept, +globalID) }); }); }); } svoid editConcept(final AIConcept c) { if (c == null) ret; final JTextField a = jTextField(c.name); final JTextField b = jTextField(c.comment); final JTextField cc = jTextField(c.globalID); Runnable r = r { cset(c, name := getTextTrim(a), comment := getTextTrim(b), globalID := getTextTrim(cc)) }; showFormTitled("Edit concept " + c.globalID, "Name", a, "Comment", b, "Global ID", cc, r); } svoid newConcept { final new JTextField a; final JTextField b = jTextField(); final JTextField c = jTextField(aGlobalID()); Runnable r = r { cnew(AIConcept, name := getTextTrim(a), comment := getTextTrim(b), globalID := getTextTrim(c)) }; showFormTitled("New concept", "Name", a, "Comment", b, "Global ID", c, r); }