これを行う最もきれいな方法は、おそらく、テーブル行のスタイルクラスまたは擬似クラスを変更する行ファクトリを使用することです。次に、セルに固定されたスタイルクラスを設定します。
私の例では、従来のDate
タイプの代わりにLocalDate
を使用しています。あなたは
PseudoClass nearlyExpired = PseudoClass.getPseudoClass("nearly-expired");
table.setRowFactory(tv -> {
TableRow<Bill> row = new TableRow<>() ;
BooleanProperty nearlyDueProperty = new SimpleBooleanProperty();
nearlyDueProperty.addListener((obs, wasNearlyDue, isNearlyDue) ->
row.pseudoClassStateChanged(nearlyExpired, isNearlyDue));
row.itemProperty().addListener((obs, oldBill, newBill) -> {
nearlyDueProperty.unbind();
if (newBill == null) {
nearlyDueProperty.set(false);
} else {
// bind nearlyDueProperty to the time between the current Bill's
// paymentDate and expirationDate
// true if less than 7 days, false otherwise:
nearlyDueProperty.bind(Bindings.createBooleanBinding(() ->
newBill.getExpirationDate().minusDays(7).isBefore(newBill.getPaymentDate()),
newBill.expirationDateProperty(), newBill.paymentDateProperty()));
}
});
return row ;
});
ような何かを行うことができますし、もちろん、あなたが定義することができ、その後、列自体のために、あなただけの
LocalDateStringConverter converter = new LocalDateStringConverter();
Callback<TableColumn<Bill, LocalDate>, TableCell<Bill, LocalDate>> defaultCellFactory = TextFieldTableCell.forTableColumn(converter);
expirationDateCol.setCellFactory(tc -> {
TableCell<Bill, LocalDate> cell = defaultCellFactory.call(tc);
cell.getStyleClass().add("expiration-cell");
return cell ;
});
を必要とし、最終的にあなたが
.table-row-cell:nearly-expired .expiration-cell {
-fx-background-color: red ;
}
で外部スタイルシートを添付することができますあなたがここで好きな方法でスタイルを整えます。支払い-table.css上記のスタイルシートと
import java.time.LocalDate;
import java.util.Random;
import java.util.function.Function;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.css.PseudoClass;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.stage.Stage;
import javafx.util.Callback;
import javafx.util.converter.LocalDateStringConverter;
public class BillingTable extends Application {
@Override
public void start(Stage primaryStage) {
TableView<Bill> table = new TableView<>();
table.setEditable(true);
PseudoClass nearlyExpired = PseudoClass.getPseudoClass("nearly-expired");
table.setRowFactory(tv -> {
TableRow<Bill> row = new TableRow<>() ;
BooleanProperty nearlyDueProperty = new SimpleBooleanProperty();
nearlyDueProperty.addListener((obs, wasNearlyDue, isNearlyDue) ->
row.pseudoClassStateChanged(nearlyExpired, isNearlyDue));
row.itemProperty().addListener((obs, oldBill, newBill) -> {
nearlyDueProperty.unbind();
if (newBill == null) {
nearlyDueProperty.set(false);
} else {
nearlyDueProperty.bind(Bindings.createBooleanBinding(() ->
newBill.getExpirationDate().minusDays(7).isBefore(newBill.getPaymentDate()),
newBill.expirationDateProperty(), newBill.paymentDateProperty()));
}
});
return row ;
});
TableColumn<Bill, LocalDate> paymentDateCol = column("Payment Date", Bill::paymentDateProperty);
table.getColumns().add(paymentDateCol);
LocalDateStringConverter converter = new LocalDateStringConverter();
Callback<TableColumn<Bill, LocalDate>, TableCell<Bill, LocalDate>>
defaultCellFactory = TextFieldTableCell.forTableColumn(converter);
paymentDateCol.setCellFactory(defaultCellFactory);
TableColumn<Bill, LocalDate> expirationDateCol = column("Expiration Date", Bill::expirationDateProperty);
table.getColumns().add(expirationDateCol);
expirationDateCol.setCellFactory(tc -> {
TableCell<Bill, LocalDate> cell = defaultCellFactory.call(tc);
cell.getStyleClass().add("expiration-cell");
return cell ;
});
Random rng = new Random();
for (int i = 1; i <= 20 ; i++) {
LocalDate now = LocalDate.now();
LocalDate payment = now.plusDays(rng.nextInt(5));
LocalDate expiration = payment.plusDays(rng.nextInt(14));
table.getItems().add(new Bill(payment, expiration));
}
Scene scene = new Scene(table);
scene.getStylesheets().add("payment-table.css");
primaryStage.setScene(scene);
primaryStage.show();
}
private static <S,T> TableColumn<S,T> column(String title, Function<S,Property<T>> property) {
TableColumn<S,T> col = new TableColumn<>(title);
col.setCellValueFactory(cellData -> property.apply(cellData.getValue()));
return col ;
}
public static class Bill {
private final ObjectProperty<LocalDate> paymentDate = new SimpleObjectProperty<>();
private final ObjectProperty<LocalDate> expirationDate = new SimpleObjectProperty<>();
// other properties...
public Bill(LocalDate paymentDate, LocalDate expirationDate) {
setPaymentDate(paymentDate);
setExpirationDate(expirationDate);
}
public final ObjectProperty<LocalDate> paymentDateProperty() {
return this.paymentDate;
}
public final java.time.LocalDate getPaymentDate() {
return this.paymentDateProperty().get();
}
public final void setPaymentDate(final java.time.LocalDate paymentDate) {
this.paymentDateProperty().set(paymentDate);
}
public final ObjectProperty<LocalDate> expirationDateProperty() {
return this.expirationDate;
}
public final java.time.LocalDate getExpirationDate() {
return this.expirationDateProperty().get();
}
public final void setExpirationDate(final java.time.LocalDate expirationDate) {
this.expirationDateProperty().set(expirationDate);
}
}
public static void main(String[] args) {
launch(args);
}
}
:
はここで完全な例です。
コードを減らして、ダウンロードしなくても実行できるようにすることはできますか? (言い換えると、[MCVE]を提供します)実際の問題を示すために2つの列が必要です。モデルクラスには2つのプロパティがあります。 –
完了。私は関連する部分だけを残しました。 – coderodde
今私は実際の要件について混乱しています。どのような細胞の色を決定する必要がありますか? 'onCommitEdit'の場所はあなたがしようとしているところであれば、それを行う場所ではありません。 –