// Note: renderUIUrl etc are called in Swing thread srecord noeq UIURLSystem(Enterable owner, SimpleLiveValue uiURL) { // key: ui URL // value: component maker transient Map> uiMap = syncCIMap(); // these are additionally displayed at the top of the list LS preferredURLs = syncList(); settable transient SingleComponentPanel scp; JComboBox comboBox; JComponent urlBar() { ret withLabel("Show", comboBoxAndButton( onSelectedItem( bindComboBoxToLiveValue(centerComboBox( comboBox = autoComboBox(url(), urlsForComboBox())), uiURL), url -> showUIURL(url) ), "Go", url -> showUIURL(url))); } JComponent renderUIUrl aka renderUIURL aka uiGet(S url) { try { temp tempEnter(owner); var maker = uiMap.get(url); var component = callF(maker); if (component != null) ret component; ret jCenteredLabel("URL not found: " + url); } catch print e { ret jErrorView(e); } } void showUIURL(S url) { temp tempEnter(owner); setURL(trim(url)); go(); } void go { setComponent(scp, renderUIUrl(url())); } S url() { ret uiURL!; } void setURL(S url) { uiURL.set(url); } selfType put(S url, IF0 maker) { uiMap.put(url, maker); this; } LS urlsForComboBox() { var sorted = cloneKeys(uiMap); ret concatLists(listSetIntersection(preferredURLs, sorted), sorted); } void addPreferredUIURL(S uiURL) { preferredURLs.add(uiURL); } }