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 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204
| package tablestyle;
import java.util.Arrays;
import java.util.Optional;
import java.util.stream.IntStream;
import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.css.PseudoClass;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;
import javafx.stage.Stage;
public final class Main extends Application {
private TableView<Person> tableView;
private Editor editor;
@Override
public void start(final Stage primaryStage) throws Exception {
final TableColumn<Person, String> column1 = new TableColumn("Nom");
column1.setCellValueFactory(new PropertyValueFactory<>("name"));
final TableColumn<Person, String> column2 = new TableColumn("Prenom");
column2.setCellValueFactory(new PropertyValueFactory<>("forename"));
tableView = new TableView<>();
tableView.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
tableView.getColumns().setAll(column1, column2);
tableView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
tableView.setRowFactory(table -> new PersonTableRow());
Arrays.asList("Jean Dupont", "Elodie Marchand", "Malick Meoud", "Djibril Masise", "Edouard Berschtein", "Sakura Tarachi", "Meryl Andrew")
.stream()
.map(name -> name.split("\\s+"))
.map(Person::build)
.forEach(tableView.getItems()::add);
editor = new Editor();
editor.personProperty().bind(tableView.getSelectionModel().selectedItemProperty());
final BorderPane root = new BorderPane();
root.setCenter(tableView);
root.setBottom(editor);
final Scene scene = new Scene(root);
Optional.ofNullable(getClass().getResource("style.css"))
.ifPresent(url -> scene.getStylesheets().add(url.toExternalForm()));
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
private class Editor extends GridPane {
private final Label nameLabel = new Label("Nom");
private final TextField nameField = new TextField();
private final Label forenameLabel = new Label("Prenom");
private final TextField forenameField = new TextField();
public Editor() {
getStyleClass().add("editor");
IntStream.range(0, 2)
.mapToObj(column -> {
final ColumnConstraints result = new ColumnConstraints();
result.setFillWidth(true);
result.setHgrow(column == 0 ? Priority.SOMETIMES : Priority.ALWAYS);
return result;
})
.forEach(getColumnConstraints()::add);
IntStream.range(0, 2)
.mapToObj(row -> new RowConstraints())
.forEach(getRowConstraints()::add);
GridPane.setConstraints(nameLabel, 0, 0);
GridPane.setConstraints(nameField, 1, 0);
GridPane.setConstraints(forenameLabel, 0, 1);
GridPane.setConstraints(forenameField, 1, 1);
getChildren().setAll(nameLabel, nameField, forenameLabel, forenameField);
personProperty().addListener(personChangeListener);
}
private final ChangeListener<Person> personChangeListener = (observable, oldValue, newValue) -> {
Optional.ofNullable(oldValue)
.ifPresent(this::uninstallPerson);
Optional.ofNullable(newValue)
.ifPresent(this::installPerson);
};
private void uninstallPerson(final Person person) {
nameField.textProperty().unbindBidirectional(person.nameProperty());
nameField.setText(null);
forenameField.textProperty().unbindBidirectional(person.forenameProperty());
forenameField.setText(null);
}
private void installPerson(final Person person) {
nameField.textProperty().bindBidirectional(person.nameProperty());
forenameField.textProperty().bindBidirectional(person.forenameProperty());
}
private final ObjectProperty<Person> person = new SimpleObjectProperty<>(this, "person");
public final Person getPerson() {
return person.get();
}
public final void setPerson(Person value) {
person.set(value);
}
public final ObjectProperty personProperty() {
return person;
}
}
public static class Person {
public static Person build(final String[] values) {
final Person result = new Person();
result.setName(values[1]);
result.setForename(values[0]);
return result;
}
private final StringProperty name = new SimpleStringProperty(this, "name");
public final String getName() {
return name.get();
}
public final void setName(String value) {
name.set(value);
}
public final StringProperty nameProperty() {
return name;
}
private final StringProperty forename = new SimpleStringProperty(this, "forname");
public final String getForename() {
return forename.get();
}
public final void setForename(String value) {
forename.set(value);
}
public final StringProperty forenameProperty() {
return forename;
}
}
private static class PersonTableRow extends TableRow<Person> {
private static final PseudoClass E_PSEUDO_CLASS = PseudoClass.getPseudoClass("E");
public PersonTableRow() {
getStyleClass().add("person-row");
}
private Person oldItem;
@Override
protected void updateItem(Person item, boolean empty) {
super.updateItem(item, empty);
if (oldItem != item) {
Optional.ofNullable(oldItem)
.ifPresent(this::uninstallPerson);
Optional.ofNullable(item)
.ifPresent(this::installPerson);
oldItem = item;
}
}
private void uninstallPerson(final Person person) {
person.forenameProperty().removeListener(forenameChangeListener);
applyStyleChange(null);
}
private void installPerson(final Person person) {
person.forenameProperty().addListener(forenameChangeListener);
applyStyleChange(person.getForename());
}
private final ChangeListener<String> forenameChangeListener = (observable, oldValue, newValue) -> applyStyleChange(newValue);
private void applyStyleChange(final String value) {
final boolean styleEnabled = value != null && value.startsWith("E");
pseudoClassStateChanged(E_PSEUDO_CLASS, styleEnabled);
}
}
} |
Partager