2016-12-14 81 views
0

我想下面的代碼轉換爲是通用的Java類型,以避免手動重新代碼編輯上提交的每個新的表格列...的JavaFX的TableView - 通用OnEditCommit

colOccurrences.setOnEditCommit(
      new EventHandler<TableColumn.CellEditEvent<Damageloop, Float>>() { 
       @Override 
       public void handle(TableColumn.CellEditEvent<Damageloop, Float> t) { 
        ((Damageloop)t.getTableView().getItems().get(
          t.getTablePosition().getRow())).setOccurrences(t.getNewValue()); 
       } 
     }); 

我有嘗試添加以下代碼被分配給每個表列的自定義細胞工廠類...

TableColumn<S, T> col = super.getTableColumn(); 
col.setOnEditCommit(
new EventHandler<CellEditEvent<S, T>>() { 
    @Override 
    public void handle(CellEditEvent<S, T> t) { 
     TableColumn<S, T> col = t.getTableColumn(); 
     int row = t.getTablePosition().getRow(); 
     ObservableValue<T> ov = col.getCellObservableValue(row); 
     if (ov instanceof WritableValue) { 
      ((WritableValue<T>)ov).setValue(t.getNewValue()); 
     } 
    } 
}); 

這成功地設置所編輯的單元格的底層觀察到的值。但是,當我打電話時...

TableView.getSelectionModel().getSelectedItem() 

在代碼的進一步部分中,仍舊返回舊的未編輯值。但是,如果更新我的編輯通用承諾包括以下內容...

TableColumn<S, T> col = super.getTableColumn(); 
col.setOnEditCommit(
new EventHandler<CellEditEvent<S, T>>() { 
    @Override 
    public void handle(CellEditEvent<S, T> t) { 
     TableColumn<S, T> col = t.getTableColumn(); 
     int row = t.getTablePosition().getRow(); 
     ObservableValue<T> ov = col.getCellObservableValue(row); 
     if (ov instanceof WritableValue) { 
      ((WritableValue<T>)ov).setValue(t.getNewValue()); 
     } 
     //NEW ADDITION TO EVENT HANDLER 
     Date date; 
     date = (Date) t.getNewValue(); 
     ((Damageloop) t.getTableView().getItems().get(t.getTablePosition().getRow())).setDamageloopworkshopduedate(date); 
    } 
}); 

的TableView.getSelectionModel()。getSelectedItem()代碼將返回正確的更新後的值。

任何人都可以告訴我爲什麼oberservable值沒有更新支持列表嗎?或更恰當地如何將我的事件處理程序中的新增功能轉換爲使用泛型?

+0

請張貼的屬性包括的getter/setter /屬性的getter形式'Damageloop'類和'cellValueFactory'在使用該屬性的一個... – fabian

+0

注意的代碼你的整個第一塊可以簡單地降低到'colOccurrences .setOnEditCommit(t - > t.getRowValue()。setOccurrences(t.getNewValue()));' –

回答

1

首先,你可能根本不需要這個的一些原因。

  1. 如果使用JavaFX properties pattern在你的模型類,也就是說,如果你做

    public class Damageloop { 
    
        private ObjectProperty<Float> occurrences = new SimpleObjectProperty<>(0.0f); 
    
        public ObjectProperty<Float> occurrencesProperty() { 
         return occurrences ; 
        } 
    
        public final Float getOccurrences() { 
         return occurrencesProperty().get(); 
        } 
    
        public final void setOccurrences(Float occurrences) { 
         occurrencesProperty().set(occurrences); 
        } 
    
        // ... 
    } 
    

    那麼標準的可編輯的表格單元格(如TextFieldTableCell)將更新編輯屬性提交默認爲:即根本不需要定義onEditCommit處理程序。

  2. 即使你不使用如上面的屬性模式,Java的8 lambda表達式和增強的類型推斷已經允許您在整個第一代碼塊減少到一個在線聲明:

    colOccurrences.setOnEditCommit(e -> e.getRowValue().setOccurrences(e.getNewValue())); 
    

如果你真的想在一個可重用的通用方法來創建此,你可以這樣做

public class TableUtils { 

    public static <S,T> void createDefaultEditHandler(
     TableColumn<S,T> column, BiConsumer<S,T> committer) { 

     column.setOnEditCommit(event -> 
      committer.accept(event.getRowValue(), event.getNewValue())); 

    } 
} 

您可以與調用:

TableUtils.createDefaultEditHandler(colOccurrences, Damageloop::setOccurrences); 

(並且這對於其他類型的列是完全可重用的)。

+0

這裏有很多很好的解決方案。感謝您的全面回答:)。 – Josh

+0

爲什麼'setOnEditCommit'? https://docs.oracle.com/javase/8/javafx/api/javafx/scene/control/TableView.html說:「除非你處理回寫屬性(或相關數據源),否則不會發生任何事情。 「我們需要採取什麼樣的預防措施來確保這不是我們的命運? –

+0

@LimitedAtonement和我在這裏回答的不一樣嗎?如果使用JavaFX屬性模式並且不調用'setOnEditCommit','onEditCommit'的默認值將更新屬性。 –