3030
3131package org .scijava .ui .swing .options ;
3232
33+ import java .awt .Component ;
3334import java .awt .EventQueue ;
35+ import java .awt .Window ;
3436import java .util .ArrayList ;
37+ import java .util .HashSet ;
38+ import java .util .Set ;
3539
3640import javax .swing .SwingUtilities ;
3741import javax .swing .UIManager ;
3842import javax .swing .UIManager .LookAndFeelInfo ;
3943import javax .swing .UnsupportedLookAndFeelException ;
4044
45+ import org .scijava .display .Display ;
46+ import org .scijava .display .DisplayService ;
4147import org .scijava .log .LogService ;
4248import org .scijava .menu .MenuConstants ;
4349import org .scijava .module .MutableModuleItem ;
4753import org .scijava .plugin .Plugin ;
4854import org .scijava .ui .UIService ;
4955import org .scijava .ui .UserInterface ;
50- import org .scijava .ui .swing .SwingApplicationFrame ;
56+ import org .scijava .ui .viewer .DisplayViewer ;
57+ import org .scijava .widget .UIComponent ;
5158
5259/**
5360 * Runs the Edit::Options::Look and Feel dialog.
@@ -70,6 +77,9 @@ public class OptionsLookAndFeel extends OptionsPlugin {
7077 @ Parameter
7178 private UIService uiService ;
7279
80+ @ Parameter
81+ private DisplayService displayService ;
82+
7383 @ Parameter
7484 private LogService log ;
7585
@@ -148,12 +158,47 @@ protected void initLookAndFeel() {
148158
149159 /** Tells all known Swing components to change to the new Look & Feel. */
150160 private void refreshSwingComponents () {
151- // FIXME: Get all windows from UIService rather than just app.
152- final UserInterface ui = uiService .getDefaultUI ();
153- final SwingApplicationFrame swingAppFrame =
154- (SwingApplicationFrame ) ui .getApplicationFrame ();
155- SwingUtilities .updateComponentTreeUI (swingAppFrame );
156- swingAppFrame .pack ();
161+ // TODO: Change this hacky logic to call a clean UIService API
162+ // for window retrieval. But does not exist as of this writing.
163+
164+ final Set <Component > components = new HashSet <>();
165+
166+ // add Swing UI components from visible UIs
167+ for (final UserInterface ui : uiService .getVisibleUIs ()) {
168+ findComponents (components , ui .getApplicationFrame ());
169+ findComponents (components , ui .getConsolePane ());
170+ }
171+
172+ // add Swing UI components from visible displays
173+ for (final Display <?> d : displayService .getDisplays ()) {
174+ final DisplayViewer <?> viewer = uiService .getDisplayViewer (d );
175+ if (viewer == null ) continue ;
176+ findComponents (components , viewer .getWindow ());
177+ }
178+
179+ // refresh all discovered components
180+ for (final Component c : components ) {
181+ SwingUtilities .updateComponentTreeUI (c );
182+ if (c instanceof Window ) ((Window ) c ).pack ();
183+ }
184+ }
185+
186+ /**
187+ * Extracts Swing components from the given object, adding them to
188+ * the specified set.
189+ */
190+ private void findComponents (final Set <Component > set , final Object o ) {
191+ if (o == null ) return ;
192+ if (o instanceof UIComponent ) {
193+ final UIComponent <?> c = (UIComponent <?>) o ;
194+ findComponents (set , c .getComponent ());
195+ }
196+ if (o instanceof Window ) set .add ((Window ) o );
197+ else if (o instanceof Component ) {
198+ final Component c = (Component ) o ;
199+ final Window w = SwingUtilities .getWindowAncestor (c );
200+ set .add (w == null ? c : w );
201+ }
157202 }
158203
159204 // -- Deprecated methods --
0 commit comments