首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JavaFX如何在鼠标悬停到列时突出显示TableColumn而不是TableRow

JavaFX如何在鼠标悬停到列时突出显示TableColumn而不是TableRow
EN

Stack Overflow用户
提问于 2015-01-05 14:52:12
回答 2查看 1.8K关注 0票数 0

当鼠标位于该列的顶部时,我试图找到一个突出显示表格列的解决方案,但我未能找到解决方案。有人已经找到解决办法了吗?我已经尝试过使用ScenicView来查看css和组件,但这并没有多大帮助。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-01-05 17:37:50

如果您使用的是Java 8,则可以使用CSS伪类很好地完成这一任务。CSS伪类的性能非常好(至少,它是更改JavaFX控件样式的最快方法),而且由于表视图只创建少量的表单元格,即使对于非常大的数据集,这应该会执行得很好。

定义一个外部css类,该类设置具有自定义伪类的表单元格的样式,如下所示:

代码语言:javascript
运行
复制
.table-cell:column-hover {
    -fx-background-color: -fx-cell-focus-inner-border, -fx-selection-bar  ;
    -fx-background-insets: 0, 0 0 1 0 ;
    -fx-background: -fx-selection-bar ;
}

(这里的-fx-background-color实际上改变了背景颜色:-fx-background只是确保文本填充相对于背景保持合适颜色的一个技巧。)

现在,为每一列定义一个布尔属性。为每一列创建一个单元格工厂,当鼠标在单元格上移动时将布尔属性设置为true,并在鼠标移动时将其设置为false。让每个单元格观察布尔属性,并在变化时为单元格设置伪类状态。

下面是一个示例,使用来自Person的常用标准教程表。有趣的代码在createCol(...)方法中:

代码语言:javascript
运行
复制
import java.util.function.Function;

import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.css.PseudoClass;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class TableViewTest extends Application {

    private static final PseudoClass COLUMN_HOVER_PSEUDO_CLASS = PseudoClass.getPseudoClass("column-hover");

    @Override
    public void start(Stage primaryStage) {
        TableView<Person> table = new TableView<>();
        TableColumn<Person, String> firstNameCol = createCol("First Name", Person::firstNameProperty, 150);
        TableColumn<Person, String> lastNameCol = createCol("Last Name", Person::lastNameProperty, 150);
        TableColumn<Person, String> emailCol = createCol("Email", Person::emailProperty, 200);

        table.getItems().addAll(
            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")
        );

        table.getColumns().add(firstNameCol);
        table.getColumns().add(lastNameCol);
        table.getColumns().add(emailCol);

        VBox root = new VBox(15, table);
        root.setAlignment(Pos.CENTER);
        Scene scene = new Scene(root, 800, 600);

        scene.getStylesheets().add("table-column-hover.css");

        primaryStage.setScene(scene);
        primaryStage.show();
    }


    private TableColumn<Person, String> createCol(String title, 
            Function<Person, ObservableValue<String>> mapper, double size) {

        TableColumn<Person, String> col = new TableColumn<>(title);

        col.setCellValueFactory(cellData -> mapper.apply(cellData.getValue()));

        // Is the column being hovered over with the mouse?
        BooleanProperty columnHover = new SimpleBooleanProperty();

        col.setCellFactory(column -> {

            // basic table cell:
            TableCell<Person, String> cell = new TableCell<Person, String>() ;
            cell.textProperty().bind(cell.itemProperty());

            // when the mouse hovers over the cell, set the columnHover to indicate 
            // the mouse is over the column:
            cell.hoverProperty().addListener((obs, wasHovered, isNowHovered) -> {
                columnHover.set(isNowHovered);
            });

            // update the column-hover pseudoclass state for this cell when the column is hovered over
            // note this will activate the pseudoclass when the mouse is over any cell in this column
            columnHover.addListener((obs, columnWasHovered, columnIsNowHovered) -> 
                cell.pseudoClassStateChanged(COLUMN_HOVER_PSEUDO_CLASS, columnIsNowHovered)
            );

            return cell ;
        });

        col.setPrefWidth(size);

        return col ;
    }

    public class Person {
        private final StringProperty firstName = new SimpleStringProperty(this, "firstName");
        private final StringProperty lastName = new SimpleStringProperty(this, "lastName");
        private final StringProperty email = new SimpleStringProperty(this, "email");

        public Person(String firstName, String lastName, String email) {
            this.firstName.set(firstName);
            this.lastName.set(lastName);
            this.email.set(email);
        }

        public final StringProperty firstNameProperty() {
            return this.firstName;
        }

        public final java.lang.String getFirstName() {
            return this.firstNameProperty().get();
        }

        public final void setFirstName(final java.lang.String firstName) {
            this.firstNameProperty().set(firstName);
        }

        public final StringProperty lastNameProperty() {
            return this.lastName;
        }

        public final java.lang.String getLastName() {
            return this.lastNameProperty().get();
        }

        public final void setLastName(final java.lang.String lastName) {
            this.lastNameProperty().set(lastName);
        }

        public final StringProperty emailProperty() {
            return this.email;
        }

        public final java.lang.String getEmail() {
            return this.emailProperty().get();
        }

        public final void setEmail(final java.lang.String email) {
            this.emailProperty().set(email);
        }

    }

    public static void main(String[] args) {
        launch(args);
    }
}
票数 0
EN

Stack Overflow用户

发布于 2015-01-05 15:49:08

我想只有在许多“黑客”的情况下才能做到这一点。

TableColumn只存在于TableView的数据模型中,基于该模型呈现的视图部分被呈现为行而不是列。因此,每个TableCell都有一个表行作为父列,而不是一个表列。

如果它是以相反的方式实现的,表就会呈现在列中,我们可以很容易地做到这一点。

现在,如果您真的想要这样做,您必须执行以下操作:

  1. 编写自定义TableCell并将其注册为所有列的CellRenderer。
  2. 如果您的自定义单元格被悬停,请检索其列,并通知位于同一列中的所有其他单元格。

但是:--如果表变大和/或运行应用程序的计算机速度慢,这将减慢应用程序的速度。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27781987

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档