Javafx 在不启用setCellSelectionEnabled的情况下更改焦点上的TableCell样式

Javafx 在不启用setCellSelectionEnabled的情况下更改焦点上的TableCell样式,javafx,tableview,fxml,Javafx,Tableview,Fxml,是否有一种方法可以在不使用TableView.getSelectionModel().setCellSelectionEnabled(true)的情况下在TableView中设置TableCell的样式在JavaFX中 我尝试了这个解决方案,但它随机地无法突出显示行 例: tableView.getSelectionModel().setCellSelectionEnabled(true); 最终ObservableSet selectedRowIndexes=FXCollections.Obs

是否有一种方法可以在不使用
TableView.getSelectionModel().setCellSelectionEnabled(true)的情况下在TableView中设置TableCell的样式在JavaFX中

我尝试了这个解决方案,但它随机地无法突出显示行

例:

tableView.getSelectionModel().setCellSelectionEnabled(true);
最终ObservableSet selectedRowIndexes=FXCollections.ObservableSet();
最终伪类selectedRowPseudoClass=PseudoClass.getPseudoClass(“选定行”);

tableView.getSelectionModel().getSelectedCells().addListener((更改好的。因此,只要您的单元格实际获得焦点,为您想要改变样式的列的单元格工厂提供一个自定义的
TableCell
,将允许您监听
TableCell
的任何属性,因为您自己定义了
TableCell
。下面是一个如何监听f的示例查看
表格单元格的ocusedProperty
,并在发生这种情况时更改样式

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();
    }
}
导入javafx.application.application;
导入javafx.beans.property.SimpleStringProperty;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.scene.scene;
导入javafx.scene.control.TableCell;
导入javafx.scene.control.TableColumn;
导入javafx.scene.control.TableView;
导入javafx.scene.layout.BorderPane;
导入javafx.stage.stage;
公共类MCVE3扩展了应用程序{
@凌驾
公众假期开始(阶段){
TableView table=新TableView();
//除非启用单元格选择,否则我不知道如何聚焦单元格。这似乎根本不可能。
table.getSelectionModel().setCellSelectionEnabled(true);
//初始化列并将其添加到表中。
TableColumn col=新的TableColumn(“列”);
col.setCellValueFactory(param->new SimpleStringProperty(param.getValue().get(0));
//初始化列并将其添加到表中。
TableColumn col2=新的TableColumn(“第2列”);
col2.setCellValueFactory(param->newSimpleStringProperty(param.getValue().get(1));
//我们在第二列中添加了一个自定义单元格工厂。这使我们能够自定义单元格的行为。
col2.setCellFactory(e->new FocusStyleCell());
table.getColumns().addAll(col,col2);
//将数据添加到表中。
table.getItems().add(FXCollections.observableArrayList(“一个”、“一个两个”);
table.getItems().add(FXCollections.observableArrayList(“两个”、“两个”);
table.getItems().add(FXCollections.observableArrayList(“三”、“三二”));
table.getItems().add(FXCollections.observearraylist(“Four”、“FourTwo”);
BorderPane视图=新建BorderPane();
视图。设置中心(表);
舞台场景(新场景(视图));
stage.show();
}
/**
*将在焦点上更改样式的自定义TableCell。
*/
类FocusStyleCell扩展了TableCell{
//您总是需要覆盖updateItem。当您这样做时,不要忘记调用super.updateItem,这一点非常重要。
@凌驾
public void updateItem(字符串项,布尔值为空){
super.updateItem(项,空);
如果(项==null | |空){
setText(空);
}否则{
setText(项目);
}
}
公共聚焦细胞(){
//我们向focusedProperty添加一个侦听器。当单元格聚焦时,newValue将为true。
focusedProperty().addListener((obs、旧值、新值)->{
如果(新值){
setStyle(“-fx背景色:黑色;”);
////或添加一些自定义样式类:
//如果(getStyleClass()包含(“聚焦单元格”)){
//getStyleClass().add(“聚焦单元格”);
// }
}否则{
//如果您希望使用样式类,则需要
//一旦焦点丢失,请删除该样式类。
//getStyleClass().remove(“聚焦单元格”);
设置样式(“-fx背景颜色:-fx背景”);
}
});
}
}
公共静态void main(字符串[]args){
发射();
}
}

我无法使用focus listener解决此问题,但可以使用MouseeEvent.MOUSE\u

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;

});
column.setCellFactory(column1->{
TableCell cell=新文本字段TableCell();
cell.addEventFilter(MouseEvent.MOUSE_单击,e->
cell.setStyle(“-fx边框颜色:黑色;-fx背景颜色:#005BD1;-fx文本填充:白色”)
);
cell.addEventFilter(MouseEvent.MOUSE_退出,e->
单元格设置样式(“”)
);
返回单元;
});

完整示例

我不确定我是否理解您希望从示例中得到什么。您是希望始终将样式应用于每个
TableCell
还是仅在选中行时应用样式?选中行时。我通常通过tableView.getFocusModel().getFocusedCell()获取单元格位置但是无法设置样式,因为我无法使TableCell对象对其应用样式类。因此,当选择了
TableRow
时,您希望在
TableRow
中设置一个特定的
TableCell
样式,而不允许
TableCell
本身成为焦点?不,单元格已经处于焦点,我可以获取单元格数据很好,但是我想给它一个不同于行的其他部分的样式/突出显示。除非启用单元格选择,否则单元格无法获得焦点。因此,如果要在不启用单元格选择的情况下聚焦单个单元格,我认为这是不可能的。但是,当其
表行
聚焦时,可以设置
表单元格
的样式。M也许你把条件弄混了。一旦我确定我理解了你的要求,我会很乐意帮助你。也许你可以
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;

});