Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package com.dlsc.gemsfx.demo.binding;
import com.dlsc.gemsfx.binding.AggregatedListBinding;
import com.dlsc.gemsfx.binding.GeneralAggregatedListBinding;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Pair;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
/**
* This demo shows how to use the {@link AggregatedListBinding} and {@link GeneralAggregatedListBinding} classes to create
* bindings that aggregate values from a list of objects. In this example, we have a list of students where each student
* has a list of scores. We create bindings that calculate the total and average score of all students, as well as the
* number of students who have at least one failing score.
*/
public class AggregatedListBindingApp extends Application {
private final ObservableList students = FXCollections.observableArrayList();
private final TableView tableView = new TableView<>();
private final Random random = new Random();
private int index;
@Override
public void start(Stage primaryStage) {
students.add(new Student("Alice", FXCollections.observableArrayList(80, 90, 88)));
students.add(new Student("Bob", FXCollections.observableArrayList(75, 82, 91)));
initTableView();
Label averageLabel = new Label();
// Creates a binding to calculate the average score of all students. Each student has a list of scores,
// and this binding computes the average of all these scores across all students. This is achieved by mapping each
// student's scores to their integer values, calculating the average of these values, and handling cases where
// there are no scores (using orElse(0.0) to return 0.0 if no scores are present).
AggregatedListBinding averageBinding = new AggregatedListBinding<>(
students, // the list of students
Student::getScores, // function to get scores from each student
stream -> stream.mapToInt(Integer::intValue).average().orElse(0.0) // function to calculate average of scores
);
averageLabel.textProperty().bind(averageBinding.asString("Average Score: %.2f"));
Label sumLabel = new Label();
// Creates a binding to calculate the total score of all students. This binding sums up all scores
// from all students. It uses a mapping function to convert scores to integers and then sums them up.
AggregatedListBinding sumBinding = new AggregatedListBinding<>(
students, // the list of students
Student::getScores, // function to get scores from each student
stream -> stream.mapToInt(Integer::intValue).sum() // function to sum all scores
);
sumLabel.textProperty().bind(sumBinding.asString("Total Score: %d"));
Label averageLabel2 = new Label();
// This binding calculates a more complex form of average using a pair to hold the sum of scores and the count of scores,
// allowing the calculation of the average in a subsequent step. It demonstrates a more advanced use of aggregation
// with intermediary transformations.
GeneralAggregatedListBinding, Double> averageBinding2 = new GeneralAggregatedListBinding<>(
students, // the list of students
Student::getScores, // function to extract scores from each student
scores -> new Pair<>(scores.stream().mapToInt(Integer::intValue).sum(), scores.size()), // maps scores to a pair of sum and count
results -> {
List> resultsList = results.toList();
return resultsList.stream().mapToDouble(Pair::getKey).sum() / resultsList.stream().mapToDouble(Pair::getValue).sum();
}
);
averageLabel2.textProperty().bind(averageBinding2.asString("Average Score: %.2f"));
Label sumLabel2 = new Label();
// Creates a binding to calculate the total score of all students using a generalized binding approach that sums up individual results.
GeneralAggregatedListBinding sumBinding2 = new GeneralAggregatedListBinding<>(
students, // the list of students
Student::getScores, // function to extract scores from each student
scores -> scores.stream().mapToInt(Integer::intValue).sum(), // function to sum scores of a single student
results -> results.reduce(0, Integer::sum) // reduces all individual sums into one sum
);
sumLabel2.textProperty().bind(sumBinding2.asString("Total Score: %d"));
// This label displays the number of students who have at least one failing score (<60).
Label failingCountLabel = new Label();
// This binding counts how many students have at least one failing score (<60). It demonstrates using a conditional aggregation
// where each student's score list is evaluated for failing scores, and each failing student contributes '1' to the total count.
GeneralAggregatedListBinding failingCountBinding = new GeneralAggregatedListBinding<>(
students, // the list of students
Student::getScores, // function to extract scores from each student
scores -> scores.stream().anyMatch(score -> score < 60) ? 1L : 0L, // checks if any score is below 60, returns 1 if true, else 0
results -> results.reduce(0L, Long::sum) // sums up all '1's representing failing students
);
failingCountLabel.textProperty().bind(failingCountBinding.asString("Number of Failing Students: %d"));
Node statistics1 = createStatisticBox("AggregatedListBinding", averageLabel, sumLabel);
Node statistics2 = createStatisticBox("GeneralAggregatedListBinding", averageLabel2, sumLabel2, failingCountLabel);
VBox root = new VBox(10, tableView, statistics1, statistics2, createButtonBox());
root.setStyle("-fx-padding: 10px;");
Scene scene = new Scene(root);
primaryStage.setTitle("Student Scores Management");
primaryStage.setScene(scene);
primaryStage.sizeToScene();
primaryStage.show();
}
private Node createStatisticBox(String title, Node... children) {
Label titleLabel = new Label(title);
titleLabel.setStyle(" -fx-font-size: 15px;-fx-text-fill: #9a9999");
HBox box = new HBox(10, children);
VBox wrapper = new VBox(15, titleLabel, box);
wrapper.setStyle("-fx-border-color: lightgray; -fx-border-width: 1px; -fx-padding: 10px; -fx-border-radius: 5px;-fx-background-color: white;");
return wrapper;
}
private HBox createButtonBox() {
Button addStudentButton = new Button("Add New Student");
addStudentButton.setOnAction(event -> addNewStudent());
Button removeStudentButton = new Button("Remove Selected Student");
removeStudentButton.setOnAction(event -> removeSelectedStudent());
removeStudentButton.disableProperty().bind(tableView.getSelectionModel().selectedItemProperty().isNull());
Button updateStudentButton = new Button("Update Selected Student");
updateStudentButton.setOnAction(event -> updateSelectedStudentScores());
updateStudentButton.disableProperty().bind(tableView.getSelectionModel().selectedItemProperty().isNull());
return new HBox(10, addStudentButton, removeStudentButton, updateStudentButton);
}
private void initTableView() {
TableColumn nameColumn = new TableColumn<>("Name");
nameColumn.setPrefWidth(100);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
TableColumn scoresColumn = new TableColumn<>("Scores");
scoresColumn.setPrefWidth(280);
scoresColumn.setCellValueFactory(cellData -> new SimpleStringProperty(
cellData.getValue().getScores().stream().map(String::valueOf).collect(Collectors.joining(", "))
));
tableView.getColumns().addAll(nameColumn, scoresColumn);
tableView.setItems(students);
}
private void addNewStudent() {
ObservableList newScores = FXCollections.observableArrayList(randomScore(), randomScore(), randomScore());
students.add(new Student("Student " + (++index), newScores));
}
private void removeSelectedStudent() {
Student selected = tableView.getSelectionModel().getSelectedItem();
if (selected != null) {
students.remove(selected);
}
}
private void updateSelectedStudentScores() {
Student selected = tableView.getSelectionModel().getSelectedItem();
if (selected != null) {
double operation = random.nextInt(0, 3);
if (operation == 0) {
ObservableList newScores = FXCollections.observableArrayList(randomScore(), randomScore(), randomScore());
selected.scores.setAll(newScores);
} else if (operation == 1) {
selected.scores.add(randomScore());
} else {
if (!selected.scores.isEmpty()) {
selected.scores.remove(selected.scores.size() - 1);
} else {
ObservableList newScores = FXCollections.observableArrayList(randomScore());
selected.scores.setAll(newScores);
}
}
tableView.refresh();
}
}
private int randomScore() {
return random.nextInt(0, 50) + 50;
}
public static class Student {
private final SimpleStringProperty name = new SimpleStringProperty();
private final ObservableList scores;
public Student(String name, ObservableList scores) {
this.name.set(name);
this.scores = scores;
}
public String getName() {
return name.get();
}
public SimpleStringProperty nameProperty() {
return name;
}
public ObservableList getScores() {
return scores;
}
}
public static void main(String[] args) {
launch(args);
}
}