2016-07-31 79 views
0

everyone。基于JavaFX中的TableRow中的对象属性的自定义单元操作

我有一个JavaFX的tableView这样的:

 
----------------------------------------- 
| Name  | Date  | actions | 
----------------------------------------- 
| jack  |23-06-2016 | B1 B2 B3 | 
----------------------------------------- 
| Jane  |12-02-2017 | B1 B2 B3 | 
----------------------------------------- 
| Mickel  |22-05-2017 | B1 B2 B3 | 
----------------------------------------- 

的行动列使用CustomCellTable呈现。它包含三个按钮(B1,B2和B3)

我希望只有在相应的日期是表中的最大值时才启用B3按钮。

在上面的例子中,最后一排的B3按钮应该被启用,别人不

应提前感谢您的帮助。

+1

是固定每行的日期,或在显示表的时候,他们可以改变? –

+0

这些行由具有SimpleObjectProperty 的JavaFx Beans支持,该属性可以在运行时更改。 (B3按钮会弹出一个对话框来编辑bean,因此也是该行) –

回答

2

假设你有一个看起来像

public class Person { 

    // ... 

    public StringProperty nameProperty() { 
     return name ; 
    } 

    public ObjetProperty<LocalDate> dateProperty() { 
     return date ; 
    } 

    public LocalDate getDate() { 
     return dateProperty().get(); 
    } 

    // ... 
} 

一个模型类,如果你创建的项目列表表与extractor

ObservableList<Person> tableData = FXCollections.observableArrayList(p -> new Observable[] {p.dateProperty()}); 
tableData.addAll(...); 
table.setItems(tableData); 

那么你可以做

ObjectBinding<Person> personWithLatestDate = Bindings.createObjectBinding(() -> 
     tableData.stream().max(Comparator.comparing(Person::getDate)).orElse(null), 
     tableData); 

和您的操作栏可能如下所示:

TableColumn<Person, Person> actionsColumn = new TableColumn<>("Actions"); 
actionsColumn.setCellValueFactory(cellData -> new SimpleObjectProperty<>(cellData.getValue())); 

actionsColumn.setCellFactory(tc -> new TableCell<Person, Person>() { 
    // ... 
    Button b3 = new Button(...) ; 
    HBox buttons = new HBox(5, b1, b2, b3); 
    // ... 

    { 
     b3.disableProperty().bind(itemProperty().isNotEqualTo(personWithLatestDate)); 
    } 

    @Override 
    protected void updateItem(Person person, boolean empty) { 
     super.updateItem(person, empty); 
     setGraphic(empty ? null : buttons); 
    } 
}); 

这里有一个SSCCE:

import java.time.LocalDate; 
import java.util.Comparator; 

import javafx.application.Application; 
import javafx.beans.Observable; 
import javafx.beans.binding.Bindings; 
import javafx.beans.binding.ObjectBinding; 
import javafx.beans.property.ObjectProperty; 
import javafx.beans.property.SimpleObjectProperty; 
import javafx.beans.property.SimpleStringProperty; 
import javafx.beans.property.StringProperty; 
import javafx.collections.FXCollections; 
import javafx.collections.ObservableList; 
import javafx.geometry.HPos; 
import javafx.geometry.Insets; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.DatePicker; 
import javafx.scene.control.Label; 
import javafx.scene.control.TableCell; 
import javafx.scene.control.TableColumn; 
import javafx.scene.control.TableView; 
import javafx.scene.control.TextField; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.ColumnConstraints; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.HBox; 
import javafx.scene.layout.Priority; 
import javafx.stage.Modality; 
import javafx.stage.Stage; 
import javafx.stage.StageStyle; 
import javafx.stage.Window; 

public class TableCelDisableButton extends Application { 

    private ObservableList<Person> tableData; 

    @Override 
    public void start(Stage primaryStage) { 

     TableView<Person> table = new TableView<>(); 
     tableData = FXCollections.observableArrayList(p -> new Observable[] {p.dateProperty()}); 
     table.setItems(tableData); 

     ObjectBinding<Person> personWithLatestDate = Bindings.createObjectBinding(() -> 
       tableData.stream().max(Comparator.comparing(Person::getDate)).orElse(null), 
       tableData); 

     TableColumn<Person, String> nameCol = new TableColumn<>("Name"); 
     nameCol.setCellValueFactory(cellData -> cellData.getValue().nameProperty()); 

     TableColumn<Person, LocalDate> dateCol = new TableColumn<>("Date"); 
     dateCol.setCellValueFactory(cellData -> cellData.getValue().dateProperty()); 

     TableColumn<Person, Person> actionsCol = new TableColumn<>("Actions"); 
     actionsCol.setCellValueFactory(cellData -> new SimpleObjectProperty<>(cellData.getValue())); 

     actionsCol.setCellFactory(tc -> new TableCell<Person, Person>() { 
      Button edit = new Button("Edit"); 
      Button button = new Button("Click"); 
      HBox buttons = new HBox(5, edit, button); 

      { 
       edit.setOnAction(e -> edit(getItem(), primaryStage, false)); 
       button.disableProperty().bind(itemProperty().isNotEqualTo(personWithLatestDate)); 
      } 

      @Override 
      protected void updateItem(Person person, boolean empty) { 
       super.updateItem(person, empty); 
       setGraphic(empty ? null : buttons); 
      } 
     }); 

     table.getColumns().add(nameCol); 
     table.getColumns().add(dateCol); 
     table.getColumns().add(actionsCol); 

     table.getItems().add(new Person("Jack", LocalDate.of(2016, 6, 23))); 
     table.getItems().add(new Person("Jane", LocalDate.of(2017, 2, 12))); 
     table.getItems().add(new Person("Mikel", LocalDate.of(2017, 5, 22))); 

     Button add = new Button("Add"); 
     add.setOnAction(e -> edit(new Person("", LocalDate.now()), primaryStage, true)); 

     Button delete = new Button("Delete"); 
     delete.disableProperty().bind(table.getSelectionModel().selectedItemProperty().isNull()); 
     delete.setOnAction(e -> tableData.remove(table.getSelectionModel().getSelectedIndex())); 

     HBox buttons = new HBox(5, add, delete); 
     buttons.setPadding(new Insets(5)); 
     buttons.setAlignment(Pos.CENTER); 


     Scene scene = new Scene(new BorderPane(table, null, null, buttons, null), 600, 600); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private void edit(Person person, Window primaryStage, boolean addOnCommit) { 
     GridPane editor = new GridPane(); 
     ColumnConstraints leftCol = new ColumnConstraints(); 
     leftCol.setHgrow(Priority.NEVER); 
     leftCol.setHalignment(HPos.RIGHT); 
     ColumnConstraints rightCol = new ColumnConstraints(); 
     rightCol.setHgrow(Priority.SOMETIMES); 
     rightCol.setHalignment(HPos.LEFT); 
     editor.getColumnConstraints().addAll(leftCol, rightCol); 

     editor.setHgap(5); 
     editor.setVgap(8); 
     editor.setPadding(new Insets(10)); 

     editor.add(new Label("Name:"), 0, 0); 
     editor.add(new Label("Date"), 0, 1); 
     TextField name = new TextField(person.getName()); 
     editor.add(name, 1, 0); 
     DatePicker date = new DatePicker(person.getDate()); 
     editor.add(date, 1, 1); 

     Button ok = new Button("OK"); 
     Button cancel = new Button("Cancel"); 
     HBox buttons = new HBox(5, ok, cancel); 
     buttons.setAlignment(Pos.CENTER); 
     editor.add(buttons, 0, 2, 2, 1); 


     Scene scene = new Scene(editor); 
     Stage editDialog = new Stage(); 
     editDialog.setScene(scene); 
     editDialog.initModality(Modality.APPLICATION_MODAL); 
     editDialog.initOwner(primaryStage); 
     editDialog.initStyle(StageStyle.UNDECORATED); 

     editDialog.sizeToScene(); 

     ok.setOnAction(e -> { 
      person.setName(name.getText()); 
      person.setDate(date.getValue()); 
      if (addOnCommit) { 
       tableData.add(person); 
      } 
      editDialog.hide(); 
     }); 

     cancel.setOnAction(e -> editDialog.hide()); 

     editDialog.show(); 
    } 

    public static class Person { 
     private final StringProperty name = new SimpleStringProperty(); 
     private final ObjectProperty<LocalDate> date = new SimpleObjectProperty<>(); 

     public Person(String name, LocalDate date) { 
      setName(name); 
      setDate(date); 
     } 

     public final StringProperty nameProperty() { 
      return this.name; 
     } 


     public final java.lang.String getName() { 
      return this.nameProperty().get(); 
     } 


     public final void setName(final java.lang.String name) { 
      this.nameProperty().set(name); 
     } 


     public final ObjectProperty<LocalDate> dateProperty() { 
      return this.date; 
     } 


     public final java.time.LocalDate getDate() { 
      return this.dateProperty().get(); 
     } 


     public final void setDate(final java.time.LocalDate date) { 
      this.dateProperty().set(date); 
     } 



    } 

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

ObjectBinding 有一个问题,它表示在Bindings类型中的方法createObjectBinding(Callable ,Observable ...)不适用于参数(比较器 >>)不适用于参数(() - > {},ObservableList )'和'方法max(比较器<?super Person> –

+0

正如你所说的那样纠正了它,但它似乎不起作用。我尝试过调试,并发现'updateItem'方法的Person人参数始终为空。而且当我检查latestDate绑定时,我会看到一些“无效”文本。 –

+0

SSCCE的工作原理(尝试它),所以你只是有不同的设置(或者你可以跳过'setCellValueFactory(...)'行)。 –

相关问题