1818package org .jackhuang .hmcl .ui .main ;
1919
2020import com .jfoenix .controls .JFXButton ;
21+ import com .jfoenix .controls .JFXListView ;
2122import javafx .beans .binding .Bindings ;
2223import javafx .beans .value .ChangeListener ;
2324import javafx .collections .FXCollections ;
2425import javafx .geometry .Insets ;
2526import javafx .geometry .Pos ;
2627import javafx .scene .Node ;
27- import javafx .scene .control .Control ;
28+ import javafx .scene .control .ListCell ;
2829import javafx .scene .control .Skin ;
29- import javafx .scene .control .SkinBase ;
30+ import javafx .scene .control .Tooltip ;
3031import javafx .scene .layout .BorderPane ;
3132import javafx .scene .layout .HBox ;
33+ import javafx .scene .layout .StackPane ;
3234import javafx .stage .FileChooser ;
3335import org .jackhuang .hmcl .java .JavaInfo ;
3436import org .jackhuang .hmcl .java .JavaManager ;
4244import org .jackhuang .hmcl .ui .construct .RipplerContainer ;
4345import org .jackhuang .hmcl .ui .construct .TwoLineListItem ;
4446import org .jackhuang .hmcl .ui .wizard .SinglePageWizardProvider ;
47+ import org .jackhuang .hmcl .util .FXThread ;
4548import org .jackhuang .hmcl .util .Pair ;
4649import org .jackhuang .hmcl .util .TaskCancellationAction ;
4750import org .jackhuang .hmcl .util .io .FileUtils ;
6265/**
6366 * @author Glavo
6467 */
65- public final class JavaManagementPage extends ListPageBase <JavaManagementPage . JavaItem > {
68+ public final class JavaManagementPage extends ListPageBase <JavaRuntime > {
6669
6770 @ SuppressWarnings ("FieldCanBeLocal" )
6871 private final ChangeListener <Collection <JavaRuntime >> listener ;
@@ -172,117 +175,94 @@ private void onInstallArchive(Path file) {
172175 }).start ();
173176 }
174177
175- // FXThread
178+ @ FXThread
176179 private void loadJava (Collection <JavaRuntime > javaRuntimes ) {
177180 if (javaRuntimes != null ) {
178- List <JavaItem > items = new ArrayList <>();
179- for (JavaRuntime java : javaRuntimes ) {
180- items .add (new JavaItem (java ));
181- }
182- this .setItems (FXCollections .observableList (items ));
181+ this .setItems (FXCollections .observableArrayList (javaRuntimes ));
183182 this .setLoading (false );
184- } else
183+ } else {
185184 this .setLoading (true );
185+ }
186186 }
187187
188- static final class JavaItem extends Control {
189- private final JavaRuntime java ;
188+ private static final class JavaPageSkin extends ToolbarListPageSkin <JavaRuntime , JavaManagementPage > {
190189
191- public JavaItem ( JavaRuntime java ) {
192- this . java = java ;
190+ JavaPageSkin ( JavaManagementPage skinnable ) {
191+ super ( skinnable ) ;
193192 }
194193
195- public JavaRuntime getJava () {
196- return java ;
197- }
194+ @ Override
195+ protected List < Node > initializeToolbar ( JavaManagementPage skinnable ) {
196+ ArrayList < Node > res = new ArrayList <>( 4 );
198197
199- public void onReveal () {
200- Path target ;
201- Path parent = java .getBinary ().getParent ();
202- if (parent != null
203- && parent .getParent () != null
204- && parent .getFileName () != null
205- && parent .getFileName ().toString ().equals ("bin" )
206- && Files .exists (parent .getParent ().resolve ("release" ))) {
207- target = parent .getParent ();
208- } else {
209- target = java .getBinary ();
198+ res .add (createToolbarButton2 (i18n ("button.refresh" ), SVG .REFRESH , JavaManager ::refresh ));
199+ if (skinnable .onInstallJava != null ) {
200+ res .add (createToolbarButton2 (i18n ("java.download" ), SVG .DOWNLOAD , skinnable .onInstallJava ));
210201 }
202+ res .add (createToolbarButton2 (i18n ("java.add" ), SVG .ADD , skinnable ::onAddJava ));
211203
212- FXUtils .showFileInExplorer (target );
213- }
204+ JFXButton disableJava = createToolbarButton2 (i18n ("java.disabled.management" ), SVG .FORMAT_LIST_BULLETED , skinnable ::onShowRestoreJavaPage );
205+ disableJava .disableProperty ().bind (Bindings .isEmpty (ConfigHolder .globalConfig ().getDisabledJava ()));
206+ res .add (disableJava );
214207
215- public void onRemove () {
216- if (java .isManaged ()) {
217- Controllers .taskDialog (JavaManager .getUninstallJavaTask (java ), i18n ("java.uninstall" ), TaskCancellationAction .NORMAL );
218- } else {
219- String path = java .getBinary ().toString ();
220- ConfigHolder .globalConfig ().getUserJava ().remove (path );
221- ConfigHolder .globalConfig ().getDisabledJava ().add (path );
222- try {
223- JavaManager .removeJava (java );
224- } catch (InterruptedException ignored ) {
225- }
226- }
208+ return res ;
227209 }
228210
229211 @ Override
230- protected Skin <?> createDefaultSkin ( ) {
231- return new JavaRuntimeItemSkin ( this );
212+ protected ListCell < JavaRuntime > createListCell ( JFXListView < JavaRuntime > listView ) {
213+ return new JavaItemCell ( );
232214 }
233-
234215 }
235216
236- private static final class JavaRuntimeItemSkin extends SkinBase <JavaItem > {
217+ private static final class JavaItemCell extends ListCell <JavaRuntime > {
218+ private final Node graphic ;
219+ private final TwoLineListItem content ;
237220
238- JavaRuntimeItemSkin (JavaItem control ) {
239- super (control );
240- JavaRuntime java = control .getJava ();
241- String vendor = JavaInfo .normalizeVendor (java .getVendor ());
221+ private SVG removeIcon ;
222+ private final StackPane removeIconPane ;
223+ private final Tooltip removeTooltip = new Tooltip ();
242224
225+ JavaItemCell () {
243226 BorderPane root = new BorderPane ();
244227
245228 HBox center = new HBox ();
246229 center .setMouseTransparent (true );
247230 center .setSpacing (8 );
248231 center .setAlignment (Pos .CENTER_LEFT );
249232
250- TwoLineListItem item = new TwoLineListItem ();
251- item .setTitle ((java .isJDK () ? "JDK" : "JRE" ) + " " + java .getVersion ());
252- item .setSubtitle (java .getBinary ().toString ());
253- item .addTag (i18n ("java.info.architecture" ) + ": " + java .getArchitecture ().getDisplayName ());
254- if (vendor != null )
255- item .addTag (i18n ("java.info.vendor" ) + ": " + vendor );
256- BorderPane .setAlignment (item , Pos .CENTER );
257- center .getChildren ().setAll (item );
233+ this .content = new TwoLineListItem ();
234+
235+ BorderPane .setAlignment (content , Pos .CENTER );
236+ center .getChildren ().setAll (content );
258237 root .setCenter (center );
259238
260239 HBox right = new HBox ();
261240 right .setAlignment (Pos .CENTER_RIGHT );
262241 {
263242 JFXButton revealButton = new JFXButton ();
264- revealButton .getStyleClass ().add ("toggle-icon4" );
265243 revealButton .setGraphic (FXUtils .limitingSize (SVG .FOLDER_OPEN .createIcon (24 ), 24 , 24 ));
266- revealButton .setOnAction (e -> control .onReveal ());
244+ revealButton .getStyleClass ().add ("toggle-icon4" );
245+ revealButton .setOnAction (e -> {
246+ JavaRuntime java = getItem ();
247+ if (java != null )
248+ onReveal (java );
249+ });
267250 FXUtils .installFastTooltip (revealButton , i18n ("reveal.in_file_manager" ));
268251
269252 JFXButton removeButton = new JFXButton ();
270253 removeButton .getStyleClass ().add ("toggle-icon4" );
271- removeButton .setOnAction (e -> Controllers .confirm (
272- java .isManaged () ? i18n ("java.uninstall.confirm" ) : i18n ("java.disable.confirm" ),
273- i18n ("message.warning" ),
274- control ::onRemove ,
275- null
276- ));
277- if (java .isManaged ()) {
278- removeButton .setGraphic (FXUtils .limitingSize (SVG .DELETE_FOREVER .createIcon (24 ), 24 , 24 ));
279- FXUtils .installFastTooltip (removeButton , i18n ("java.uninstall" ));
280- if (JavaRuntime .CURRENT_JAVA != null && java .getBinary ().equals (JavaRuntime .CURRENT_JAVA .getBinary ()))
281- removeButton .setDisable (true );
282- } else {
283- removeButton .setGraphic (FXUtils .limitingSize (SVG .DELETE .createIcon (24 ), 24 , 24 ));
284- FXUtils .installFastTooltip (removeButton , i18n ("java.disable" ));
285- }
254+ removeButton .setOnAction (e -> {
255+ JavaRuntime java = getItem ();
256+ if (java != null )
257+ onRemove (java );
258+ });
259+ FXUtils .installFastTooltip (removeButton , removeTooltip );
260+
261+ this .removeIconPane = new StackPane ();
262+ removeIconPane .setAlignment (Pos .CENTER );
263+ FXUtils .setLimitWidth (removeIconPane , 24 );
264+ FXUtils .setLimitHeight (removeIconPane , 24 );
265+ removeButton .setGraphic (removeIconPane );
286266
287267 right .getChildren ().setAll (revealButton , removeButton );
288268 }
@@ -291,31 +271,75 @@ private static final class JavaRuntimeItemSkin extends SkinBase<JavaItem> {
291271 root .getStyleClass ().add ("md-list-cell" );
292272 root .setPadding (new Insets (8 ));
293273
294- getChildren (). setAll ( new RipplerContainer (root ) );
274+ this . graphic = new RipplerContainer (root );
295275 }
296- }
297276
298- private static final class JavaPageSkin extends ToolbarListPageSkin <JavaItem , JavaManagementPage > {
277+ @ Override
278+ protected void updateItem (JavaRuntime item , boolean empty ) {
279+ super .updateItem (item , empty );
280+ if (empty || item == null ) {
281+ setGraphic (null );
282+ } else {
283+ content .setTitle ((item .isJDK () ? "JDK" : "JRE" ) + " " + item .getVersion ());
284+ content .setSubtitle (item .getBinary ().toString ());
285+
286+ content .getTags ().clear ();
287+ content .addTag (i18n ("java.info.architecture" ) + ": " + item .getArchitecture ().getDisplayName ());
288+ String vendor = JavaInfo .normalizeVendor (item .getVendor ());
289+ if (vendor != null )
290+ content .addTag (i18n ("java.info.vendor" ) + ": " + vendor );
291+
292+ SVG newRemoveIcon = item .isManaged () ? SVG .DELETE_FOREVER : SVG .DELETE ;
293+ if (removeIcon != newRemoveIcon ) {
294+ removeIcon = newRemoveIcon ;
295+ removeIconPane .getChildren ().setAll (removeIcon .createIcon (24 ));
296+ removeTooltip .setText (item .isManaged () ? i18n ("java.uninstall" ) : i18n ("java.disable" ));
297+ }
299298
300- JavaPageSkin ( JavaManagementPage skinnable ) {
301- super ( skinnable );
299+ setGraphic ( graphic );
300+ }
302301 }
303302
304- @ Override
305- protected List <Node > initializeToolbar (JavaManagementPage skinnable ) {
306- ArrayList <Node > res = new ArrayList <>(4 );
307-
308- res .add (createToolbarButton2 (i18n ("button.refresh" ), SVG .REFRESH , JavaManager ::refresh ));
309- if (skinnable .onInstallJava != null ) {
310- res .add (createToolbarButton2 (i18n ("java.download" ), SVG .DOWNLOAD , skinnable .onInstallJava ));
303+ private void onReveal (JavaRuntime java ) {
304+ Path target ;
305+ Path parent = java .getBinary ().getParent ();
306+ if (parent != null
307+ && parent .getParent () != null
308+ && parent .getFileName () != null
309+ && parent .getFileName ().toString ().equals ("bin" )
310+ && Files .exists (parent .getParent ().resolve ("release" ))) {
311+ target = parent .getParent ();
312+ } else {
313+ target = java .getBinary ();
311314 }
312- res .add (createToolbarButton2 (i18n ("java.add" ), SVG .ADD , skinnable ::onAddJava ));
313315
314- JFXButton disableJava = createToolbarButton2 (i18n ("java.disabled.management" ), SVG .FORMAT_LIST_BULLETED , skinnable ::onShowRestoreJavaPage );
315- disableJava .disableProperty ().bind (Bindings .isEmpty (ConfigHolder .globalConfig ().getDisabledJava ()));
316- res .add (disableJava );
316+ FXUtils .showFileInExplorer (target );
317+ }
317318
318- return res ;
319+ private void onRemove (JavaRuntime java ) {
320+ if (java .isManaged ()) {
321+ Controllers .confirm (
322+ i18n ("java.uninstall.confirm" ),
323+ i18n ("message.warning" ),
324+ () -> Controllers .taskDialog (JavaManager .getUninstallJavaTask (java ), i18n ("java.uninstall" ), TaskCancellationAction .NORMAL ),
325+ null
326+ );
327+ } else {
328+ Controllers .confirm (
329+ i18n ("java.disable.confirm" ),
330+ i18n ("message.warning" ),
331+ () -> {
332+ String path = java .getBinary ().toString ();
333+ ConfigHolder .globalConfig ().getUserJava ().remove (path );
334+ ConfigHolder .globalConfig ().getDisabledJava ().add (path );
335+ try {
336+ JavaManager .removeJava (java );
337+ } catch (InterruptedException ignored ) {
338+ }
339+ },
340+ null
341+ );
342+ }
319343 }
320344 }
321345}
0 commit comments