修复部分控件响应任意鼠标按键点击事件的问题 (#3380)

* update

* update

* update

* update

* update

* update

* update

* update

* update
This commit is contained in:
Glavo
2024-10-25 12:24:57 +08:00
committed by GitHub
parent 9e56b5cd15
commit 7645a600ef
26 changed files with 121 additions and 98 deletions

View File

@@ -957,6 +957,15 @@ public final class FXUtils {
}); });
} }
public static void onClicked(Node node, Runnable action) {
node.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> {
if (e.getButton() == MouseButton.PRIMARY && e.getClickCount() == 1) {
action.run();
e.consume();
}
});
}
public static void copyText(String text) { public static void copyText(String text) {
ClipboardContent content = new ClipboardContent(); ClipboardContent content = new ClipboardContent();
content.putString(text); content.putString(text);
@@ -987,7 +996,7 @@ public final class FXUtils {
if ("a".equals(element.getTagName())) { if ("a".equals(element.getTagName())) {
String href = element.getAttribute("href"); String href = element.getAttribute("href");
Text text = new Text(element.getTextContent()); Text text = new Text(element.getTextContent());
text.setOnMouseClicked(e -> { onClicked(text, () -> {
String link = href; String link = href;
try { try {
link = new URI(href).toASCIIString(); link = new URI(href).toASCIIString();

View File

@@ -123,7 +123,7 @@ public final class HTMLRenderer {
if (hyperlink != null) { if (hyperlink != null) {
URI target = resolveLink(hyperlink); URI target = resolveLink(hyperlink);
if (target != null) { if (target != null) {
text.setOnMouseClicked(event -> onClickHyperlink.accept(target)); FXUtils.onClicked(text, () -> onClickHyperlink.accept(target));
text.setCursor(Cursor.HAND); text.setCursor(Cursor.HAND);
} }
text.getStyleClass().add("html-hyperlink"); text.getStyleClass().add("html-hyperlink");
@@ -192,7 +192,7 @@ public final class HTMLRenderer {
if (hyperlink != null) { if (hyperlink != null) {
URI target = resolveLink(hyperlink); URI target = resolveLink(hyperlink);
if (target != null) { if (target != null) {
imageView.setOnMouseClicked(event -> onClickHyperlink.accept(target)); FXUtils.onClicked(imageView, () -> onClickHyperlink.accept(target));
imageView.setCursor(Cursor.HAND); imageView.setCursor(Cursor.HAND);
} }
} }

View File

@@ -23,7 +23,6 @@ import javafx.beans.binding.Bindings;
import javafx.beans.property.ObjectProperty; import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.css.PseudoClass; import javafx.css.PseudoClass;
import javafx.event.EventHandler;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Cursor; import javafx.scene.Cursor;
@@ -33,7 +32,7 @@ import javafx.scene.control.Label;
import javafx.scene.control.Skin; import javafx.scene.control.Skin;
import javafx.scene.control.SkinBase; import javafx.scene.control.SkinBase;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent; import javafx.scene.input.MouseButton;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import org.jackhuang.hmcl.download.LibraryAnalyzer; import org.jackhuang.hmcl.download.LibraryAnalyzer;
import org.jackhuang.hmcl.setting.Theme; import org.jackhuang.hmcl.setting.Theme;
@@ -60,8 +59,8 @@ public class InstallerItem extends Control {
private final ObjectProperty<InstalledState> versionProperty = new SimpleObjectProperty<>(this, "version", null); private final ObjectProperty<InstalledState> versionProperty = new SimpleObjectProperty<>(this, "version", null);
private final ObjectProperty<State> resolvedStateProperty = new SimpleObjectProperty<>(this, "resolvedState", InstallableState.INSTANCE); private final ObjectProperty<State> resolvedStateProperty = new SimpleObjectProperty<>(this, "resolvedState", InstallableState.INSTANCE);
private final ObjectProperty<EventHandler<? super MouseEvent>> installActionProperty = new SimpleObjectProperty<>(this, "installAction"); private final ObjectProperty<Runnable> onInstall = new SimpleObjectProperty<>(this, "onInstall");
private final ObjectProperty<EventHandler<? super MouseEvent>> removeActionProperty = new SimpleObjectProperty<>(this, "removeAction"); private final ObjectProperty<Runnable> onRemove = new SimpleObjectProperty<>(this, "onRemove");
public interface State { public interface State {
} }
@@ -170,12 +169,28 @@ public class InstallerItem extends Control {
return resolvedStateProperty; return resolvedStateProperty;
} }
public ObjectProperty<EventHandler<? super MouseEvent>> installActionProperty() { public ObjectProperty<Runnable> onInstallProperty() {
return installActionProperty; return onInstall;
} }
public ObjectProperty<EventHandler<? super MouseEvent>> removeActionProperty() { public Runnable getOnInstall() {
return removeActionProperty; return onInstall.get();
}
public void setOnInstall(Runnable onInstall) {
this.onInstall.set(onInstall);
}
public ObjectProperty<Runnable> onRemoveProperty() {
return onRemove;
}
public Runnable getOnRemove() {
return onRemove.get();
}
public void setOnRemove(Runnable onRemove) {
this.onRemove.set(onRemove);
} }
@Override @Override
@@ -371,7 +386,11 @@ public class InstallerItem extends Control {
removeButton.visibleProperty().bind(Bindings.createBooleanBinding(() -> control.resolvedStateProperty.get() instanceof InstalledState, control.resolvedStateProperty)); removeButton.visibleProperty().bind(Bindings.createBooleanBinding(() -> control.resolvedStateProperty.get() instanceof InstalledState, control.resolvedStateProperty));
} }
removeButton.managedProperty().bind(removeButton.visibleProperty()); removeButton.managedProperty().bind(removeButton.visibleProperty());
removeButton.onMouseClickedProperty().bind(control.removeActionProperty); removeButton.setOnAction(e -> {
Runnable onRemove = control.getOnRemove();
if (onRemove != null)
onRemove.run();
});
buttonsContainer.getChildren().add(removeButton); buttonsContainer.getChildren().add(removeButton);
JFXButton installButton = new JFXButton(); JFXButton installButton = new JFXButton();
@@ -383,7 +402,7 @@ public class InstallerItem extends Control {
)); ));
installButton.getStyleClass().add("toggle-icon4"); installButton.getStyleClass().add("toggle-icon4");
installButton.visibleProperty().bind(Bindings.createBooleanBinding(() -> { installButton.visibleProperty().bind(Bindings.createBooleanBinding(() -> {
if (control.installActionProperty.get() == null) { if (control.getOnInstall() == null) {
return false; return false;
} }
@@ -396,18 +415,27 @@ public class InstallerItem extends Control {
} }
return false; return false;
}, control.resolvedStateProperty, control.installActionProperty)); }, control.resolvedStateProperty, control.onInstall));
installButton.managedProperty().bind(installButton.visibleProperty()); installButton.managedProperty().bind(installButton.visibleProperty());
installButton.onMouseClickedProperty().bind(control.installActionProperty); installButton.setOnAction(e -> {
Runnable onInstall = control.getOnInstall();
if (onInstall != null)
onInstall.run();
});
buttonsContainer.getChildren().add(installButton); buttonsContainer.getChildren().add(installButton);
FXUtils.onChangeAndOperate(installButton.visibleProperty(), clickable -> { FXUtils.onChangeAndOperate(installButton.visibleProperty(), clickable -> {
if (clickable) { if (clickable) {
container.onMouseClickedProperty().bind(control.installActionProperty); container.setOnMouseClicked(event -> {
Runnable onInstall = control.getOnInstall();
if (onInstall != null && event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 1) {
onInstall.run();
event.consume();
}
});
pane.setCursor(Cursor.HAND); pane.setCursor(Cursor.HAND);
} else { } else {
container.onMouseClickedProperty().unbind(); container.setOnMouseClicked(null);
container.onMouseClickedProperty().set(null);
pane.setCursor(Cursor.DEFAULT); pane.setCursor(Cursor.DEFAULT);
} }
}); });

View File

@@ -34,6 +34,7 @@ import javafx.scene.Scene;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCode;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import javafx.stage.Stage; import javafx.stage.Stage;
import org.jackhuang.hmcl.game.GameDumpGenerator; import org.jackhuang.hmcl.game.GameDumpGenerator;
@@ -322,6 +323,9 @@ public final class LogWindow extends Stage {
setGraphic(null); setGraphic(null);
setOnMouseClicked(event -> { setOnMouseClicked(event -> {
if (event.getButton() != MouseButton.PRIMARY)
return;
if (!event.isControlDown()) { if (!event.isControlDown()) {
for (ListCell<Log> logListCell : selected) { for (ListCell<Log> logListCell : selected) {
if (logListCell != this) { if (logListCell != this) {
@@ -340,6 +344,8 @@ public final class LogWindow extends Stage {
if (getItem() != null) { if (getItem() != null) {
getItem().setSelected(true); getItem().setSelected(true);
} }
event.consume();
}); });
} }

View File

@@ -297,7 +297,7 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
hintPane.setSegment(i18n("account.methods.microsoft.hint")); hintPane.setSegment(i18n("account.methods.microsoft.hint"));
} }
}); });
hintPane.setOnMouseClicked(e -> { FXUtils.onClicked(hintPane, () -> {
if (deviceCode.get() != null) { if (deviceCode.get() != null) {
FXUtils.copyText(deviceCode.get().getUserCode()); FXUtils.copyText(deviceCode.get().getUserCode());
} }
@@ -658,7 +658,7 @@ public class CreateAccountPane extends JFXDialogLayout implements DialogAware {
TexturesLoader.bindAvatar(portraitCanvas, service, profile.getId()); TexturesLoader.bindAvatar(portraitCanvas, service, profile.getId());
IconedItem accountItem = new IconedItem(portraitCanvas, profile.getName()); IconedItem accountItem = new IconedItem(portraitCanvas, profile.getName());
accountItem.setOnMouseClicked(e -> { FXUtils.onClicked(accountItem, () -> {
selectedProfile = profile; selectedProfile = profile;
latch.countDown(); latch.countDown();
}); });

View File

@@ -58,7 +58,7 @@ public class OAuthAccountLoginDialog extends DialogPane {
); );
} }
}); });
hintPane.setOnMouseClicked(e -> { FXUtils.onClicked(hintPane, () -> {
if (deviceCode.get() != null) { if (deviceCode.get() != null) {
FXUtils.copyText(deviceCode.get().getUserCode()); FXUtils.copyText(deviceCode.get().getUserCode());
} }

View File

@@ -25,7 +25,6 @@ import javafx.scene.control.Control;
import javafx.scene.control.Skin; import javafx.scene.control.Skin;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane; import javafx.scene.layout.StackPane;
import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.util.Pair; import org.jackhuang.hmcl.util.Pair;
@@ -42,7 +41,7 @@ public class AdvancedListItem extends Control {
public AdvancedListItem() { public AdvancedListItem() {
getStyleClass().add("advanced-list-item"); getStyleClass().add("advanced-list-item");
addEventHandler(MouseEvent.MOUSE_CLICKED, e -> fireEvent(new ActionEvent())); FXUtils.onClicked(this, () -> fireEvent(new ActionEvent()));
} }
public Node getLeftGraphic() { public Node getLeftGraphic() {

View File

@@ -25,9 +25,6 @@ import javafx.animation.Timeline;
import javafx.application.Platform; import javafx.application.Platform;
import javafx.beans.property.BooleanProperty; import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleBooleanProperty;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
@@ -139,7 +136,7 @@ final class ComponentListCell extends StackPane {
container.getChildren().setAll(content); container.getChildren().setAll(content);
groupNode.getChildren().add(container); groupNode.getChildren().add(container);
EventHandler<Event> onExpand = e -> { Runnable onExpand = () -> {
if (expandAnimation != null && expandAnimation.getStatus() == Animation.Status.RUNNING) { if (expandAnimation != null && expandAnimation.getStatus() == Animation.Status.RUNNING) {
expandAnimation.stop(); expandAnimation.stop();
} }
@@ -182,8 +179,8 @@ final class ComponentListCell extends StackPane {
}); });
}; };
headerRippler.setOnMouseClicked(onExpand); FXUtils.onClicked(headerRippler, onExpand);
expandButton.setOnAction((EventHandler<ActionEvent>) (Object) onExpand); expandButton.setOnAction(e -> onExpand.run());
expandedProperty().addListener((a, b, newValue) -> expandIcon.setRotate(newValue ? 180 : 0)); expandedProperty().addListener((a, b, newValue) -> expandIcon.setRotate(newValue ? 180 : 0));

View File

@@ -21,6 +21,7 @@ import static javafx.collections.FXCollections.emptyObservableList;
import static javafx.collections.FXCollections.observableList; import static javafx.collections.FXCollections.observableList;
import static javafx.collections.FXCollections.singletonObservableList; import static javafx.collections.FXCollections.singletonObservableList;
import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.util.javafx.BindingMapping; import org.jackhuang.hmcl.util.javafx.BindingMapping;
import com.jfoenix.controls.JFXComboBox; import com.jfoenix.controls.JFXComboBox;
@@ -51,7 +52,7 @@ public class FontComboBox extends JFXComboBox<String> {
itemsProperty().bind(BindingMapping.of(valueProperty()) itemsProperty().bind(BindingMapping.of(valueProperty())
.map(value -> value == null ? emptyObservableList() : singletonObservableList(value))); .map(value -> value == null ? emptyObservableList() : singletonObservableList(value)));
setOnMouseClicked(e -> { FXUtils.onClicked(this, () -> {
if (loaded) if (loaded)
return; return;
itemsProperty().unbind(); itemsProperty().unbind();

View File

@@ -30,9 +30,9 @@ public class IconedMenuItem extends IconedItem {
getStyleClass().setAll("iconed-menu-item"); getStyleClass().setAll("iconed-menu-item");
if (popup == null) { if (popup == null) {
setOnMouseClicked(e -> action.run()); FXUtils.onClicked(this, action);
} else { } else {
setOnMouseClicked(e -> { FXUtils.onClicked(this, () -> {
action.run(); action.run();
popup.hide(); popup.hide();
}); });

View File

@@ -23,12 +23,12 @@ import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty; import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler; import javafx.event.EventHandler;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.control.Label; import javafx.scene.control.Label;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox; import javafx.scene.layout.VBox;
@@ -44,8 +44,8 @@ public final class ImagePickerItem extends BorderPane {
private final ImageView imageView; private final ImageView imageView;
private final StringProperty title = new SimpleStringProperty(this, "title"); private final StringProperty title = new SimpleStringProperty(this, "title");
private final ObjectProperty<EventHandler<? super MouseEvent>> onSelectButtonClicked = new SimpleObjectProperty<>(this, "onSelectButtonClicked"); private final ObjectProperty<EventHandler<ActionEvent>> onSelectButtonClicked = new SimpleObjectProperty<>(this, "onSelectButtonClicked");
private final ObjectProperty<EventHandler<? super MouseEvent>> onDeleteButtonClicked = new SimpleObjectProperty<>(this, "onDeleteButtonClicked"); private final ObjectProperty<EventHandler<ActionEvent>> onDeleteButtonClicked = new SimpleObjectProperty<>(this, "onDeleteButtonClicked");
private final ObjectProperty<Image> image = new SimpleObjectProperty<>(this, "image"); private final ObjectProperty<Image> image = new SimpleObjectProperty<>(this, "image");
public ImagePickerItem() { public ImagePickerItem() {
@@ -55,12 +55,12 @@ public final class ImagePickerItem extends BorderPane {
JFXButton selectButton = new JFXButton(); JFXButton selectButton = new JFXButton();
selectButton.setGraphic(SVG.PENCIL.createIcon(Theme.blackFill(), 20, 20)); selectButton.setGraphic(SVG.PENCIL.createIcon(Theme.blackFill(), 20, 20));
selectButton.onMouseClickedProperty().bind(onSelectButtonClicked); selectButton.onActionProperty().bind(onSelectButtonClicked);
selectButton.getStyleClass().add("toggle-icon4"); selectButton.getStyleClass().add("toggle-icon4");
JFXButton deleteButton = new JFXButton(); JFXButton deleteButton = new JFXButton();
deleteButton.setGraphic(SVG.CLOSE.createIcon(Theme.blackFill(), 20, 20)); deleteButton.setGraphic(SVG.CLOSE.createIcon(Theme.blackFill(), 20, 20));
deleteButton.onMouseClickedProperty().bind(onDeleteButtonClicked); deleteButton.onActionProperty().bind(onDeleteButtonClicked);
deleteButton.getStyleClass().add("toggle-icon4"); deleteButton.getStyleClass().add("toggle-icon4");
FXUtils.installFastTooltip(selectButton, i18n("button.edit")); FXUtils.installFastTooltip(selectButton, i18n("button.edit"));
@@ -93,27 +93,27 @@ public final class ImagePickerItem extends BorderPane {
this.title.set(title); this.title.set(title);
} }
public EventHandler<? super MouseEvent> getOnSelectButtonClicked() { public EventHandler<ActionEvent> getOnSelectButtonClicked() {
return onSelectButtonClicked.get(); return onSelectButtonClicked.get();
} }
public ObjectProperty<EventHandler<? super MouseEvent>> onSelectButtonClickedProperty() { public ObjectProperty<EventHandler<ActionEvent>> onSelectButtonClickedProperty() {
return onSelectButtonClicked; return onSelectButtonClicked;
} }
public void setOnSelectButtonClicked(EventHandler<? super MouseEvent> onSelectButtonClicked) { public void setOnSelectButtonClicked(EventHandler<ActionEvent> onSelectButtonClicked) {
this.onSelectButtonClicked.set(onSelectButtonClicked); this.onSelectButtonClicked.set(onSelectButtonClicked);
} }
public EventHandler<? super MouseEvent> getOnDeleteButtonClicked() { public EventHandler<ActionEvent> getOnDeleteButtonClicked() {
return onDeleteButtonClicked.get(); return onDeleteButtonClicked.get();
} }
public ObjectProperty<EventHandler<? super MouseEvent>> onDeleteButtonClickedProperty() { public ObjectProperty<EventHandler<ActionEvent>> onDeleteButtonClickedProperty() {
return onDeleteButtonClicked; return onDeleteButtonClicked;
} }
public void setOnDeleteButtonClicked(EventHandler<? super MouseEvent> onDeleteButtonClicked) { public void setOnDeleteButtonClicked(EventHandler<ActionEvent> onDeleteButtonClicked) {
this.onDeleteButtonClicked.set(onDeleteButtonClicked); this.onDeleteButtonClicked.set(onDeleteButtonClicked);
} }

View File

@@ -61,9 +61,7 @@ public class OptionToggleButton extends StackPane {
toggleButton.setSize(8); toggleButton.setSize(8);
FXUtils.setLimitHeight(toggleButton, 30); FXUtils.setLimitHeight(toggleButton, 30);
container.setOnMouseClicked(e -> { FXUtils.onClicked(container, () -> toggleButton.setSelected(!toggleButton.isSelected()));
toggleButton.setSelected(!toggleButton.isSelected());
});
FXUtils.onChangeAndOperate(subtitleProperty(), subtitle -> { FXUtils.onChangeAndOperate(subtitleProperty(), subtitle -> {
if (StringUtils.isNotBlank(subtitle)) { if (StringUtils.isNotBlank(subtitle)) {

View File

@@ -32,7 +32,6 @@ import javafx.scene.layout.StackPane;
import org.jackhuang.hmcl.ui.FXUtils; import org.jackhuang.hmcl.ui.FXUtils;
import org.jackhuang.hmcl.ui.animation.ContainerAnimations; import org.jackhuang.hmcl.ui.animation.ContainerAnimations;
import org.jackhuang.hmcl.ui.animation.TransitionPane; import org.jackhuang.hmcl.ui.animation.TransitionPane;
import org.jackhuang.hmcl.util.javafx.BindingMapping;
@DefaultProperty("content") @DefaultProperty("content")
public class SpinnerPane extends Control { public class SpinnerPane extends Control {
@@ -101,18 +100,19 @@ public class SpinnerPane extends Control {
return onFailedActionProperty().get(); return onFailedActionProperty().get();
} }
private ObjectProperty<EventHandler<Event>> onFailedAction = new SimpleObjectProperty<EventHandler<Event>>(this, "onFailedAction") { private final ObjectProperty<EventHandler<Event>> onFailedAction = new SimpleObjectProperty<EventHandler<Event>>(this, "onFailedAction") {
@Override @Override
protected void invalidated() { protected void invalidated() {
setEventHandler(FAILED_ACTION, get()); setEventHandler(FAILED_ACTION, get());
} }
}; };
@Override @Override
protected Skin createDefaultSkin() { protected SkinBase<SpinnerPane> createDefaultSkin() {
return new Skin(this); return new Skin(this);
} }
private static class Skin extends SkinBase<SpinnerPane> { private static final class Skin extends SkinBase<SpinnerPane> {
private final JFXSpinner spinner = new JFXSpinner(); private final JFXSpinner spinner = new JFXSpinner();
private final StackPane contentPane = new StackPane(); private final StackPane contentPane = new StackPane();
private final StackPane topPane = new StackPane(); private final StackPane topPane = new StackPane();
@@ -122,20 +122,18 @@ public class SpinnerPane extends Control {
@SuppressWarnings("FieldCanBeLocal") // prevent from gc. @SuppressWarnings("FieldCanBeLocal") // prevent from gc.
private final InvalidationListener observer; private final InvalidationListener observer;
protected Skin(SpinnerPane control) { Skin(SpinnerPane control) {
super(control); super(control);
topPane.getChildren().setAll(spinner); topPane.getChildren().setAll(spinner);
topPane.getStyleClass().add("notice-pane"); topPane.getStyleClass().add("notice-pane");
failedPane.getStyleClass().add("notice-pane"); failedPane.getStyleClass().add("notice-pane");
failedPane.getChildren().setAll(failedReasonLabel); failedPane.getChildren().setAll(failedReasonLabel);
failedPane.onMouseClickedProperty().bind( FXUtils.onClicked(failedPane, () -> {
BindingMapping.of(control.onFailedAction) EventHandler<Event> action = control.getOnFailedAction();
.map(actionHandler -> (e -> { if (action != null)
if (actionHandler != null) { action.handle(new Event(FAILED_ACTION));
actionHandler.handle(new Event(FAILED_ACTION)); });
}
})));
FXUtils.onChangeAndOperate(getSkinnable().content, newValue -> { FXUtils.onChangeAndOperate(getSkinnable().content, newValue -> {
if (newValue == null) { if (newValue == null) {

View File

@@ -30,7 +30,6 @@ import javafx.geometry.Insets;
import javafx.geometry.Side; import javafx.geometry.Side;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import javafx.scene.paint.Color; import javafx.scene.paint.Color;
import javafx.scene.transform.Rotate; import javafx.scene.transform.Rotate;
@@ -594,11 +593,9 @@ public class TabHeader extends Control implements TabControl, PageAware {
FXUtils.onChangeAndOperate(tab.selectedProperty(), selected -> inner.pseudoClassStateChanged(SELECTED_PSEUDOCLASS_STATE, selected)); FXUtils.onChangeAndOperate(tab.selectedProperty(), selected -> inner.pseudoClassStateChanged(SELECTED_PSEUDOCLASS_STATE, selected));
this.setOnMouseClicked(event -> { FXUtils.onClicked(this, () -> {
if (event.getButton() == MouseButton.PRIMARY) {
this.setOpacity(1); this.setOpacity(1);
getSkinnable().getSelectionModel().select(tab); getSkinnable().getSelectionModel().select(tab);
}
}); });
} }
} }

View File

@@ -59,7 +59,7 @@ class AdditionalInstallersPage extends InstallersPage {
for (InstallerItem library : group.getLibraries()) { for (InstallerItem library : group.getLibraries()) {
String libraryId = library.getLibraryId(); String libraryId = library.getLibraryId();
if (libraryId.equals("game")) continue; if (libraryId.equals("game")) continue;
library.removeActionProperty().set(e -> { library.setOnRemove(() -> {
controller.getSettings().put(libraryId, new UpdateInstallerWizardProvider.RemoveVersionAction(libraryId)); controller.getSettings().put(libraryId, new UpdateInstallerWizardProvider.RemoveVersionAction(libraryId));
reload(); reload();
}); });

View File

@@ -69,7 +69,7 @@ public class InstallersPage extends Control implements WizardPage {
for (InstallerItem library : group.getLibraries()) { for (InstallerItem library : group.getLibraries()) {
String libraryId = library.getLibraryId(); String libraryId = library.getLibraryId();
if (libraryId.equals(LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId())) continue; if (libraryId.equals(LibraryAnalyzer.LibraryType.MINECRAFT.getPatchId())) continue;
library.installActionProperty().set(e -> { library.setOnInstall(() -> {
if (LibraryAnalyzer.LibraryType.FABRIC_API.getPatchId().equals(libraryId)) { if (LibraryAnalyzer.LibraryType.FABRIC_API.getPatchId().equals(libraryId)) {
Controllers.dialog(i18n("install.installer.fabric-api.warning"), i18n("message.warning"), MessageDialogPane.MessageType.WARNING); Controllers.dialog(i18n("install.installer.fabric-api.warning"), i18n("message.warning"), MessageDialogPane.MessageType.WARNING);
} }
@@ -77,7 +77,7 @@ public class InstallersPage extends Control implements WizardPage {
if (!(library.resolvedStateProperty().get() instanceof InstallerItem.IncompatibleState)) if (!(library.resolvedStateProperty().get() instanceof InstallerItem.IncompatibleState))
controller.onNext(new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer." + libraryId)), gameVersion, downloadProvider, libraryId, () -> controller.onPrev(false))); controller.onNext(new VersionsPage(controller, i18n("install.installer.choose", i18n("install.installer." + libraryId)), gameVersion, downloadProvider, libraryId, () -> controller.onPrev(false)));
}); });
library.removeActionProperty().set(e -> { library.setOnRemove(() -> {
controller.getSettings().remove(libraryId); controller.getSettings().remove(libraryId);
reload(); reload();
}); });

View File

@@ -95,7 +95,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
HintPane hintPane = new HintPane(); HintPane hintPane = new HintPane();
hintPane.setText(i18n("sponsor.bmclapi")); hintPane.setText(i18n("sponsor.bmclapi"));
hintPane.getStyleClass().add("sponsor-pane"); hintPane.getStyleClass().add("sponsor-pane");
hintPane.setOnMouseClicked(e -> onSponsor()); FXUtils.onClicked(hintPane, this::onSponsor);
BorderPane.setMargin(hintPane, new Insets(10, 10, 0, 10)); BorderPane.setMargin(hintPane, new Insets(10, 10, 0, 10));
this.setTop(hintPane); this.setTop(hintPane);
@@ -146,7 +146,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
failedPane.getStyleClass().add("notice-pane"); failedPane.getStyleClass().add("notice-pane");
{ {
Label label = new Label(i18n("download.failed.refresh")); Label label = new Label(i18n("download.failed.refresh"));
label.setOnMouseClicked(e -> onRefresh()); FXUtils.onClicked(label, this::onRefresh);
failedPane.getChildren().setAll(label); failedPane.getChildren().setAll(label);
} }
@@ -155,7 +155,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
emptyPane.getStyleClass().add("notice-pane"); emptyPane.getStyleClass().add("notice-pane");
{ {
Label label = new Label(i18n("download.failed.empty")); Label label = new Label(i18n("download.failed.empty"));
label.setOnMouseClicked(e -> onBack()); FXUtils.onClicked(label, this::onBack);
emptyPane.getChildren().setAll(label); emptyPane.getChildren().setAll(label);
} }
@@ -180,7 +180,7 @@ public final class VersionsPage extends BorderPane implements WizardPage, Refres
Holder<RemoteVersionListCell> lastCell = new Holder<>(); Holder<RemoteVersionListCell> lastCell = new Holder<>();
list.setCellFactory(listView -> new RemoteVersionListCell(lastCell)); list.setCellFactory(listView -> new RemoteVersionListCell(lastCell));
list.setOnMouseClicked(e -> { FXUtils.onClicked(list, () -> {
if (list.getSelectionModel().getSelectedIndex() < 0) if (list.getSelectionModel().getSelectedIndex() < 0)
return; return;
navigation.getSettings().put(libraryId, list.getSelectionModel().getSelectedItem()); navigation.getSettings().put(libraryId, list.getSelectionModel().getSelectedItem());

View File

@@ -21,12 +21,10 @@ import com.jfoenix.controls.*;
import javafx.beans.binding.Bindings; import javafx.beans.binding.Bindings;
import javafx.beans.property.*; import javafx.beans.property.*;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Insets; import javafx.geometry.Insets;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.*; import javafx.scene.control.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.*; import javafx.scene.layout.*;
import javafx.stage.FileChooser; import javafx.stage.FileChooser;
import org.jackhuang.hmcl.auth.Account; import org.jackhuang.hmcl.auth.Account;
@@ -78,7 +76,6 @@ public final class ModpackInfoPage extends Control implements WizardPage {
private final SimpleStringProperty authlibInjectorServer = new SimpleStringProperty(); private final SimpleStringProperty authlibInjectorServer = new SimpleStringProperty();
private final SimpleStringProperty launchArguments = new SimpleStringProperty(""); private final SimpleStringProperty launchArguments = new SimpleStringProperty("");
private final SimpleStringProperty javaArguments = new SimpleStringProperty(""); private final SimpleStringProperty javaArguments = new SimpleStringProperty("");
private final ObjectProperty<EventHandler<? super MouseEvent>> next = new SimpleObjectProperty<>();
private final SimpleStringProperty mcbbsThreadId = new SimpleStringProperty(""); private final SimpleStringProperty mcbbsThreadId = new SimpleStringProperty("");
public ModpackInfoPage(WizardController controller, HMCLGameRepository gameRepository, String version) { public ModpackInfoPage(WizardController controller, HMCLGameRepository gameRepository, String version) {
@@ -97,8 +94,6 @@ public final class ModpackInfoPage extends Control implements WizardPage {
javaArguments.set(versionSetting.getJavaArgs()); javaArguments.set(versionSetting.getJavaArgs());
canIncludeLauncher = JarUtils.thisJarPath() != null; canIncludeLauncher = JarUtils.thisJarPath() != null;
next.set(e -> onNext());
} }
private void onNext() { private void onNext() {
@@ -376,7 +371,7 @@ public final class ModpackInfoPage extends Control implements WizardPage {
borderPane.setBottom(hbox); borderPane.setBottom(hbox);
JFXButton nextButton = FXUtils.newRaisedButton(i18n("wizard.next")); JFXButton nextButton = FXUtils.newRaisedButton(i18n("wizard.next"));
nextButton.onMouseClickedProperty().bind(skinnable.next); nextButton.setOnAction(e -> skinnable.onNext());
nextButton.setPrefWidth(100); nextButton.setPrefWidth(100);
nextButton.setPrefHeight(40); nextButton.setPrefHeight(40);
nextButton.disableProperty().bind( nextButton.disableProperty().bind(

View File

@@ -117,7 +117,7 @@ public final class MainPage extends StackPane implements DecoratorPage {
FXUtils.setLimitWidth(updatePane, 230); FXUtils.setLimitWidth(updatePane, 230);
FXUtils.setLimitHeight(updatePane, 55); FXUtils.setLimitHeight(updatePane, 55);
StackPane.setAlignment(updatePane, Pos.TOP_RIGHT); StackPane.setAlignment(updatePane, Pos.TOP_RIGHT);
updatePane.setOnMouseClicked(e -> onUpgrade()); FXUtils.onClicked(updatePane, this::onUpgrade);
FXUtils.onChange(showUpdateProperty(), this::showUpdate); FXUtils.onChange(showUpdateProperty(), this::showUpdate);
{ {
@@ -224,10 +224,10 @@ public final class MainPage extends StackPane implements DecoratorPage {
menu.setMaxHeight(365); menu.setMaxHeight(365);
menu.setMaxWidth(545); menu.setMaxWidth(545);
menu.setAlwaysShowingVBar(true); menu.setAlwaysShowingVBar(true);
menu.setOnMouseClicked(e -> popup.hide()); FXUtils.onClicked(menu, popup::hide);
versionNodes = MappedObservableList.create(versions, version -> { versionNodes = MappedObservableList.create(versions, version -> {
Node node = PopupMenu.wrapPopupMenuItem(new GameItem(profile, version.getId())); Node node = PopupMenu.wrapPopupMenuItem(new GameItem(profile, version.getId()));
node.setOnMouseClicked(e -> profile.setSelectedVersion(version.getId())); FXUtils.onClicked(node, () -> profile.setSelectedVersion(version.getId()));
return node; return node;
}); });
Bindings.bindContent(menu.getContent(), versionNodes); Bindings.bindContent(menu.getContent(), versionNodes);

View File

@@ -73,7 +73,7 @@ public abstract class SettingsView extends StackPane {
{ {
StackPane sponsorPane = new StackPane(); StackPane sponsorPane = new StackPane();
sponsorPane.setCursor(Cursor.HAND); sponsorPane.setCursor(Cursor.HAND);
sponsorPane.setOnMouseClicked(e -> onSponsor()); FXUtils.onClicked(sponsorPane, this::onSponsor);
sponsorPane.setPadding(new Insets(8, 0, 8, 0)); sponsorPane.setPadding(new Insets(8, 0, 8, 0));
GridPane gridPane = new GridPane(); GridPane gridPane = new GridPane();

View File

@@ -22,7 +22,6 @@ import javafx.css.PseudoClass;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Node; import javafx.scene.Node;
import javafx.scene.control.SkinBase; import javafx.scene.control.SkinBase;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane; import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import org.jackhuang.hmcl.setting.Theme; import org.jackhuang.hmcl.setting.Theme;
@@ -47,9 +46,7 @@ public class ProfileListItemSkin extends SkinBase<ProfileListItem> {
skinnable.pseudoClassStateChanged(SELECTED, active); skinnable.pseudoClassStateChanged(SELECTED, active);
}); });
getSkinnable().addEventHandler(MouseEvent.MOUSE_CLICKED, e -> { FXUtils.onClicked(getSkinnable(), () -> getSkinnable().setSelected(true));
getSkinnable().setSelected(true);
});
Node left = VersionPage.wrap(SVG.FOLDER_OUTLINE); Node left = VersionPage.wrap(SVG.FOLDER_OUTLINE);
root.setLeft(left); root.setLeft(left);

View File

@@ -488,7 +488,7 @@ public class DownloadListPage extends Control implements DecoratorPage, VersionP
JFXListView<RemoteMod> listView = new JFXListView<>(); JFXListView<RemoteMod> listView = new JFXListView<>();
spinnerPane.setContent(listView); spinnerPane.setContent(listView);
Bindings.bindContent(listView.getItems(), getSkinnable().items); Bindings.bindContent(listView.getItems(), getSkinnable().items);
listView.setOnMouseClicked(e -> { FXUtils.onClicked(listView, () -> {
if (listView.getSelectionModel().getSelectedIndex() < 0) if (listView.getSelectionModel().getSelectedIndex() < 0)
return; return;
RemoteMod selectedItem = listView.getSelectionModel().getSelectedItem(); RemoteMod selectedItem = listView.getSelectionModel().getSelectedItem();

View File

@@ -346,7 +346,7 @@ public class DownloadPage extends Control implements DecoratorPage {
pane.getChildren().setAll(FXUtils.limitingSize(imageView, 40, 40), content); pane.getChildren().setAll(FXUtils.limitingSize(imageView, 40, 40), content);
RipplerContainer container = new RipplerContainer(pane); RipplerContainer container = new RipplerContainer(pane);
container.setOnMouseClicked(e -> Controllers.navigate(new DownloadPage(page, addon, version, callback))); FXUtils.onClicked(container, () -> Controllers.navigate(new DownloadPage(page, addon, version, callback)));
getChildren().setAll(container); getChildren().setAll(container);
if (addon != RemoteMod.BROKEN) { if (addon != RemoteMod.BROKEN) {
@@ -428,7 +428,7 @@ public class DownloadPage extends Control implements DecoratorPage {
} }
RipplerContainer container = new RipplerContainer(pane); RipplerContainer container = new RipplerContainer(pane);
container.setOnMouseClicked(e -> Controllers.dialog(new ModVersion(dataItem, selfPage))); FXUtils.onClicked(container, () -> Controllers.dialog(new ModVersion(dataItem, selfPage)));
getChildren().setAll(container); getChildren().setAll(container);
// Workaround for https://github.com/HMCL-dev/HMCL/issues/2129 // Workaround for https://github.com/HMCL-dev/HMCL/issues/2129
@@ -443,7 +443,7 @@ public class DownloadPage extends Control implements DecoratorPage {
VBox box = new VBox(8); VBox box = new VBox(8);
box.setPadding(new Insets(8)); box.setPadding(new Insets(8));
ModItem modItem = new ModItem(version, selfPage); ModItem modItem = new ModItem(version, selfPage);
modItem.setOnMouseClicked(e -> fireEvent(new DialogCloseEvent())); FXUtils.onClicked(modItem, () -> fireEvent(new DialogCloseEvent()));
box.getChildren().setAll(modItem); box.getChildren().setAll(modItem);
SpinnerPane spinnerPane = new SpinnerPane(); SpinnerPane spinnerPane = new SpinnerPane();
ScrollPane scrollPane = new ScrollPane(); ScrollPane scrollPane = new ScrollPane();
@@ -505,7 +505,7 @@ public class DownloadPage extends Control implements DecoratorPage {
dependencies.put(dependency.getType(), list); dependencies.put(dependency.getType(), list);
} }
DependencyModItem dependencyModItem = new DependencyModItem(selfPage.page, dependency.load(), selfPage.version, selfPage.callback); DependencyModItem dependencyModItem = new DependencyModItem(selfPage.page, dependency.load(), selfPage.version, selfPage.callback);
dependencyModItem.setOnMouseClicked(e -> fireEvent(new DialogCloseEvent())); FXUtils.onClicked(dependencyModItem, () -> fireEvent(new DialogCloseEvent()));
dependencies.get(dependency.getType()).add(dependencyModItem); dependencies.get(dependency.getType()).add(dependencyModItem);
} }

View File

@@ -97,11 +97,11 @@ public class InstallerListPage extends ListPageBase<InstallerItem> implements Ve
item.versionProperty().set(null); item.versionProperty().set(null);
} }
item.installActionProperty().set(e -> { item.setOnInstall(() -> {
Controllers.getDecorator().startWizard(new UpdateInstallerWizardProvider(profile, gameVersion, version, libraryId, libraryVersion)); Controllers.getDecorator().startWizard(new UpdateInstallerWizardProvider(profile, gameVersion, version, libraryId, libraryVersion));
}); });
item.removeActionProperty().set(e -> profile.getDependency().removeLibraryAsync(version, libraryId) item.setOnRemove(() -> profile.getDependency().removeLibraryAsync(version, libraryId)
.thenComposeAsync(profile.getRepository()::saveAsync) .thenComposeAsync(profile.getRepository()::saveAsync)
.withComposeAsync(profile.getRepository().refreshVersionsAsync()) .withComposeAsync(profile.getRepository().refreshVersionsAsync())
.withRunAsync(Schedulers.javafx(), () -> loadVersion(this.profile, this.versionId)) .withRunAsync(Schedulers.javafx(), () -> loadVersion(this.profile, this.versionId))
@@ -121,7 +121,7 @@ public class InstallerListPage extends ListPageBase<InstallerItem> implements Ve
InstallerItem installerItem = new InstallerItem(libraryId, InstallerItem.Style.LIST_ITEM); InstallerItem installerItem = new InstallerItem(libraryId, InstallerItem.Style.LIST_ITEM);
installerItem.versionProperty().set(new InstallerItem.InstalledState(libraryVersion, false, false)); installerItem.versionProperty().set(new InstallerItem.InstalledState(libraryVersion, false, false));
installerItem.removeActionProperty().set(e -> profile.getDependency().removeLibraryAsync(version, libraryId) installerItem.setOnRemove(() -> profile.getDependency().removeLibraryAsync(version, libraryId)
.thenComposeAsync(profile.getRepository()::saveAsync) .thenComposeAsync(profile.getRepository()::saveAsync)
.withComposeAsync(profile.getRepository().refreshVersionsAsync()) .withComposeAsync(profile.getRepository().refreshVersionsAsync())
.withRunAsync(Schedulers.javafx(), () -> loadVersion(this.profile, this.versionId)) .withRunAsync(Schedulers.javafx(), () -> loadVersion(this.profile, this.versionId))

View File

@@ -95,9 +95,7 @@ public class VersionIconDialog extends DialogPane {
RipplerContainer container = new RipplerContainer(shape); RipplerContainer container = new RipplerContainer(shape);
FXUtils.setLimitWidth(container, 36); FXUtils.setLimitWidth(container, 36);
FXUtils.setLimitHeight(container, 36); FXUtils.setLimitHeight(container, 36);
container.setOnMouseClicked(e -> { FXUtils.onClicked(container, this::exploreIcon);
exploreIcon();
});
return container; return container;
} }
@@ -107,7 +105,7 @@ public class VersionIconDialog extends DialogPane {
RipplerContainer container = new RipplerContainer(imageView); RipplerContainer container = new RipplerContainer(imageView);
FXUtils.setLimitWidth(container, 36); FXUtils.setLimitWidth(container, 36);
FXUtils.setLimitHeight(container, 36); FXUtils.setLimitHeight(container, 36);
container.setOnMouseClicked(e -> { FXUtils.onClicked(container, () -> {
if (vs != null) { if (vs != null) {
vs.setVersionIcon(type); vs.setVersionIcon(type);
onAccept(); onAccept();

View File

@@ -51,7 +51,7 @@ public class WorldListItem extends Control {
subtitle.set(i18n("world.description", world.getFileName(), formatDateTime(Instant.ofEpochMilli(world.getLastPlayed())), world.getGameVersion() == null ? i18n("message.unknown") : world.getGameVersion())); subtitle.set(i18n("world.description", world.getFileName(), formatDateTime(Instant.ofEpochMilli(world.getLastPlayed())), world.getGameVersion() == null ? i18n("message.unknown") : world.getGameVersion()));
setOnMouseClicked(event -> showInfo()); FXUtils.onClicked(this, this::showInfo);
} }
@Override @Override