2017-01-26 9 views
0

У меня есть следующая проблема: я пишу свое приложение с помощью JavaFX. Я использую TableView. Пользователи должны использовать его для наблюдения, добавления и удаления данных. У меня есть поле ID, которое должно быть уникальным. Поэтому, когда пользователь заканчивает редактирование, я должен проверить, является ли результат уникальным или нет. И если это уникально, мне приходится снимать изменения. Или даже лучше, я должен проверить это в момент обновления данных и, если необходимо, пропустить обновление.JavaFX TableView. Как проверить, что пользователь вводит uniqe значение

У меня есть TableView с тремя столбцами

colID.setCellValueFactory((TableColumn.CellDataFeatures<CDataType, String> cell) -> cell.getValue().getSID()); 
    colCaption.setCellValueFactory((TableColumn.CellDataFeatures<CDataType, String> cell) -> cell.getValue().getSCaption()); 
    colType.setCellValueFactory((TableColumn.CellDataFeatures<CDataType, String> cell) -> cell.getValue().getSType()); 

    colID.setCellFactory(TextFieldTableCell.forTableColumn()); 
    colCaption.setCellFactory(TextFieldTableCell.forTableColumn()); 
    colType.setCellFactory(TextFieldTableCell.forTableColumn()); 

    lstObservable = FXCollections.observableList(lstData, (CDataType param)->{ 

     param.getSID().addListener((ObservableValue<? extends String> observable, String oldValue, String newValue) -> { 

       System.out.println("getSID().ChangeListener: Changed: " + observable + ")"+ observable.getClass() + ") [" + oldValue + " -> " + newValue + "]"); 
      } 
     }); 

     return new Observable[]{param.getSID(), 
           param.getSCaption(), 
           param.getSType() 
     }; 
    }); 

    tabView.setItems(lstObservable); 

Что обычная практика для этого? Я уверен, что эта проблема не нова, но я не могу найти решение.

UPD: Я имею в виду, что я не понимаю, какое событие я должен обработать, чтобы уменьшить пользовательские изменения. Я полагаю, что это должен быть ChangeListener, но если я изменил значение элемента данных, я получил бесконечную рекурсию.

+1

хорошо, самый простой подход является собрать все идентификаторы в наборе, а затем на новое значение вставленной проверки, если этот набор содержит, что Я бы. Если у вас нет миллионов записей, которые бы работали довольно быстро – Enigo

+0

Проблема в том, что я не знаю, где я должен это проверить? Если в ChangeListener я могу избежать изменений? – Yura

ответ

1

Вы можете справиться с этим в редактированием совершить - что-то вроде следующего:

colID.setOnEditCommit(event -> { 
    String newValue = event.getNewValue(); 
    if(checkUniqueness(newValue)){ 
     event.getRowValue().setSID(newValue); 
    }else { 
     event.getRowValue().setSID(null); 
    } 

    //Weird FX Bug - on the second time through, the value was set, but the table 
    //column didn't repaint, showing the incorrect amount. 
    colID.setVisible(false); 
    colID.setVisible(true); 
}); 

//Stream the backing collection for the table and look for the value that needs to be unique 

public boolean checkUniqueness(String value) { 
     return backingCollection 
      .stream() 
      .noneMatch(item -> item.getSID().equals(value)); 
    } 
+0

Большое спасибо! Этот трюк с помощью setVisible действительно помог. Я сделал то же самое, кроме видимости столбцов. Спасибо еще одному! – Yura

+0

, что setVisible было одной вещью, которая вызвала у меня много разочаровывающих дней при кодировании. он в конечном итоге перестает изменять отображаемое значение до тех пор, пока вы его не перекрасите, так что это единственный способ, который я нашел, что обеспечивает последовательное поведение. –

+0

Вы спасли мне много разочаровывающих дней :) – Yura