1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
| package test.table.radio;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.StringBinding;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.CheckBoxTableCell;
import javafx.stage.Stage;
import javafx.util.Pair;
import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public final class Main extends Application {
public static void main(String... args) {
launch(args);
}
private boolean defaultRiskAdjusting = false;
@Override
public void start(final Stage stage) throws Exception {
final int maxRisks = 50;
final var risks = IntStream.range(0, maxRisks)
.mapToObj(index -> new Risk(String.format("risk %d", index + 1), 10 * Math.random(), false))
.collect(Collectors.toUnmodifiableList());
///////////
final var nameColumn = new TableColumn<Risk, String>("Name");
nameColumn.setCellValueFactory(feature -> feature.getValue().nameProperty());
final var riskValueColumn = new TableColumn<Risk, Double>("Risk Value");
riskValueColumn.setCellValueFactory(feature -> feature.getValue().riskValueProperty());
final var defaultRiskColumn = new TableColumn<Risk, Boolean>("Default Risk");
defaultRiskColumn.setEditable(true);
defaultRiskColumn.setCellValueFactory(feature -> feature.getValue().defaultRiskProperty());
defaultRiskColumn.setCellFactory(CheckBoxTableCell.forTableColumn(defaultRiskColumn));
final var tableView = new TableView<Risk>();
tableView.setEditable(true);
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
tableView.getColumns().setAll(nameColumn, riskValueColumn, defaultRiskColumn);
tableView.getItems().setAll(risks);
final var listenersToRemoveLater = risks.stream()
.map(risk -> {
final ChangeListener<Boolean> changeListener = (observable, oldValue, newValue) -> {
System.out.printf("%s %b -> %b%n", risk.nameProperty().get(), oldValue, newValue);
if (!defaultRiskAdjusting && newValue) {
defaultRiskAdjusting = true;
try {
risks.stream()
.filter(r -> r != risk)
.forEach(r -> r.defaultRiskProperty().set(false));
} finally {
defaultRiskAdjusting = false;
}
}
};
risk.defaultRiskProperty().addListener(changeListener);
return new Pair<>(risk, changeListener);
})
.collect(Collectors.toUnmodifiableList());
///////////
final var listView = new ListView<Risk>();
listView.getItems().setAll(risks);
listView.setCellFactory(lv -> new ListCell<>() {
@Override
protected void updateItem(final Risk item, final boolean empty) {
super.updateItem(item, empty);
if (!empty && Objects.nonNull(item)) {
textProperty().bind(Bindings.format("%s - %b", item.nameProperty(), item.defaultRiskProperty()));
styleProperty().bind(new StringBinding() {
{
bind(item.defaultRiskProperty());
}
@Override
public void dispose() {
super.dispose();
unbind(item.defaultRiskProperty());
}
@Override
protected String computeValue() {
return (item.defaultRiskProperty().get()) ? "-fx-font-weight: bold;" : null;
}
});
} else {
textProperty().unbind();
setText(null);
styleProperty().unbind();
setStyle(null);
}
}
});
///////////
final var textArea = new TextArea();
FXCollections.observableList(risks, risk -> new Observable[]{risk.defaultRiskProperty()})
.addListener((ListChangeListener<Risk>) change -> {
while (change.next()) {
String changeLabel = "?"; // NOI18N.
if (change.wasReplaced()) {
changeLabel = "replaced"; // NOI18N.
} else if (change.wasAdded()) {
changeLabel = "added"; // NOI18N.
} else if (change.wasRemoved()) {
changeLabel = "removed"; // NOI18N.
} else if (change.wasPermutated()) {
changeLabel = "permutated"; // NOI18N.
} else if (change.wasUpdated()) {
changeLabel = "updated"; // NOI18N.
}
final var pattern = String.format("Element %s was %s%n", "%d", changeLabel); // NOI18N.
final var builder = new StringBuilder(textArea.getText());
if (change.wasAdded() || change.wasReplaced() || change.wasUpdated()) {
for (int index = change.getFrom(); index < change.getTo(); index++) {
builder.append(String.format(pattern, index));
}
} else {
for (int index = change.getFrom(); index <= change.getTo(); index++) {
builder.append(String.format(pattern, index));
}
}
final String text = builder.toString();
textArea.setText(text);
}
});
///////////
final var root = new SplitPane(tableView, listView, textArea);
final var scene = new Scene(root);
stage.setWidth(800);
stage.setHeight(600);
stage.setTitle("Test");
stage.setScene(scene);
stage.show();
Platform.runLater(() -> root.setDividerPositions(0.33d, 0.66d));
}
} |
Partager