TableColumn.setStyle() 在 setOnEditCommit(...) 中不起作用

问题描述 投票:0回答:1

在 TableColumn 的 setOnEditCommit() 方法中,我尝试更改单元格文本的颜色,但没有效果。 它是只有一行的 TableView。这里是我的代码...我做错了什么?

columnnumberofsession.setOnEditCommit(event -> {
    try {
        ffnumberofsession.checkValue(event.getNewValue());
    }
    catch(IllegalArgumentException iae) {
        System.err.println("The value for number of session is invalid !");

        event.getTableColumn().setStyle("-fx-text-fill: red;");
        return;
    }

    event.getTableColumn().setStyle("-fx-text-fill: black;");
    System.out.println("Value is correct.");
});

我尝试了回调之外的方法,效果很好。文本颜色发生变化,但这是静态测试。我希望当我发现错误时单元格文本的颜色变成红色。我不明白为什么它在 setOnEditCommit() 中不起作用。

javafx tableview tablecolumn
1个回答
0
投票

你做错了什么

我不太确定,但另一方面我也不确定为什么你所做的事情会起作用。

我尝试更改单元格文本的颜色

不,你不知道,我的意思是不直接。

您致电:

event.getTableColumn().setStyle("-fx-text-fill: red;") 

更改列的填充样式,而不是单元格的填充样式。

柱子与单元格不同。

我确实尝试过测试这个,如果你有一个

TableView
和一个
TableColumn
对象并且你调用:

myTableColumn.setStyle("-fx-text-fill: red;");

在列上,它将将该列中单元格中的所有标签(但不是表标题)的样式更改为红色。

这与编辑无关,与 Estienne 提到时所说的相符

我尝试了回调之外的方法,效果很好。

我只是不知道它是如何以及为什么有效的。据我所知,通过对列进行样式设置来设置表格单元格样式的行为并未记录在 CSS 参考指南中。

您的方法可能出了什么问题

通常,在

TableView
中进行编辑时,单元实现涉及多个节点,并且节点根据单元是否正在编辑而切换进出视图。这可能会干扰通过在列上设置样式来设置文本单元格填充样式的未记录行为。但这只是我的猜测。

建议的方法

通常对于这些状态更改样式,与其直接在代码中设置样式,不如将样式类(或伪类)与定义了适当规则的样式表一起应用和删除,这是更好的做法,更可配置且更健壮。

例如,在单元格的 updateItem 中,检查会话是否无效,如果是,请确保单元格具有 session-invalid 样式类,否则确保它没有。

然后在 CSS 样式表中定义会话无效样式类的样式。您可能需要可观察项目列表上的提取器才能触发更新。

如有必要,可以为支持 TableView 的项目定义一个单独的属性(如果整个 TableView 的状态受到影响,则可以定义一个全局属性),并且该属性可以指示更新项目时要应用的样式。在这种情况下,可能不需要附加属性,因为可以在 updateItem 中执行验证检查。

演示建议方法的示例片段

CSS 样式(您可以在外部样式表中定义它,我只是内联定义它以减少文件):

公共静态最终字符串INVALID_STYLECLASS =“无效”; 公共静态最终字符串CSS_DATA =“数据:文本/ CSS,”; private static Final String CSS = CSS_DATA + // 语言=CSS ”“” 。无效的 { -fx-文本填充:红色; } “””;

自定义文本字段表格单元格,当单元格数据无效时应用样式。在这种情况下,如果编辑电子邮件列以不在电子邮件中包含

@
符号,则该电子邮件无效。

TableColumn<Person, String> emailCol = new TableColumn<>("Email");
emailCol.setMinWidth(200);
emailCol.setCellValueFactory(item -> item.getValue().emailProperty());
emailCol.setCellFactory(param -> new TextFieldTableCell<>(new DefaultStringConverter()) {
   @Override
   public void updateItem(String item, boolean empty) {
      super.updateItem(item, empty);

       if (item != null && !empty && !isValidEmail(item)) {
          if (!getStyleClass().contains(INVALID_STYLECLASS)) {
             getStyleClass().add(INVALID_STYLECLASS);
          }
       } else {
          getStyleClass().remove(INVALID_STYLECLASS);
       }
   }

   private static boolean isValidEmail(String item) {
      return item.contains("@");
   }
});
emailCol.setEditable(true);

表格也需要可编辑:

table.setEditable(true);

定义支持表格的项目列表时,会在电子邮件数据上设置提取器,以便在电子邮件更改时更新电子邮件单元格:

  final ObservableList<Person> data = FXCollections.observableArrayList(
          person -> new Observable[] { person.emailProperty()}
  );
  data.addAll(
          // data added here . . .
  );
);

如果您双击某个单元格,编辑其值并将其更改为无效的值(例如,从电子邮件中删除

@
符号),结果将是,该单元格将以红色突出显示,直到它被修复。

示例应用程序

import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.stage.Stage;
import javafx.util.converter.DefaultStringConverter;

import java.io.IOException;

public class StatedTableApp extends Application {

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

   public static final String CSS_DATA = "data:text/css,";
   private static final String CSS = CSS_DATA + // language=CSS
               """
               .invalid {
                   -fx-text-fill: red;
               }
               """;

   @Override
   public void start(Stage stage) throws IOException {
      final TableView<Person> table = new TableView<>();

      final ObservableList<Person> data = FXCollections.observableArrayList(person -> new Observable[] { person.emailProperty()});
      data.addAll(
              new Person("Jacob", "Smith", "[email protected]"),
              new Person("Isabella", "Johnson", "[email protected]"),
              new Person("Ethan", "Williams", "[email protected]"),
              new Person("Emma", "Jones", "[email protected]"),
              new Person("Michael", "Brown", "[email protected]")
      );

      table.getSelectionModel().setCellSelectionEnabled(true);
      table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

      TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
      firstNameCol.setMinWidth(100);
      firstNameCol.setCellValueFactory(item -> item.getValue().firstNameProperty());
      TableColumn<Person, String> lastNameCol = new TableColumn<>("Last Name");
      lastNameCol.setMinWidth(100);
      lastNameCol.setCellValueFactory(item -> item.getValue().lastNameProperty());
      TableColumn<Person, String> emailCol = new TableColumn<>("Email");
      emailCol.setMinWidth(200);
      emailCol.setCellValueFactory(item -> item.getValue().emailProperty());
      emailCol.setCellFactory(param -> new TextFieldTableCell<>(new DefaultStringConverter()) {
         @Override
         public void updateItem(String item, boolean empty) {
            super.updateItem(item, empty);

             if (item != null && !empty && !isValidEmail(item)) {
                if (!getStyleClass().contains("invalid")) {
                   getStyleClass().add("invalid");
                }
             } else {
                getStyleClass().remove("invalid");
             }
         }

         private static boolean isValidEmail(String item) {
            return item.contains("@");
         }
      });
      emailCol.setEditable(true);

      table.setEditable(true);
      table.setItems(data);
      //noinspection unchecked
      table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);

      Scene scene = new Scene(table);
      scene.getStylesheets().add(CSS);
      stage.setScene(scene);
      stage.show();
   }

   public static class Person {
      private final StringProperty firstName;
      private final StringProperty lastName;
      private final StringProperty 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 StringProperty firstNameProperty() {
         return firstName;
      }

      public String getLastName() {
         return lastName.get();
      }

      public void setLastName(String fName) {
         lastName.set(fName);
      }

      public StringProperty lastNameProperty() {
         return lastName;
      }

      public String getEmail() {
         return email.get();
      }

      public void setEmail(String fName) {
         email.set(fName);
      }

      public StringProperty emailProperty() {
         return email;
      }
   }
}

编辑其中一封电子邮件使值无效后的输出:

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.