Summary
Images across the ui and ui.jobs bundles are loaded at each call site (mostly through
UiUtils.buildImageFromPngPath(...) / buildImageDescriptorFromPngPath(...)) instead of through a central
ImageRegistry. Each caller passes a hard-coded resource path, gets a freshly created Image, caches
it in a field, and is responsible for disposing it. This is repetitive, leak-prone, and hard to maintain.
Problems
- Manual disposal is error-prone and duplicated — every image owner repeats image instantiation, caching, disposal checks, and registers dispose listeners. Every occurrence is a chance to leak, to access a disposed image, or to double-dispose.
- Actual resource leaks — some images are created as static fields and never disposed.
- Fragile hand-rolled static caches — several widgets keep a
static Image field plus a manual
disposeStaticIcons() cleanup that must stay in sync with every read.
- Duplicate image instances —
buildImageFromPngPath decodes and allocates a new Image on every call,
so the same icon is loaded many times instead of being shared/cached.
- Theme handling duplicated and easy to get wrong — dark/light selection is re-implemented inline at
~17 sites, each branching on UiUtils.isDarkTheme() and picking one of two hard-coded paths; inconsistent
file names (*_black/*_white, *_dark) make it easy to swap the arguments and show the wrong variant.
- Raw path string literals instead of typed keys — icons are referenced as strings like
"/icons/chat/tools_disabled.png" (~130+ literals), so typos or moved/renamed resources fail only at
runtime and there is no single inventory of shipped icons.
Expected behavior
Images should be loaded, cached, and disposed using a plug-in's image registry.
Summary
Images across the
uiandui.jobsbundles are loaded at each call site (mostly throughUiUtils.buildImageFromPngPath(...)/buildImageDescriptorFromPngPath(...)) instead of through a centralImageRegistry. Each caller passes a hard-coded resource path, gets a freshly createdImage, cachesit in a field, and is responsible for disposing it. This is repetitive, leak-prone, and hard to maintain.
Problems
static Imagefield plus a manualdisposeStaticIcons()cleanup that must stay in sync with every read.buildImageFromPngPathdecodes and allocates a newImageon every call,so the same icon is loaded many times instead of being shared/cached.
~17 sites, each branching on
UiUtils.isDarkTheme()and picking one of two hard-coded paths; inconsistentfile names (
*_black/*_white,*_dark) make it easy to swap the arguments and show the wrong variant."/icons/chat/tools_disabled.png"(~130+ literals), so typos or moved/renamed resources fail only atruntime and there is no single inventory of shipped icons.
Expected behavior
Images should be loaded, cached, and disposed using a plug-in's image registry.