sclass ButtonImageLoader { DynamicStack stack; Set loadedButtons = weakIdentityHashSet(); DeQ loadQ; JScrollPane scrollPane; ChangeListener changeListener; *(final DynamicStack *stack) { bindToComponent(stack, r { scrollPane = enclosingScrollPane(stack); changeListener = scrollPaneOnScroll(scrollPane, r { update() }); update(); }, r { if (scrollPane != null) { scrollPane.getViewport().removeChangeListener(changeListener); scrollPane = null; changeListener = null; } }); } void update() swing { new L l; for (final JButton b : (L) (L) stackElementsShowing(buttons)) { //if (add(loadedButtons, b)) pcall { // will strangely not work if (add_byContains(loadedButtons, b)) pcall { TextImageAction tia = makeNiceButtons_map.get(b); if (tia == null) continue with print("no tia"); final File f = filesForNiceButtons_map.get(tia); if (f == null) continue with print("no file"); l.add(r { setButtonImage(b, loadPreviewImageWithExactHeight(128, f)); print("Loaded: " + f); print("Size: " + l(loadedButtons)); }); } } if (empty(l)) ret; if (loadQ == null) loadQ = startDeQ(); loadQ.addFirst(chainRunnables_pcall(l)); } }