!7 concept AIConcept { S globalID = aGlobalID(); S name; S comment; new Ref pngFile; } 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, "Has Image" := yn(c.pngFile.has())) }); 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) }); }); }); hideConsole(); } 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); final ImageChooser ic = new ImageChooser(c.pngFile.has() ? c.pngFile->getImage() : null); Runnable r = r { BufferedImage image = ic.getImage(); if (image == null && c.pngFile.has()) { //c.pngFile->delete(); c.pngFile.clear(); } else if (image != null && (!c.pngFile.has() || imagesIdentical(c.pngFile->getImage(), image))) { //if (c.pngFile.has()) c.pngFile->delete(); c.pngFile.set(new PNGFile(image)); } cset(c, name := getTextTrim(a), comment := getTextTrim(b), globalID := getTextTrim(cc)); }; O[] params = { "Description/Name", a, "Comment (optional)", b, "Global ID", cc, "Example Image (optional)", ic, r }; //for i over params: print("#" + i + ": " + params[i]); showFormTitled("Edit concept " + c.globalID, params); } svoid newConcept { final new JTextField a; final JTextField b = jTextField(); final JTextField cc = jTextField(aGlobalID()); final new ImageChooser ic; Runnable r = r { cnew(AIConcept, name := getTextTrim(a), comment := getTextTrim(b), globalID := getTextTrim(cc), pngFile := ic.createPNGFile()) }; showFormTitled("New concept", "Description/Name", a, "Comment (optional)", b, "Global ID", cc, "Example Image (optional)", ic, r); }