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,95 @@ 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 {
184+ this .setItems (FXCollections .emptyObservableList ());
185185 this .setLoading (true );
186+ }
186187 }
187188
188- static final class JavaItem extends Control {
189- private final JavaRuntime java ;
189+ private static final class JavaPageSkin extends ToolbarListPageSkin <JavaRuntime , JavaManagementPage > {
190190
191- public JavaItem ( JavaRuntime java ) {
192- this . java = java ;
191+ JavaPageSkin ( JavaManagementPage skinnable ) {
192+ super ( skinnable ) ;
193193 }
194194
195- public JavaRuntime getJava () {
196- return java ;
197- }
195+ @ Override
196+ protected List < Node > initializeToolbar ( JavaManagementPage skinnable ) {
197+ ArrayList < Node > res = new ArrayList <>( 4 );
198198
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 ();
199+ res .add (createToolbarButton2 (i18n ("button.refresh" ), SVG .REFRESH , JavaManager ::refresh ));
200+ if (skinnable .onInstallJava != null ) {
201+ res .add (createToolbarButton2 (i18n ("java.download" ), SVG .DOWNLOAD , skinnable .onInstallJava ));
210202 }
203+ res .add (createToolbarButton2 (i18n ("java.add" ), SVG .ADD , skinnable ::onAddJava ));
211204
212- FXUtils .showFileInExplorer (target );
213- }
205+ JFXButton disableJava = createToolbarButton2 (i18n ("java.disabled.management" ), SVG .FORMAT_LIST_BULLETED , skinnable ::onShowRestoreJavaPage );
206+ disableJava .disableProperty ().bind (Bindings .isEmpty (ConfigHolder .globalConfig ().getDisabledJava ()));
207+ res .add (disableJava );
214208
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- }
209+ return res ;
227210 }
228211
229212 @ Override
230- protected Skin <?> createDefaultSkin ( ) {
231- return new JavaRuntimeItemSkin ( this );
213+ protected ListCell < JavaRuntime > createListCell ( JFXListView < JavaRuntime > listView ) {
214+ return new JavaItemCell ( );
232215 }
233-
234216 }
235217
236- private static final class JavaRuntimeItemSkin extends SkinBase <JavaItem > {
218+ private static final class JavaItemCell extends ListCell <JavaRuntime > {
219+ private final Node graphic ;
220+ private final TwoLineListItem content ;
237221
238- JavaRuntimeItemSkin (JavaItem control ) {
239- super (control );
240- JavaRuntime java = control .getJava ();
241- String vendor = JavaInfo .normalizeVendor (java .getVendor ());
222+ private SVG removeIcon ;
223+ private final StackPane removeIconPane ;
224+ private final Tooltip removeTooltip = new Tooltip ();
242225
226+ JavaItemCell () {
243227 BorderPane root = new BorderPane ();
244228
245229 HBox center = new HBox ();
246230 center .setMouseTransparent (true );
247231 center .setSpacing (8 );
248232 center .setAlignment (Pos .CENTER_LEFT );
249233
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 );
234+ this .content = new TwoLineListItem ();
235+
236+ BorderPane .setAlignment (content , Pos .CENTER );
237+ center .getChildren ().setAll (content );
258238 root .setCenter (center );
259239
260240 HBox right = new HBox ();
261241 right .setAlignment (Pos .CENTER_RIGHT );
262242 {
263243 JFXButton revealButton = new JFXButton ();
264- revealButton .getStyleClass ().add ("toggle-icon4" );
265244 revealButton .setGraphic (FXUtils .limitingSize (SVG .FOLDER_OPEN .createIcon (24 ), 24 , 24 ));
266- revealButton .setOnAction (e -> control .onReveal ());
245+ revealButton .getStyleClass ().add ("toggle-icon4" );
246+ revealButton .setOnAction (e -> {
247+ JavaRuntime java = getItem ();
248+ if (java != null )
249+ onReveal (java );
250+ });
267251 FXUtils .installFastTooltip (revealButton , i18n ("reveal.in_file_manager" ));
268252
269253 JFXButton removeButton = new JFXButton ();
270254 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- }
255+ removeButton .setOnAction (e -> {
256+ JavaRuntime java = getItem ();
257+ if (java != null )
258+ onRemove (java );
259+ });
260+ FXUtils .installFastTooltip (removeButton , removeTooltip );
261+
262+ this .removeIconPane = new StackPane ();
263+ removeIconPane .setAlignment (Pos .CENTER );
264+ FXUtils .setLimitWidth (removeIconPane , 24 );
265+ FXUtils .setLimitHeight (removeIconPane , 24 );
266+ removeButton .setGraphic (removeIconPane );
286267
287268 right .getChildren ().setAll (revealButton , removeButton );
288269 }
@@ -291,31 +272,75 @@ private static final class JavaRuntimeItemSkin extends SkinBase<JavaItem> {
291272 root .getStyleClass ().add ("md-list-cell" );
292273 root .setPadding (new Insets (8 ));
293274
294- getChildren (). setAll ( new RipplerContainer (root ) );
275+ this . graphic = new RipplerContainer (root );
295276 }
296- }
297277
298- private static final class JavaPageSkin extends ToolbarListPageSkin <JavaItem , JavaManagementPage > {
278+ @ Override
279+ protected void updateItem (JavaRuntime item , boolean empty ) {
280+ super .updateItem (item , empty );
281+ if (empty || item == null ) {
282+ setGraphic (null );
283+ } else {
284+ content .setTitle ((item .isJDK () ? "JDK" : "JRE" ) + " " + item .getVersion ());
285+ content .setSubtitle (item .getBinary ().toString ());
286+
287+ content .getTags ().clear ();
288+ content .addTag (i18n ("java.info.architecture" ) + ": " + item .getArchitecture ().getDisplayName ());
289+ String vendor = JavaInfo .normalizeVendor (item .getVendor ());
290+ if (vendor != null )
291+ content .addTag (i18n ("java.info.vendor" ) + ": " + vendor );
292+
293+ SVG newRemoveIcon = item .isManaged () ? SVG .DELETE_FOREVER : SVG .DELETE ;
294+ if (removeIcon != newRemoveIcon ) {
295+ removeIcon = newRemoveIcon ;
296+ removeIconPane .getChildren ().setAll (removeIcon .createIcon (24 ));
297+ removeTooltip .setText (item .isManaged () ? i18n ("java.uninstall" ) : i18n ("java.disable" ));
298+ }
299299
300- JavaPageSkin ( JavaManagementPage skinnable ) {
301- super ( skinnable );
300+ setGraphic ( graphic );
301+ }
302302 }
303303
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 ));
304+ private void onReveal (JavaRuntime java ) {
305+ Path target ;
306+ Path parent = java .getBinary ().getParent ();
307+ if (parent != null
308+ && parent .getParent () != null
309+ && parent .getFileName () != null
310+ && parent .getFileName ().toString ().equals ("bin" )
311+ && Files .exists (parent .getParent ().resolve ("release" ))) {
312+ target = parent .getParent ();
313+ } else {
314+ target = java .getBinary ();
311315 }
312- res .add (createToolbarButton2 (i18n ("java.add" ), SVG .ADD , skinnable ::onAddJava ));
313316
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 );
317+ FXUtils .showFileInExplorer (target );
318+ }
317319
318- return res ;
320+ private void onRemove (JavaRuntime java ) {
321+ if (java .isManaged ()) {
322+ Controllers .confirm (
323+ i18n ("java.uninstall.confirm" ),
324+ i18n ("message.warning" ),
325+ () -> Controllers .taskDialog (JavaManager .getUninstallJavaTask (java ), i18n ("java.uninstall" ), TaskCancellationAction .NORMAL ),
326+ null
327+ );
328+ } else {
329+ Controllers .confirm (
330+ i18n ("java.disable.confirm" ),
331+ i18n ("message.warning" ),
332+ () -> {
333+ String path = java .getBinary ().toString ();
334+ ConfigHolder .globalConfig ().getUserJava ().remove (path );
335+ ConfigHolder .globalConfig ().getDisabledJava ().add (path );
336+ try {
337+ JavaManager .removeJava (java );
338+ } catch (InterruptedException ignored ) {
339+ }
340+ },
341+ null
342+ );
343+ }
319344 }
320345 }
321346}
0 commit comments