sclass JConceptsTable { Class c; Concepts concepts; JTable table; // options L dropFields; IF1 postProcess; Runnable afterUpdate; bool latestFirst; IF1> sorter; int idWidth = 50; int updateInterval = 1000; *(Class *c) { showAsFrame(); } S defaultTitle() { ret plural(shortClassName(c)); } void showAsFrame(S title default defaultTitle()) { makeTable(); showFrame(title, table); } void makeTable { if (table != null) ret; if (concepts == null) concepts = db_mainConcepts(); table = sexyTable(); awtOnConceptChanges(table, updateInterval, r { new L data; Cl l = list(concepts, cClass); l = postProcess(sorter, l); for (A c : l) addIfNotNull(data, pcallF(renderer, c)); if (latestFirst) reverseInPlace(data); data = (L) postProcess(postProcess, data); dataToTable_uneditable(data, table); pcallF(afterUpdate); }); } JComponent visualize() { makeTable(); ret table; } }