Support #2992: 检查模组更新界面加入全选/取消全选复选框 (#3032)

Support #2992

---------

Co-authored-by: Glavo <zjx001202@gmail.com>
This commit is contained in:
Burning_TNT
2024-10-15 04:06:40 +08:00
committed by GitHub
parent 71c9632d61
commit 1ce9858893
2 changed files with 63 additions and 6 deletions

View File

@@ -23,11 +23,9 @@ import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.WeakInvalidationListener;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.Property;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.beans.value.WeakChangeListener;
import javafx.beans.value.WritableValue;
import javafx.beans.value.*;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
@@ -657,6 +655,61 @@ public final class FXUtils {
comboBox.getSelectionModel().selectedIndexProperty().removeListener(listener);
}
public static void bindAllEnabled(BooleanProperty allEnabled, BooleanProperty... children) {
int itemCount = children.length;
int childSelectedCount = 0;
for (BooleanProperty child : children) {
if (child.get())
childSelectedCount++;
}
allEnabled.set(childSelectedCount == itemCount);
class Listener implements InvalidationListener {
private int childSelectedCount;
private boolean updating = false;
public Listener(int childSelectedCount) {
this.childSelectedCount = childSelectedCount;
}
@Override
public void invalidated(Observable observable) {
if (updating)
return;
updating = true;
try {
boolean value = ((BooleanProperty) observable).get();
if (observable == allEnabled) {
for (BooleanProperty child : children) {
child.setValue(value);
}
childSelectedCount = value ? itemCount : 0;
} else {
if (value)
childSelectedCount++;
else
childSelectedCount--;
allEnabled.set(childSelectedCount == itemCount);
}
} finally {
updating = false;
}
}
}
InvalidationListener listener = new Listener(childSelectedCount);
WeakInvalidationListener weakListener = new WeakInvalidationListener(listener);
allEnabled.addListener(listener);
for (BooleanProperty child : children) {
child.addListener(weakListener);
}
}
public static void setIcon(Stage stage) {
String icon;
if (OperatingSystem.CURRENT_OS == OperatingSystem.WINDOWS) {
@@ -925,7 +978,7 @@ public final class FXUtils {
Element r = doc.getDocumentElement();
NodeList children = r.getChildNodes();
List<javafx.scene.Node> texts = new ArrayList<>();
List<Node> texts = new ArrayList<>();
for (int i = 0; i < children.getLength(); i++) {
org.w3c.dom.Node node = children.item(i);

View File

@@ -24,6 +24,7 @@ import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.CheckBoxTableCell;
@@ -73,6 +74,8 @@ public class ModUpdatesPage extends BorderPane implements DecoratorPage {
getStyleClass().add("gray-background");
TableColumn<ModUpdateObject, Boolean> enabledColumn = new TableColumn<>();
CheckBox allEnabledBox = new CheckBox();
enabledColumn.setGraphic(allEnabledBox);
enabledColumn.setCellFactory(CheckBoxTableCell.forTableColumn(enabledColumn));
setupCellValueFactory(enabledColumn, ModUpdateObject::enabledProperty);
enabledColumn.setEditable(true);
@@ -95,6 +98,7 @@ public class ModUpdatesPage extends BorderPane implements DecoratorPage {
setupCellValueFactory(sourceColumn, ModUpdateObject::sourceProperty);
objects = FXCollections.observableList(updates.stream().map(ModUpdateObject::new).collect(Collectors.toList()));
FXUtils.bindAllEnabled(allEnabledBox.selectedProperty(), objects.stream().map(o -> o.enabled).toArray(BooleanProperty[]::new));
TableView<ModUpdateObject> table = new TableView<>(objects);
table.setEditable(true);
@@ -170,7 +174,7 @@ public class ModUpdatesPage extends BorderPane implements DecoratorPage {
csvTable.write(Files.newOutputStream(path));
FXUtils.showFileInExplorer(path);
}).whenComplete(Schedulers.javafx() ,exception -> {
}).whenComplete(Schedulers.javafx(), exception -> {
if (exception == null) {
Controllers.dialog(path.toString(), i18n("message.success"));
} else {