在没有setCellSelectionEnabled的情况下更改焦点上的TableCell样式

时间:2016-06-13 21:15:15

标签: javafx tableview fxml

有没有办法在没有tableView.getSelectionModel().setCellSelectionEnabled(true);的JavaFX中的TableView中设置TableCell的样式?

我尝试了这个解决方案https://community.oracle.com/thread/3528543?start=0&tstart=0,但随机无法突出显示行

例如:

    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;
    });

2 个答案:

答案 0 :(得分:0)

好。因此,只要您的单元格实际获得焦点,向列的单元格工厂提供自定义TableCell,您希望以不同的方式设置样式,这样您就可以收听TableCell的任何属性,因为您是自己定义TableCell。下面是一个关于如何监听TableCell的focusedProperty并在发生这种情况时更改样式的示例。

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();
    }
}

答案 1 :(得分:0)

我无法使用焦点侦听器解决它,但可以使用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;

});

完整示例https://github.com/gadelkareem/aws-client/blob/master/src/main/java/com/gadelkareem/awsclient/application/Controller.java#L443