JavaFX 2.2 : Styling a table cell and handling row pseudo-classes (hover, selected, etc)

五迷三道 提交于 2019-12-11 04:02:26

问题


I'm working on a JavaFX application which include a TableView with special cell, such that when the data in the cell is invalid, the cell turns red.

That's easy enough with css, but I'm having trouble covering all of the pseudo-classes of the TableCell.

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ReadOnlyBooleanWrapper;
import javafx.beans.property.ReadOnlyIntegerWrapper;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import javafx.util.Callback;

public class Test extends Application {

    public static void main( String[] args ) throws Exception {
        Application.launch( "Sportz Club" );
    }

    @Override
    public void start( Stage stage ) throws Exception {
        TableView<User> table = new TableView<>();
        table.getStylesheets().add(
            this.getClass().getResource( "test.css" ).toExternalForm() );

        final TableColumn<User, String> nameColumn =
        this.<String>unstyledColumn( "name" );
        nameColumn.setText( "Name" );
        table.getColumns().add( nameColumn );

        final TableColumn<User, Integer> numColumn =
        this.<Integer>unstyledColumn( "number" );
        numColumn.setMinWidth(200);
        numColumn.setText( "Number" );
        table.getColumns().add( numColumn );

        final TableColumn<User, Boolean> allowedColumn =
        this.unstyledColumn( "allowed" );
        allowedColumn .setText( "Allowed" );
        allowedColumn .setMinWidth(200);
        allowedColumn .setCellFactory( allowedCellFactory() );
        table.getColumns().add( allowedColumn );

        ObservableList<User> items = FXCollections.observableArrayList();
        items.add( new User( "guy #1", 1, true ) );
        items.add( new User( "guy #2", 2, true ) );
        items.add( new User( "Steve", 3, false ) );
        table.setItems( items );

        stage.setScene( new Scene( table, 500, 500 ) );
        stage.centerOnScreen();
        stage.show();
    }

    private Callback<TableColumn<User, Boolean>, TableCell<User, Boolean>> allowedCellFactory() {
        final Callback<TableColumn<User, Boolean>, TableCell<User, Boolean>> callback =
            new Callback<TableColumn<User, Boolean>, TableCell<User, Boolean>>() {
                @Override
                public TableCell<User, Boolean> call(
                    TableColumn<User, Boolean> arg0 ) {
                    return new TableCell<User, Boolean>() {
                        @Override
                        protected void updateItem( Boolean item, boolean empty ) {
                            super.updateItem( item, empty );
                            if ( item == null || empty ) {
                                return;
                            }
                            if ( item ) {
                                getStyleClass().remove( "invalidCell" );
                            }
                            else {
                                getStyleClass().add( "invalidCell" );
                            }
                            setContentDisplay( ContentDisplay.TEXT_ONLY );
                            setText( item.toString() );
                        };
                    };
                }
            };
        return callback;
    }

    private <S> TableColumn<User, S> unstyledColumn( String name ) {
        TableColumn<User, S> column = new TableColumn<>();
        column.setCellValueFactory( new PropertyValueFactory<User, S>( name ) );
        return column;
    }

    public static class User {

        StringProperty name;
        IntegerProperty number;
        BooleanProperty allowed;

        public User( String name, int number, boolean allowed ) {
            this.name = new ReadOnlyStringWrapper( name );
            this.number = new ReadOnlyIntegerWrapper( number );
            this.allowed = new ReadOnlyBooleanWrapper( allowed );
        }

        public StringProperty nameProperty() {
            return name;
        }

        public IntegerProperty numberProperty() {
            return number;
        }

        public BooleanProperty allowedProperty() {
            return allowed;
        }

    }
}

This is complete code ^ But the point of interest is the allowedCellFactory method, which adds the "invalidCell" style class whenever the value in the cell is false.

Here is the css: (test.css, place in same package as code above)

.invalidCell {
    -fx-background-color: #FFBBBB;
    -fx-text-fill: black !important;
}

.invalidCell:odd {
    -fx-background-color: #FFAAAA;
}

.invalidCell:hover {
    -fx-background-color: #CCAACC;
}

.invalidCell:filled:selected:focused, .invalidCell:filled:selected, .invalidCell:selected  {
-fx-background-insets: 0, 1.4;
-fx-background-color: linear-gradient(from 0% 0% to 0% 100%, #FF6666 0%, #FF2222 100%);
}

.table-view:focused .invalidCell:filled:focused:selected:hover {
    -fx-background: -fx-accent;
    -fx-background-color: yellow;
    -fx-background-insets: 0, 1, 2;
    -fx-text-fill: -fx-selection-bar-text;
}

The problem, as can be seen when running the application is that the "allowed" column does not change style when the rest of the row is hovered. When you hover over the allowed column itself, it changes color to match the :hover pseudoclass.

What I would like for it to do is for the allowed column to change along with all of the other columns when the row is hovered over.

Any ideas?


回答1:


Remove below style code from CSS file

.invalidCell:hover {
   -fx-background-color: #CCAACC;
} 


来源:https://stackoverflow.com/questions/14781861/javafx-2-2-styling-a-table-cell-and-handling-row-pseudo-classes-hover-select

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!