29
29
30
30
package org .scijava .ui .swing .laf ;
31
31
32
- import java .awt .Component ;
33
- import java .awt .EventQueue ;
34
- import java .awt .Window ;
35
- import java .util .ArrayList ;
36
- import java .util .HashSet ;
37
- import java .util .Set ;
32
+ import java .util .Arrays ;
33
+ import java .util .Collections ;
34
+ import java .util .List ;
35
+ import java .util .stream .Collectors ;
38
36
39
- import javax .swing .SwingUtilities ;
37
+ import javax .swing .LookAndFeel ;
40
38
import javax .swing .UIManager ;
41
39
import javax .swing .UIManager .LookAndFeelInfo ;
42
- import javax .swing .UnsupportedLookAndFeelException ;
43
40
44
- import com .formdev .flatlaf .FlatLightLaf ;
45
- import com .formdev .flatlaf .FlatDarkLaf ;
46
- import com .formdev .flatlaf .FlatIntelliJLaf ;
47
- import com .formdev .flatlaf .FlatLaf ;
48
- import com .formdev .flatlaf .FlatDarculaLaf ;
49
-
50
- import org .scijava .display .Display ;
51
- import org .scijava .display .DisplayService ;
52
- import org .scijava .log .LogService ;
53
41
import org .scijava .menu .MenuConstants ;
54
42
import org .scijava .module .MutableModuleItem ;
55
43
import org .scijava .options .OptionsPlugin ;
56
44
import org .scijava .plugin .Menu ;
57
45
import org .scijava .plugin .Parameter ;
58
46
import org .scijava .plugin .Plugin ;
59
- import org .scijava .ui .UIService ;
60
- import org .scijava .ui .UserInterface ;
61
- import org .scijava .ui .viewer .DisplayViewer ;
62
- import org .scijava .widget .UIComponent ;
63
47
64
48
/**
65
49
* Runs the Edit::Options::Look and Feel dialog.
@@ -79,9 +63,10 @@ public class OptionsLookAndFeel extends OptionsPlugin {
79
63
80
64
// -- Parameters --
81
65
82
- @ Parameter
83
- private LogService log ;
66
+ @ Parameter ( required = false )
67
+ private SwingLookAndFeelService lafService ;
84
68
69
+ // NB: This setting is persisted by the SwingLookAndFeelService.
85
70
@ Parameter (label = "Look & Feel" , persist = false ,
86
71
initializer = "initLookAndFeel" )
87
72
private String lookAndFeel ;
@@ -100,164 +85,28 @@ public void setLookAndFeel(final String lookAndFeel) {
100
85
101
86
@ Override
102
87
public void run () {
103
- // set look and feel
104
- final LookAndFeelInfo [] lookAndFeels = UIManager .getInstalledLookAndFeels ();
105
- for (final LookAndFeelInfo lookAndFeelInfo : lookAndFeels ) {
106
- if (lookAndFeelInfo .getName ().equals (lookAndFeel )) {
107
- try {
108
- UIManager .setLookAndFeel (lookAndFeelInfo .getClassName ());
109
- EventQueue .invokeLater (new Runnable () {
110
-
111
- @ Override
112
- public void run () {
113
- refreshSwingComponents ();
114
- }
115
- });
116
- }
117
- catch (final ClassNotFoundException e ) {
118
- log .error (e );
119
- }
120
- catch (final InstantiationException e ) {
121
- log .error (e );
122
- }
123
- catch (final IllegalAccessException e ) {
124
- log .error (e );
125
- }
126
- catch (final UnsupportedLookAndFeelException e ) {
127
- log .error (e );
128
- }
129
- break ;
130
- }
131
- }
132
-
88
+ if (lafService != null ) lafService .setLookAndFeel (lookAndFeel );
133
89
super .run ();
134
90
}
135
91
136
92
// -- Initializers --
137
93
138
94
protected void initLookAndFeel () {
139
- final String lafClass = UIManager .getLookAndFeel ().getClass ().getName ();
140
- LookAndFeelInfo [] lookAndFeels = UIManager .getInstalledLookAndFeels ();
141
-
142
- // Make UIManager aware of FlatLaf look and feels, as needed
143
- if (!isRegistered (lookAndFeels , FlatLightLaf .NAME )) FlatLightLaf .installLafInfo ();
144
- if (!isRegistered (lookAndFeels , FlatDarkLaf .NAME )) FlatDarkLaf .installLafInfo ();
145
- if (!isRegistered (lookAndFeels , FlatDarculaLaf .NAME )) FlatDarculaLaf .installLafInfo ();
146
- if (!isRegistered (lookAndFeels , FlatIntelliJLaf .NAME )) FlatIntelliJLaf .installLafInfo ();
147
- lookAndFeels = UIManager .getInstalledLookAndFeels (); // retrieve updated list
148
-
149
- final ArrayList <String > lookAndFeelChoices = new ArrayList <>();
150
- for (final LookAndFeelInfo lafInfo : lookAndFeels ) {
151
- final String lafName = lafInfo .getName ();
152
- lookAndFeelChoices .add (lafInfo .getName ());
153
- if (lafClass .equals (lafInfo .getClassName ())) {
154
- lookAndFeel = lafName ;
155
- }
156
- }
157
-
158
- final MutableModuleItem <String > lookAndFeelItem =
95
+ final MutableModuleItem <String > lafItem = //
159
96
getInfo ().getMutableInput (LOOK_AND_FEEL , String .class );
160
- lookAndFeelItem .setChoices (lookAndFeelChoices );
161
- }
162
-
163
- // -- Helper methods --
164
-
165
- /** Assesses whether lookAndFeels contains the laf associated with lafName*/
166
- private boolean isRegistered (final LookAndFeelInfo [] lookAndFeels , final String lafName ) {
167
- for (final LookAndFeelInfo lafInfo : lookAndFeels ) {
168
- if (lafInfo .getName ().equals (lafName ))
169
- return true ;
170
- }
171
- return false ;
172
- }
173
-
174
- /** Tells all known Swing components to change to the new Look & Feel. */
175
- private void refreshSwingComponents () {
176
- // TODO: Change this hacky logic to call a clean UIService API
177
- // for window retrieval. But does not exist as of this writing.
178
97
179
- final Set <Component > components = new HashSet <>();
98
+ final LookAndFeel laf = UIManager .getLookAndFeel ();
99
+ lookAndFeel = laf == null ? "<None>" : laf .getName ();
180
100
181
- // add Swing UI components from visible UIs
182
- for (final UserInterface ui : uiService ().getVisibleUIs ()) {
183
- findComponents (components , ui .getApplicationFrame ());
184
- findComponents (components , ui .getConsolePane ());
101
+ if (lafService == null ) {
102
+ lafItem .setChoices (Collections .singletonList (lookAndFeel ));
185
103
}
186
-
187
- // add Swing UI components from visible displays
188
- for (final Display <?> d : displayService ().getDisplays ()) {
189
- final DisplayViewer <?> viewer = uiService ().getDisplayViewer (d );
190
- if (viewer == null ) continue ;
191
- findComponents (components , viewer .getWindow ());
192
- }
193
-
194
- // refresh all discovered components
195
- for (final Component c : components ) {
196
- SwingUtilities .updateComponentTreeUI (c );
197
- if (c instanceof Window ) ((Window ) c ).pack ();
198
- }
199
- }
200
-
201
- /**
202
- * Extracts Swing components from the given object, adding them to
203
- * the specified set.
204
- */
205
- private void findComponents (final Set <Component > set , final Object o ) {
206
- if (o == null ) return ;
207
- if (o instanceof UIComponent ) {
208
- final UIComponent <?> c = (UIComponent <?>) o ;
209
- findComponents (set , c .getComponent ());
210
- }
211
- if (o instanceof Window ) set .add ((Window ) o );
212
- else if (o instanceof Component ) {
213
- final Component c = (Component ) o ;
214
- final Window w = SwingUtilities .getWindowAncestor (c );
215
- set .add (w == null ? c : w );
216
- }
217
- }
218
-
219
- private UIService uiService () {
220
- return getContext ().service (UIService .class );
221
- }
222
-
223
- private DisplayService displayService () {
224
- return getContext ().service (DisplayService .class );
225
- }
226
-
227
- /**
228
- * Sets the application look and feel.
229
- * <p>
230
- * Useful for setting up the look and feel early on in application startup
231
- * routine (e.g., through a macro or script)
232
- * </p>
233
- *
234
- * @param lookAndFeel the look and feel. Supported values include "FlatLaf
235
- * Light", "FlatLaf Dark", "FlatLaf Darcula", "FlatLaf
236
- * IntelliJ", and JVM defaults
237
- * ("javax.swing.plaf.metal.MetalLookAndFeel", etc.)
238
- */
239
- public static void setupLookAndFeel (final String lookAndFeel ) {
240
- switch (lookAndFeel ) { // FIXME: should FlatLaf.updateUI() calls be replaced with updateUILater()?
241
- case FlatLightLaf .NAME :
242
- if (FlatLightLaf .setup ()) FlatLaf .updateUI ();
243
- return ;
244
- case FlatDarkLaf .NAME :
245
- if (FlatDarkLaf .setup ()) FlatLaf .updateUI ();
246
- return ;
247
- case FlatDarculaLaf .NAME :
248
- if (FlatDarculaLaf .setup ()) FlatLaf .updateUI ();
249
- return ;
250
- case FlatIntelliJLaf .NAME :
251
- if (FlatIntelliJLaf .setup ()) FlatLaf .updateUI ();
252
- return ;
253
- default :
254
- try {
255
- UIManager .setLookAndFeel (lookAndFeel );
256
- FlatLaf .updateUI ();
257
- } catch (final Exception ex ) {
258
- ex .printStackTrace ();
259
- FlatLaf .revalidateAndRepaintAllFramesAndDialogs (); // Recover from possible ill-states
260
- }
104
+ else {
105
+ final LookAndFeelInfo [] infos = lafService .getLookAndFeels ();
106
+ final List <String > choices = Arrays .stream (infos )//
107
+ .map (info -> info .getName ())//
108
+ .collect (Collectors .toList ());
109
+ lafItem .setChoices (choices );
261
110
}
262
111
}
263
112
}
0 commit comments