Programmgesteuert das Aussehen der TableView-Zeile ändern
Nachdem ich ein Oracle tutorial über den TableViewich Frage mich, ob es gibt eine Möglichkeit, programmgesteuert auf unterschiedliche CSS-Stil auf den ausgewählten TableView Zeile. Zum Beispiel, Benutzer wählt eine bestimmte Zeile, klickt auf den "Markieren" - Taste und die ausgewählte Zeile wird brauner hintergrund, weißer text, füllen, etc. Ich habe gelesen, die JavaFX tableview FarbenAktualisierung TableView Zeile Aussehen und Hintergrund mit 2 Farben in JavaFX?aber ohne Erfolg =/
Hier ist die Quelle:
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Group;
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.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class TableViewSample extends Application {
private TableView<Person> table = new TableView<Person>();
private final ObservableList<Person> data =
FXCollections.observableArrayList(
new Person("Jacob", "Smith", "[email protected]"),
new Person("Isabella", "Johnson", "[email protected]"),
new Person("Ethan", "Williams", "[email protected]"),
new Person("Emma", "Jones", "[email protected]"),
new Person("Michael", "Brown", "[email protected]")
);
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(450);
stage.setHeight(600);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
TableColumn firstNameCol = new TableColumn("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("firstName"));
TableColumn lastNameCol = new TableColumn("Last Name");
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("lastName"));
TableColumn emailCol = new TableColumn("Email");
emailCol.setMinWidth(200);
emailCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("email"));
table.setItems(data);
table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
final Button btnHighlight = new Button("Highlight selected row");
btnHighlight.setMaxWidth(Double.MAX_VALUE);
btnHighlight.setPrefHeight(30);
btnHighlight.setOnAction(new EventHandler<ActionEvent>(){
public void handle(ActionEvent e){
//this is where the CSS should be applied
}
});
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(label, table, btnHighlight);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty email;
private Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
}
}
Und die Anwendung.cssaus denen das "Highlight selected row" - Schaltfläche wendet die highlightedRow-Klasse, um die ausgewählte Zeile in der Tabelle:
.highlightedRow {
-fx-background-color: brown;
-fx-background-insets: 0, 1, 2;
-fx-background: -fx-accent;
-fx-text-fill: -fx-selection-bar-text;
}
Edit:
Nachdem mehrere Stunden zu versuchen, das beste was ich tun konnte, ist diese mithilfe des folgenden Codes:
firstNameCol.setCellFactory(new Callback<TableColumn<Person, String>, TableCell<Person, String>>() {
@Override
public TableCell<Person, String> call(TableColumn<Person, String> personStringTableColumn) {
return new TableCell<Person, String>() {
@Override
protected void updateItem(String name, boolean empty) {
super.updateItem(name, empty);
if (!empty) {
if (name.toLowerCase().startsWith("e") || name.toLowerCase().startsWith("i")) {
getStyleClass().add("highlightedRow");
}
setText(name);
} else {
setText("empty"); //for debugging purposes
}
}
};
}
});
Den Teil, den ich nicht wirklich verstehe, ist, warum ich das nicht kann, aus dem inneren der setOnAction
Methode der btnHighlight
? Ich habe auch versucht, aktualisieren der Tabelle danach (hier beschrieben), aber es schien nicht zu funktionieren. Auch meine "Lösung" funktioniert nur bei den firstNameCol
Spalte, so muss man haben, um neue zellfabrik für jede Spalte, um einen bestimmten Stil, oder gibt es eine intelligentere Lösung?
InformationsquelleAutor der Frage E. Normous | 2013-12-03
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie nicht möchten, dass die Wiederverwendbarkeit der Lösung, die ich oben gepostet, das ist wirklich die gleiche Sache, aber über eine anonyme innere Klasse für die Zeile Fabrik statt eine eigenständige Klasse. Vielleicht ist der code leichter zu Folgen, wie es ist alles an einem Ort. Es ist eine Art hybrid zwischen Jonathan Lösung und mir, sondern wird automatisch aktualisiert, highlights, ohne dass es mit einer Art.
Habe ich eine Liste von Integer-zahlen, so dass es unterstützt mehrere Auswahl, aber wenn Sie nicht brauchen, dass Sie offensichtlich verwenden Sie einfach einen IntegerProperty statt.
Hier ist die Reihe Werk:
Und hier sind, was einige Schaltflächen Aussehen könnte:
InformationsquelleAutor der Antwort James_D
Wie über das erstellen einer Reihe-Fabrik, die stellt eine beobachtbare Liste der Indizes der Zeilen, die hervorgehoben werden sollen? So können Sie einfach aktualisieren Sie die Liste mit den Indizes, die Sie brauchen, um zu markieren: zum Beispiel durch aufrufen der getSelectedIndices() auf die Auswahl-Modell und der übergabe an die Liste der setAll (...) - Methode.
Diese könnte ungefähr so Aussehen:
Können Sie jetzt tun,
- Und in deiner button-Aktion-handler tun
Weil StyleChangingRowFactory wraps eine weitere Zeile der Fabrik, können Sie immer noch verwenden, wenn Sie bereits eine benutzerdefinierte Zeile factory-Implementierung, die Sie verwenden möchten. Zum Beispiel:
Hier ist ein komplettes code-Beispiel.
InformationsquelleAutor der Antwort James_D
Hier ist ein hässlicher hack, Lösung. Erstens, definieren Sie ein int-Feld namens highlightedRow. Legen Sie dann eine Zeile, die Fabrik auf dem TableView:
Dann fügen Sie den folgenden code in der Schaltfläche auf die Aktion (und das ist, wo die hässlichen hack ins Spiel kommt):
Sobald dies geschehen ist, erhalten Sie den braunen Markierung auf die markierte Zeile. Man könnte natürlich einfach die Unterstützung von mehreren braunen highlights durch den Austausch der int mit einer Liste von Netzwerken.
InformationsquelleAutor der Antwort Jonathan Giles
Der beste Weg finde ich, um dies zu tun:
In meiner CSS -
In meiner Tabelle Initialisierung mit einem SimpleBooleanProperty eines Objekts Inhalt in meiner ObservableList:
Code Anpassung von das vollständige Beispiel
InformationsquelleAutor der Antwort negstek
Vielleicht habe ich etwas gefunden, das funktioniert:
Mit dieser code Hinzugefügt, wenn Sie die Taste drücken Sie die hervorgehobene Zeile die Farbe ändert, wenn Sie wählen Sie eine andere Zeile wechselt die Farbe wieder auf default, wenn Sie die Taste erneut drücken, ändert sich die Farbe der neuen Zeile zu Braun.
css:
Einzige problem bei dieser Lösung ist, dass, wenn Sie drücken Sie die Taste zweimal hintereinander, wird der nächste ausgewählte Zeile ist bereits Braun. Sie müssten verwenden Sie eine separate css-Datei, sonst beim Start der Anwendung keine css-Regeln werden angewendet, bis Sie die Taste drücken.
InformationsquelleAutor der Antwort WonderWorld
Fand ich, dass die beste Lösung wäre, zu hören für Zeile.itemProperty() ändert sich, weil wenn Sie die Sortierreihenfolge für das Beispiel der Zeilen ändern, Indizes, also Zeilen erhalten Sie automatisch benachrichtigt.
InformationsquelleAutor der Antwort michael laudrup