Hier ein Beispiel-Code, wo man ein Limit an selected CheckBoxen, in einem TableView festlegen kann.
Funktion
- wenn das Limit an aktiven Checkboxen erreicht wurde, wird ein Alert angezeigt und alle andern Checkboxen im TableView werden auf disable gesetzt
- wenn in der ObservableList des TableView, mehr Items auf „true“ gesetzt sind, als das Limit zulässt, werden die letzten Einträge in der ObservableList auf „false“ gesetzt
Code
DemoMaxChecked.java
import java.util.HashMap;
import java.util.function.Consumer;
import javafx.application.Application;
import javafx.beans.property.SimpleLongProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.CheckBox;
import javafx.scene.control.DialogPane;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class DemoMaxChecked extends Application {
// Config
private int maxChecked = 4;
private TableView<DemoUserModel> table;
private SimpleLongProperty activeUserProperty = new SimpleLongProperty();
private HashMap<String, Boolean> dontShowAgain = new HashMap<String, Boolean>();
@Override
public void start(Stage mainStage) {
mainStage.setTitle("JavaFX-Table");
ObservableList<DemoUserModel> data =FXCollections.observableArrayList(
new DemoUserModel("1", "Inge", true ),
new DemoUserModel("2", "Jens", false ),
new DemoUserModel("3", "Klaus", true ),
new DemoUserModel("4", "Sven", true ),
new DemoUserModel("5", "Patrick", true ),
new DemoUserModel("6", "Ben", true ),
new DemoUserModel("7", "Eddy", true ),
new DemoUserModel("8", "Maik", true ),
new DemoUserModel("9", "Rudi", false ),
new DemoUserModel("10", "Daniel", true ),
new DemoUserModel("11", "Rainer", false ),
new DemoUserModel("12", "Rene", true ),
new DemoUserModel("13", "Thorsten", true ));
this.table = new TableView<>();
table.setEditable(true);
TableColumn<DemoUserModel, String> col1 = new TableColumn<>("ID");
col1.setCellValueFactory(new PropertyValueFactory<DemoUserModel, String>("id"));
TableColumn<DemoUserModel, String> col2 = new TableColumn<>("User");
col2.setCellValueFactory(new PropertyValueFactory<DemoUserModel, String>("userName"));
TableColumn<DemoUserModel, Boolean> col3 = new TableColumn<>("Activate");
col3.setCellValueFactory(new PropertyValueFactory<>("userActivate"));
col3.setCellFactory(column -> new TableCellCheckboxAktiviert<>(this));
table.getColumns().addAll(col1, col2, col3);
table.setItems(data);
// Shows a Alert when user maximum is reached
activeUserProperty.addListener((ov, oldVal, newVal) -> {
boolean isAlertAgain = dontShowAgain.size() == 0
? true : dontShowAgain.get("KEY_AUTO_EXIT");
if (newVal == Long.valueOf(maxChecked) && isAlertAgain) {
showAlert();
}
});
Button buttonAddUser = new Button("Add User");
buttonAddUser.setOnAction(e -> addUser());
Button buttonDelUser = new Button("Delete User");
buttonDelUser.setOnAction(e -> delUser());
HBox hBoxButtons = new HBox(buttonAddUser, buttonDelUser);
hBoxButtons.setSpacing(10);
hBoxButtons.setAlignment(Pos.CENTER);
Label labelActiveUser = new Label();
labelActiveUser.textProperty().bind(activeUserProperty.asString());
Label labelActiveUserMax = new Label("/" + maxChecked + " User");
HBox hBoxActiveUser = new HBox(labelActiveUser, labelActiveUserMax);
hBoxActiveUser.setSpacing(0);
hBoxActiveUser.setPadding(new Insets(0, 5, -8, 0)); // (top/right/bottom/left)
hBoxActiveUser.setAlignment(Pos.BOTTOM_RIGHT);
VBox root = new VBox(hBoxButtons, hBoxActiveUser, table);
root.setSpacing(10);
Scene scene = new Scene(root, 500, 500);
mainStage.setScene(scene);
mainStage.show();
}
private void addUser() {
String userID = table.getItems().size() + 1 + "";
table.getItems().add(new DemoUserModel(userID, "Max", false ));
}
private void delUser() {
DemoUserModel item = table.getSelectionModel().getSelectedItem();
if (item != null) {
table.getItems().remove(item);
}
}
public void showAlert() {
Alert alert = createAlertWithOptOut(AlertType.CONFIRMATION, "Exit", null,
"You can only select a maximum of " + maxChecked + "!", "Do not show again",
param -> dontShowAgain.put("KEY_AUTO_EXIT", param ? false : true), ButtonType.OK);
if (alert.showAndWait().filter(t -> t == ButtonType.OK).isPresent()) {
alert.close();
}
}
private Alert createAlertWithOptOut(AlertType type, String title, String headerText,
String message, String optOutMessage, Consumer<Boolean> optOutAction,
ButtonType... buttonTypes) {
Alert alert = new Alert(type);
Node graphic = alert.getDialogPane().getGraphic();
alert.getDialogPane().applyCss();
alert.setDialogPane(new DialogPane() {
@Override
protected Node createDetailsButton() {
CheckBox optOut = new CheckBox();
optOut.setText(optOutMessage);
optOut.setOnAction(e -> optOutAction.accept(optOut.isSelected()));
return optOut;
}
});
alert.getDialogPane().getButtonTypes().addAll(buttonTypes);
alert.getDialogPane().setContentText(message);
alert.getDialogPane().setExpandableContent(new Group());
alert.getDialogPane().setExpanded(true);
alert.getDialogPane().setGraphic(graphic);
alert.setTitle(title);
alert.setHeaderText(headerText);
return alert;
}
// Getter
public int getMaxChecked() {return maxChecked;}
public SimpleLongProperty activeUserProperty() {return activeUserProperty;}
public HashMap<String, Boolean> getDontShowAgain() {return dontShowAgain;}
public static void main(String[] args) {
launch(args);
}
}Code-Sprache: JavaScript (javascript)
TableCellCheckboxAktiviert.java
import javafx.application.Platform;
import javafx.beans.property.SimpleLongProperty;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableRow;
import javafx.scene.layout.HBox;
public class TableCellCheckboxAktiviert<T> extends TableCell<DemoUserModel, Boolean> {
private int maxChecked;
private SimpleLongProperty activeUserProperty;
private DemoMaxChecked demoMaxChecked;
public TableCellCheckboxAktiviert(DemoMaxChecked demoMaxChecked) {
this.demoMaxChecked = demoMaxChecked;
this.maxChecked = demoMaxChecked.getMaxChecked();
this.activeUserProperty = demoMaxChecked.activeUserProperty();
}
@Override
protected void updateItem(Boolean item, boolean empty) {
super.updateItem(item, empty);
Platform.runLater(() -> {
TableRow<DemoUserModel> row = (TableRow<DemoUserModel>) getTableRow();
if (row == null || row.getItem() == null) {
setText(null);
setGraphic(null);
} else {
System.out.println("updateItem -> ID["
+ row.getItem().getID() + "], User[" + row.getItem().getUserName() + "]");
DemoUserModel rowItem = row.getItem();
CheckBox checkBox = rowItem.getCheckBox();
HBox hBox = new HBox();
hBox.setAlignment(Pos.CENTER);
hBox.getChildren().add(checkBox);
setText(null);
setGraphic(hBox);
// Select Row if CheckBox clicked
getTableView().requestFocus();
getTableView().getSelectionModel().select(row.getItem());
getTableView().getFocusModel().focus(
getTableView().getSelectionModel().getSelectedIndex());
// limit Activate users to a maximum
ObservableList<DemoUserModel> items = getTableView().getItems();
long countAktiveBenutzer = items.stream().filter(b -> b.isUserActivate()).count();
if (countAktiveBenutzer == maxChecked) {
items.stream().filter(b -> !b.isUserActivate())
.forEach(e -> e.getCheckBox().setDisable(true));
} else {
items.stream().filter(b -> !b.isUserActivate())
.forEach(e -> e.getCheckBox().setDisable(false));
}
// remove selection if more than maximum
while (countAktiveBenutzer > maxChecked) {
// get last selected checkBox
DemoUserModel lastSelected = items.stream().filter(b -> b.isUserActivate())
.reduce((first, second) -> second).orElse(null);
// remove selection from last selected checkBox
lastSelected.getCheckBox().setSelected(false);
System.out.println("remove selection by -> ID["
+ lastSelected.getID() + "], User[" + lastSelected.getUserName() + "]");
countAktiveBenutzer = items.stream().filter(b -> b.isUserActivate()).count();
}
// Update labelActiveUser
activeUserProperty.set(getTableView().getItems().stream()
.filter(b -> b.isUserActivate()).count());
}
});
}
}Code-Sprache: JavaScript (javascript)
DemoUserModel
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.ReadOnlyStringProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.scene.control.CheckBox;
public class DemoUserModel {
private SimpleStringProperty id;
private SimpleStringProperty userName;
private SimpleBooleanProperty userActivate;
private CheckBox checkBox;
public DemoUserModel(String id, String userName, boolean userActivate) {
this.id = new SimpleStringProperty(id);
this.userName = new SimpleStringProperty(userName);
this.userActivate = new SimpleBooleanProperty(userActivate);
this.checkBox = new CheckBox();
checkBox.setSelected(userActivate);
checkBox.selectedProperty().addListener((ov, olaVal, newVal) -> setUserActivate(newVal));
}
// Properteis
public ReadOnlyStringProperty idProperty() {return id;}
public ReadOnlyStringProperty userNameProperty() {return userName;}
public ReadOnlyBooleanProperty userActivateProperty() {return userActivate;}
// Getter
public String getID(){ return id.get();}
public String getUserName(){ return userName.get();}
public boolean isUserActivate(){ return userActivate.get();}
public CheckBox getCheckBox() {return checkBox;}
// Setter
public void setID(String id){ this.id.set(id);}
public void setUserName(String userName){this.userName.set(userName);}
public void setUserActivate(boolean userActivate){ this.userActivate.set(userActivate);}
}Code-Sprache: JavaScript (javascript)