【问题标题】:How to highlight the column that I select through a checkbox in JavaFX如何突出显示我通过 JavaFX 中的复选框选择的列
【发布时间】:2017-01-25 07:50:59
【问题描述】:

我有这样的情况: Example

在我选择一个复选框(一个或多个)的那一刻,我想突出显示相应的列。

我正在尝试这个愚蠢而粗鲁的solution,但它只在列的标题中起作用。

【问题讨论】:

  • 它们是互斥的复选框吗?
  • 不,我可以选择任何复选框。对于每个选中的复选框,我想突出显示其对应的列,对于每个取消选中的复选框,我不想突出显示其对应的列。
  • Checkbox 和 TableColumn 是分开的(看我的错误解决方案)

标签: css checkbox javafx tableview background-color


【解决方案1】:

如果要突出显示整列,则需要在列上使用单元工厂并突出显示单元格。这在本质上类似于JavaFX - Detect & highlight TableColumn being dragged onto,但您需要能够突出显示多个列。为此,请使用ObservableSet<TableColumn<?,?> 跟踪应突出显示的列,并从复选框中添加/删除列。

这是一个示例,改编自上面链接的示例:

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;

import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableSet;
import javafx.collections.SetChangeListener.Change;
import javafx.css.PseudoClass;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;

public class TableColumnHighlightByCheckBox extends Application {

    @Override
    public void start(Stage primaryStage) {
        TableView<Person> table = new TableView<>();
        table.getColumns().add(column("First Name", Person::firstNameProperty));
        table.getColumns().add(column("Last Name", Person::lastNameProperty));
        table.getColumns().add(column("Email", Person::emailProperty));

        ObservableSet<TableColumn<?,?>> highlightColumns = FXCollections.observableSet();

        table.getItems().addAll(createData());

        VBox checkBoxes = new VBox(5);
        checkBoxes.getStyleClass().add("controls");
        table.getColumns().forEach(col -> 
            checkBoxes.getChildren().add(createHighlightColumnCheckBox(col, highlightColumns)));

        table.getColumns().forEach(col -> highlightColumnWhenNeeded(col, highlightColumns));

        BorderPane root = new BorderPane(table);
        root.setTop(checkBoxes);

        Scene scene = new Scene(root, 800, 600);
        scene.getStylesheets().add("style.css");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private <S,T> CheckBox createHighlightColumnCheckBox(TableColumn<S,T> column, ObservableSet<TableColumn<?,?>> highlightColumns) {


        CheckBox checkBox = new CheckBox();
        checkBox.textProperty().bind(column.textProperty());
        checkBox.selectedProperty().addListener((obs, wasSelected, isNowSelected) -> {
            if (isNowSelected) {
                highlightColumns.add(column);
            } else {
                highlightColumns.remove(column);
            }
        });

        return checkBox ;
    }

    private <S,T> void highlightColumnWhenNeeded(TableColumn<S,T> column, ObservableSet<TableColumn<?,?>> highlightColumns) {

        Callback<TableColumn<S,T>, TableCell<S,T>> currentCellFactory = column.getCellFactory() ;

        PseudoClass highlight = PseudoClass.getPseudoClass("highlight");

        column.setCellFactory(tc -> {
            TableCell<S,T> cell = currentCellFactory.call(tc);
            highlightColumns.addListener((Change<? extends TableColumn<?,?>> c) -> 
                    cell.pseudoClassStateChanged(highlight,
                        highlightColumns.contains(column)));

            cell.pseudoClassStateChanged(highlight, highlightColumns.contains(column));

            return cell ;
        });
    }

    private static <S,T> TableColumn<S,T> column(String text, Function<S, ObservableValue<T>> property) {
        TableColumn<S,T> col = new TableColumn<>(text);
        col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
        return col ;
    }

    private List<Person> createData() {
        return Arrays.asList(
                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 class Person {
        private final StringProperty firstName = new SimpleStringProperty();
        private final StringProperty lastName = new SimpleStringProperty();
        private final StringProperty email = new SimpleStringProperty();


        public Person(String firstName, String lastName, String email) {
            setFirstName(firstName);
            setLastName(lastName);
            setEmail(email);
        }


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



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



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



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



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



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



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



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



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



    }

    public static void main(String[] args) {
        launch(args);
    }
}

还有样式表:

.table-cell:highlight {
    -fx-background-color: -fx-background ;
    -fx-background: yellow ;
    -fx-border-color: -fx-table-cell-border-color -fx-table-cell-border-color transparent transparent ;
}
.controls {
    -fx-padding: 10 ;
}

如果它所在的列被突出显示,我只是将整个单元格设置为亮黄色,但是您可以修改样式表以使用您喜欢的任何样式进行突出显示。

【讨论】:

  • 感谢您的解决方案帮助了我和this is my simple solution。我是一个java初学者,你能解释一下你的highlightColumnWhenNeeded方法吗?我不太了解通配符和泛型类型
  • TableColumn&lt;?,?&gt; 仅表示“某些未知类型的 TableColumn”。由于您只是将它们存储在一个集合中,因此您并不关心它们是什么类型,因此保持通用性就可以了。
  • 好的,谢谢!但是有一个问题:选择复选框后,如果我滚动表格视图,某些行将不会突出显示。仅突出显示所有单元格我选择其他复选框...look this video to understand the problem。是fxml还是java代码的布局问题?
  • @giuseppeaccardo 是的,当然:我犯的愚蠢错误。当您滚动时,该列会创建新的单元格,并且这些单元格需要正确设置其样式。在单元工厂中添加了一条额外的线,它应该可以正常工作。
猜你喜欢
  • 1970-01-01
  • 2012-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-26
  • 2012-07-22
  • 2021-08-30
相关资源
最近更新 更多