1

Is there a way to style a TableCell in a TableView without tableView.getSelectionModel().setCellSelectionEnabled(true); in JavaFX?

I tried this solution https://community.oracle.com/thread/3528543?start=0&tstart=0 but it randomly fails to highlight the row

ex:

 tableView.getSelectionModel().setCellSelectionEnabled(true); final ObservableSet<Integer> selectedRowIndexes = FXCollections.observableSet(); final PseudoClass selectedRowPseudoClass = PseudoClass.getPseudoClass("selected-row"); tableView.getSelectionModel().getSelectedCells().addListener((Change<? extends TablePosition> change) -> { selectedRowIndexes.clear(); tableView.getSelectionModel().getSelectedCells().stream().map(TablePosition::getRow).forEach(row -> { selectedRowIndexes.add(row); }); }); tableView.setRowFactory(tableView -> { final TableRow<List<StringProperty>> row = new TableRow<>(); BooleanBinding selectedRow = Bindings.createBooleanBinding(() -> selectedRowIndexes.contains(row.getIndex()), row.indexProperty(), selectedRowIndexes); selectedRow.addListener((observable, oldValue, newValue) -> { row.pseudoClassStateChanged(selectedRowPseudoClass, newValue); } ); return row; }); 
9
  • I'm not sure I understand what you want from your example. Do you just want a style to be applied to each TableCell always, or just when the row gets selected? Commented Jun 14, 2016 at 9:27
  • When the row is selected. I usually get the cell position through tableView.getFocusModel().getFocusedCell() but can not style it as I can not get the TableCell object to apply a style class to it. Commented Jun 14, 2016 at 9:44
  • So you want to style one specific TableCell in a TableRow when the TableRow is selected, without allowing the TableCell itself to become focused? Commented Jun 14, 2016 at 9:53
  • No, the cell is already on focus and I can get the cell data easily but I want to give it a different style/highlight than the rest of the row. Commented Jun 14, 2016 at 10:57
  • Well a cell can't get focus unless you enable cell selection. So if you want to focus a single cell without enabling cell selection, I don't think that's possible. But it is possible to style a TableCell when its TableRow is getting focused. Maybe you have mixed the terms up. Once I'm sure I understand what you're asking for I'll be happy to help you. Maybe you can edit your question to clarify your issue. Commented Jun 14, 2016 at 15:50

2 Answers 2

1

Okay. So as long as your cell actually gets the focus, providing a custom TableCell to the cell factory of the column you want to style differently will allow you to listen to any property of the TableCell, since you are defining that TableCell yourself. Below is an example on how to listen to the focusedProperty of the TableCell and change the style when that happens.

import javafx.application.Application; import javafx.beans.property.SimpleStringProperty; import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.scene.Scene; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.layout.BorderPane; import javafx.stage.Stage; public class MCVE3 extends Application { @Override public void start(Stage stage) { TableView<ObservableList<String>> table = new TableView<ObservableList<String>>(); // I have no idea how to get focus on a cell unless you enable cell selection. It does not seem to be possible at all. table.getSelectionModel().setCellSelectionEnabled(true); // Initializes a column and adds it to the table. TableColumn<ObservableList<String>, String> col = new TableColumn<ObservableList<String>, String>("Column"); col.setCellValueFactory(param -> new SimpleStringProperty(param.getValue().get(0))); // Initializes a column and adds it to the table. TableColumn<ObservableList<String>, String> col2 = new TableColumn<ObservableList<String>, String>("Column 2"); col2.setCellValueFactory(param -> new SimpleStringProperty(param.getValue().get(1))); // We add a custom cell factory to second column. This enables us to customize the behaviour of the cell. col2.setCellFactory(e -> new FocusStyleCell()); table.getColumns().addAll(col, col2); // Add data to the table. table.getItems().add(FXCollections.observableArrayList("One", "OneTwo")); table.getItems().add(FXCollections.observableArrayList("Two", "TwoTwo")); table.getItems().add(FXCollections.observableArrayList("Three", "ThreeTwo")); table.getItems().add(FXCollections.observableArrayList("Four", "FourTwo")); BorderPane view = new BorderPane(); view.setCenter(table); stage.setScene(new Scene(view)); stage.show(); } /** * A custom TableCell that will change style on focus. */ class FocusStyleCell extends TableCell<ObservableList<String>, String> { // You always need to override updateItem. It's very important that you don't forget to call super.updateItem when you do this. @Override public void updateItem(String item, boolean empty) { super.updateItem(item, empty); if (item == null || empty) { setText(null); } else { setText(item); } } public FocusStyleCell() { // We add a listener to the focusedProperty. newValue will be true when the cell gets focused. focusedProperty().addListener((obs, oldValue, newValue) -> { if (newValue) { setStyle("-fx-background-color: black;"); // // Or add some custom style class: // if (getStyleClass().contains("focused-cell")) { // getStyleClass().add("focused-cell"); // } } else { // If you instead wish to use style classes you need to // remove that style class once focus is lost. // getStyleClass().remove("focused-cell"); setStyle("-fx-background-color: -fx-background"); } }); } } public static void main(String[] args) { launch(); } } 
Sign up to request clarification or add additional context in comments.

Comments

0

I could not solve it using focus listener but it is possible using a MouseEvent.MOUSE_CLICKED

column.setCellFactory(column1 -> { TableCell<List<StringProperty>, String> cell = new TextFieldTableCell<>(); cell.addEventFilter(MouseEvent.MOUSE_CLICKED, e -> cell.setStyle("-fx-border-color:black black black black;-fx-background-color:#005BD1;-fx-text-fill:white") ); cell.addEventFilter(MouseEvent.MOUSE_EXITED, e -> cell.setStyle("") ); return cell; }); 

Full example https://github.com/gadelkareem/aws-client/blob/master/src/main/java/com/gadelkareem/awsclient/application/Controller.java#L443

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.