单击按钮时 JavaFX 更改 Table 行的颜色

JavaFX Change Color of Table Row when Button is clicked

我希望 table 根据是否选中列或单击按钮来更改行的颜色。 我搜索了解决方案,但它从来没有按照我想要的方式工作。我很高兴每一个关键词或帮助你。也许我只是在寻找错误的东西?

我的代码如下所示:

public class Cellexample_presenter implements Initializable{
@FXML 
TableColumn<ExampleData, Boolean> checkcol;
@FXML 
TableView<ExampleData> testtable;

@Override
public void initialize(URL arg0, ResourceBundle arg1) {

    checkcol.setText("Check");
    ObservableList<ExampleData> exList = FXCollections.observableArrayList();
    exList.add(new ExampleData(true));
    exList.add(new ExampleData(false));
    
    checkcol.setCellValueFactory(
            new Callback<CellDataFeatures<ExampleData, Boolean>, ObservableValue<Boolean>>() {
                
                @Override
                public ObservableValue<Boolean> call(CellDataFeatures<ExampleData, Boolean> param) {
                    return param.getValue().checkProperty();
                }
            });

    testtable.setItems(exList);
    testtable.setEditable(true);
    checkcol.setCellFactory(CheckBoxTableCell.forTableColumn(checkcol));
    
    
}

@FXML
private void clicked() {
    ObservableList<ExampleData> tabledata = testtable.getItems();
    for (ExampleData e : tabledata) {
        System.out.println(e.isCheck());
    }
}
}

我找到了另一个 setCellFactory 的解决方案,但是当我已经有一个 setCellFactory 并且我无法合并时,我似乎无法工作。此外,仍然缺少与 Checkbox 的变化。 我遇到的另一个解决方案是 PseudoClass 但这也需要另一个 setCellFactory

method private void clicked()我用来检查我的对象中的数据是否真的被改变了。 我还想作为另一个功能来单击一个按钮并更改包含错误数据的行的颜色。 我希望有一种方法可以遍历 table,检查数据,如果有什么不等于其他东西。它会改变颜色。 在伪代码中像这样

for (tablerow row: table)
     if (row.ischecked()) {
           row.changecolor();
  }

这是将所有内容放在一起的 .FXML:

<?xml version="1.0" encoding="UTF-8"?>

 <?import javafx.scene.control.Button?>
 <?import javafx.scene.control.TableColumn?>
 <?import javafx.scene.control.TableView?>
 <?import javafx.scene.layout.AnchorPane?>
 <?import javafx.scene.layout.Pane?>

 <AnchorPane prefHeight="254.0" prefWidth="700.0" xmlns="http://javafx.com/javafx/11.0.1" 
  xmlns:fx="http://javafx.com/fxml/1" 
  fx:controller="pathToFXML/Cellexample_presenter">
  <children>
  <Pane layoutX="-269.0" prefHeight="315.0" prefWidth="700.0" AnchorPane.bottomAnchor="0.0" 
  AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
     <children>
        <TableView fx:id="testtable" layoutX="142.0" layoutY="27.0" prefHeight="200.0" 
       prefWidth="340.0">
          <columns>
            <TableColumn fx:id="checkcol" prefWidth="75.0" text="C1" />
          </columns>
        </TableView>
        <Button fx:id="checkbtn" layoutX="70.0" layoutY="36.0" mnemonicParsing="false" 
     onAction="#clicked" text="isChecked" />
     </children>
     </Pane>
   </children>
  </AnchorPane>

您可以为此使用自定义 TableRow。我也更喜欢使用 CSS 和 PseudoClasses 来管理行的颜色。

这里需要做的是,行需要知道行当前显示的ExampleData实例中的checked 属性是否发生变化,如果发生变化需要改变颜色发生了。

当然,对于任何给定的 table 行,该 table 行显示的 ExampleData 实例也可能发生变化(例如,如果基础数据列表发生变化,或者如果用户滚动 table,等等)

所以这里的基本策略是:

  1. 创建一个侦听器来观察当前项的 checked 属性,并在出现时更新伪类状态(这反过来会导致样式更改)。在下面的代码中,我将此侦听器称为 checkListener.
  2. 如果行显示的项目发生变化,我们需要停止观察旧项目的 checked 属性 并开始观察新项目的 checked 属性。这可以通过 table 行的 item 属性 上的侦听器来实现。 itemProperty 上的侦听器然后可以从旧项目的 checkedProperty 中删除 checkListener(如果有旧项目),并将其添加到 checkedProperty新项目(如果有的话)。它还需要根据新项目的checkedProperty.
  3. 的当前状态更新伪类状态
@Override
public void initialize(URL arg0, ResourceBundle arg1) {

    // Existing code....

    testTable.setRowFactory(tv -> new TableRow<ExampleData>() {

        private final PseudoClass checkedPC = PseudoClass.getPseudoClass("checked");

        private final ChangeListener<Boolean> checkListener = (obs, wasChecked, isNowChecked) -> 
            pseudoClassStateChanged(checkedPC, isNowChecked);

        {
             itemProperty().addListener((obs, oldItem, newItem) -> {
                 if (oldItem != null) {
                     oldItem.checkedProperty().removeListener(checkListener);
                 }
                 if (newItem == null) {
                     pseudoClassStateChanged(checkedPC, false);
                 } else {
                     pseudoClassStateChanged(checkedPC, newItem.isChecked());
                     newItem.checkedProperty().addListener(checkListener);
                 }
            });
        }
    });
}

然后在您的外部 CSS 文件中包含

.table-row-cell:checked {
    -fx-background-color: red ;
}