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 (concepts == null) concepts = db_mainConcepts(); if (table != null) ret table; 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(pp, data); dataToTable_uneditable(data, table); pcallF(afterUpdate); }); ret table; } JComponent visualize() { ret makeTable(); } }