Skip to content

Instantly share code, notes, and snippets.

@james-d
Created June 12, 2014 11:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save james-d/523831d5921fbe15824d to your computer and use it in GitHub Desktop.
Save james-d/523831d5921fbe15824d to your computer and use it in GitHub Desktop.
.table-row-cell:new {
-fx-background-color: darkseagreen ;
}
import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
import javafx.css.PseudoClass;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.stage.Stage;
import javafx.util.Duration;
public class HighlightNewTableRows extends Application {
@Override
public void start(Stage primaryStage) {
TableView<Person> table = new TableView<>();
table.getItems().addAll(
new Person("Jacob", "Smith", "jacob.smith@example.com"),
new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
new Person("Ethan", "Williams", "ethan.williams@example.com"),
new Person("Emma", "Jones", "emma.jones@example.com"),
new Person("Michael", "Brown", "michael.brown@example.com")
);
table.getColumns().addAll(Arrays.asList(
createTableColumn("First Name", Person::firstNameProperty, 150),
createTableColumn("Last Name", Person::lastNameProperty, 150),
createTableColumn("Email", Person::emailProperty, 150)
));
BorderPane newPersonPane = createEditor(table.getItems());
final Duration timeToGetOld = Duration.seconds(1.0);
final ObjectProperty<Person> recentlyAddedPerson = new SimpleObjectProperty<>();
table.getItems().addListener((Change<? extends Person> change) -> {
while (change.next()) {
if (change.wasAdded()) {
List<? extends Person> addedPeople = change.getAddedSubList();
Person lastAddedPerson = addedPeople.get(addedPeople.size()-1);
recentlyAddedPerson.set(lastAddedPerson);
// set back to null after a short delay, unless changed since then:
PauseTransition agingTime = new PauseTransition(timeToGetOld);
agingTime.setOnFinished(event -> {
if (recentlyAddedPerson.get() == lastAddedPerson) {
recentlyAddedPerson.set(null);
}
});
agingTime.play();
}
}
});
final PseudoClass newPersonPseudoClass = PseudoClass.getPseudoClass("new");
table.setRowFactory(tableView -> new TableRow<Person>() {
// Bindings API uses weak listeners, so this needs to be a field to
// make sure it stays in scope as long as the TableRow is in scope.
private final BooleanBinding itemIsNewPerson
= Bindings.isNotNull(itemProperty())
.and(Bindings.equal(itemProperty(), recentlyAddedPerson));
{
// anonymous constructor:
itemIsNewPerson.addListener((obs, wasNew, isNew)
-> pseudoClassStateChanged(newPersonPseudoClass, isNew));
}
});
BorderPane root = new BorderPane();
root.setCenter(table);
root.setBottom(newPersonPane);
Scene scene = new Scene(root,600,400);
scene.getStylesheets().add(getClass().getResource("highlight-new-table-rows.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
private BorderPane createEditor(ObservableList<Person> items) {
GridPane newPersonEditor = new GridPane();
TextField firstNameTF = new TextField();
TextField lastNameTF = new TextField();
TextField emailTF = new TextField();
newPersonEditor.addRow(0, new Label("First Name:"), firstNameTF);
newPersonEditor.addRow(1, new Label("Last Name:"), lastNameTF);
newPersonEditor.addRow(2, new Label("Email Name:"), emailTF);
ColumnConstraints leftCol = new ColumnConstraints();
leftCol.setHalignment(HPos.RIGHT);
leftCol.setHgrow(Priority.NEVER);
ColumnConstraints rightCol = new ColumnConstraints();
rightCol.setHalignment(HPos.LEFT);
rightCol.setHgrow(Priority.ALWAYS);
newPersonEditor.getColumnConstraints().addAll(leftCol, rightCol);
Button addButton = new Button("Add");
Button clearButton = new Button("Clear");
List<TextField> fields = Arrays.asList(firstNameTF, lastNameTF, emailTF);
clearButton.setOnAction(event -> fields.forEach(TextField::clear));
addButton.setOnAction(event -> {
items.add(new Person(firstNameTF.getText(), lastNameTF.getText(), emailTF.getText()));
fields.forEach(TextField::clear);
});
HBox buttons = new HBox(5, addButton, clearButton);
buttons.setAlignment(Pos.CENTER);
return new BorderPane(newPersonEditor, null, null, buttons, null);
}
private <S,T> TableColumn<S, T> createTableColumn(String title, Function<S, Property<T>> accessor, double width) {
TableColumn<S, T> col = new TableColumn<>(title);
col.setCellValueFactory(data -> accessor.apply(data.getValue()));
col.setPrefWidth(width);
return col ;
}
public static class Person {
private final StringProperty firstName;
private final StringProperty lastName;
private final StringProperty email;
private Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(this, "firstName", fName);
this.lastName = new SimpleStringProperty(this, "lastName", lName);
this.email = new SimpleStringProperty(this, "email", email);
}
public final String getFirstName() {
return firstName.get();
}
public final void setFirstName(String fName) {
firstName.set(fName);
}
public StringProperty firstNameProperty() {
return firstName ;
}
public final String getLastName() {
return lastName.get();
}
public final void setLastName(String fName) {
lastName.set(fName);
}
public StringProperty lastNameProperty() {
return lastName ;
}
public final String getEmail() {
return email.get();
}
public final void setEmail(String fName) {
email.set(fName);
}
public StringProperty emailProperty() {
return email ;
}
}
public static void main(String[] args) {
launch(args);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment