Table 单元格选择关闭 1 个像素

Table cell selection off by 1 pixel

问题

TableView 的单元格选择偏离了 1 个像素。选择包括 bottom/right 网格线,但不包括 top/left 网格线。

这里有一个 CSS 可以使它立即可见

.table-row-cell {
    -fx-background: gray;
}

以下是 Oracle 网站上的一个 JavaFX 示例中 TableView 选择的放大图:

在 Oracle 的示例中,它可能不是很明显,但是如果您选择不同的颜色,那么很明显有些东西发生了变化。

问题

有人知道怎么解决吗?选择应覆盖所有周围的网格线或 none.

代码

示例代码(取自Oracle示例,我只激活了单元格选择):

public class TableViewSample2 extends Application {

    private TableView<Person> table = new TableView<Person>();
    private final ObservableList<Person> data =
        FXCollections.observableArrayList(
            new Person("Jacob", "Smith", "jacob.smith@example.com"),
            new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
            new Person("Ethan", "Williams", "ethan.williams@example.com"),
            new Person("Emma", "Jones", "emma.jones@example.com"),
            new Person("Michael", "Brown", "michael.brown@example.com")
        );

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

        final Label label = new Label("Address Book");
        label.setFont(new Font("Arial", 20));

        table.setEditable(true);

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

        table.getSelectionModel().setCellSelectionEnabled(true);

        final VBox vbox = new VBox();
        vbox.setSpacing(5);
        vbox.setPadding(new Insets(10, 0, 0, 10));
        vbox.getChildren().addAll(label, table);

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

我为此创建了一个issue request

视觉调整以将选择着色放置在单元格网格内

要达到你想要的效果(选择完全在灰色单元格边框内),你可以使用以下css:

.table-cell:selected {
    -fx-border-color: transparent derive(-fx-color,5%) transparent transparent;
    -fx-background-insets: 0 1 1 0, 1 2 2 1, 2 3 3 2;
}

通常选择一行时,右边框设置为选择强调颜色(蓝色),而不是默认的灰色。 derive(-fx-color,5%) 颜色是默认的单元格边框,因此当单元格被选中时,对于更新的 css,我们只保留该颜色。我们实际上不需要设置单元格底部边框(我猜是因为有一个单独的行 css 来处理)。

那么单元格背景需要从右下方(以及聚焦环和聚焦环内的内背景)向内平移一个像素。因此,标准的选定单元格背景颜色从 -fx-background-insets: 0, 1, 2; 的原始形式更改为更新后的形式。

意见

我很确定 table 单元格的渲染是设计使然。 table 视图中的网格线实际上是单元格定义区域的一部分,因此单元格之间没有间距或间隙,也没有单元格重叠。为实现此设计,单元格区域不包括顶线和左线,但包括底线和右线。因此,当单元格被选中并更改颜色以指示它被选中时,您会看到顶部和左侧的网格线,但看不到底部和右侧的网格线。

此外,如果您将选择模式设置为多选(table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);),则选择区域在内部网格选择视觉调整下看起来有点奇怪,因为网格通过多选和选择显示区域不是一种连续的颜色。

I updated the question and added the css where the situation became immediately obvious.

感谢您更新问题以包括颜色更改 css 以使对齐差异更加明显 - 我只是更新了选择颜色并且没有使对齐差异像它一样明显整个 table 单元格背景的颜色变化。