2017-02-17 16 views
0

Я создал свой собственный столбец выбора, а в заголовке столбца у меня есть флажок, который, когда я нажимаю на изменение значения ячейки, которую я установил для cellValueFactory, которая запускает метод updateItem в TableCell, который запускает настраиваемое событие, с которым мне нужно работать.TableView Cell updateItem не вызывается для ячеек вне окна просмотра

public abstract class GeneratedPersistableBeanFX extends GeneratedPersistableBean { 

private static CheckBox select_all; 

public GeneratedPersistableBeanFX(int beanState) { 
    super(beanState); 
    // TODO Auto-generated constructor stub 
} 
private BooleanProperty SelectedInGridProperty = new SimpleBooleanProperty(false); 

public BooleanProperty selectedInGridProperty() { 
    return SelectedInGridProperty; 
} 

public Boolean getSelectedInGrid() { 
    return SelectedInGridProperty.getValue(); 
} 

public void setSelectedInGrid(Boolean val) { 
    SelectedInGridProperty.setValue(val); 
} 

public static CustomTableColumn<GeneratedPersistableBeanFX, Boolean> getTableColumnSelectedInGrid(String columnName) { 
    getSelectAllCheckBox(); 

    String columnHeader = ((columnName == null) ? "Selected" : columnName); 
    CustomTableColumn<GeneratedPersistableBeanFX, Boolean> theCol = new CustomTableColumn<>(columnHeader); 
    theCol.setId(columnHeader); 
    theCol.setMinWidth(32); 
    theCol.setColumnName(columnHeader); 
    theCol.setGraphic(getSelectAllCheckBox()); 
    theCol.setStyle("-fx-alignment: CENTER;"); 
    theCol.setCellValueFactory(cellData -> cellData.getValue().selectedInGridProperty()); 
    theCol.setCellFactory(new Callback<TableColumn<GeneratedPersistableBeanFX, Boolean>, TableCell<GeneratedPersistableBeanFX, Boolean>>() { 
     @Override 
     public TableCell<GeneratedPersistableBeanFX, Boolean> call(TableColumn<GeneratedPersistableBeanFX, Boolean> col) { 

      final TableCell<GeneratedPersistableBeanFX, Boolean> cell = new TableCell<GeneratedPersistableBeanFX, Boolean>() { 

       @Override 
       public void updateItem(Boolean item, boolean empty) { 
        super.updateItem(item, empty); 
        setText(null); 
        // setMinHeight(40); 
        if (item == null) { 
         setGraphic(null); 
        } 
        else { 
         if (item.booleanValue() && getGraphic() == null) { 
          setGraphic(CustomImageLoaderFX.getInstance().getImageView("check.png", 16)); 
         } 
         else if (item.booleanValue() && getGraphic() != null) { 
          getGraphic().setVisible(true); 
         } 
         else if (getGraphic() != null) { 
          getGraphic().setVisible(false); 
         } 
         if (getTableView() != null && getTableRow() != null && item != null) { 
          getTableView().fireEvent(
            new CustomTableColumnSelectionChangedEvent((GeneratedPersistableBeanFX) getTableRow().getItem(), item.booleanValue())); 
         } 
        } 
       } 
      }; 

      cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { 
       @Override 
       public void handle(MouseEvent event) { 
        ObservableValue<Boolean> ov = ((TableCell<GeneratedPersistableBeanFX, Boolean>) event.getSource()).getTableColumn() 
          .getCellObservableValue(((TableCell<GeneratedPersistableBeanFX, Boolean>) event.getSource()).getIndex()); 
        SimpleBooleanProperty sp = (SimpleBooleanProperty) ov; 
        if (sp == null) { 
         return; 
        } 
        GeneratedPersistableBeanFX bean = (GeneratedPersistableBeanFX) ((TableCell<GeneratedPersistableBeanFX, Boolean>) event.getSource()) 
          .getTableRow().getItem(); 
        if (sp.getValue() == false) { 
         sp.setValue(true); 
        } 
        else { 
         sp.setValue(false); 
        } 
       } 
      }); 
      return cell; 
     } 

    }); 
    return theCol; 
} 

public static CheckBox getSelectAllCheckBox() { 
    if (select_all == null) { 
     select_all = new CheckBox(); 
     select_all.setOnAction(e -> selectAllBoxes(e)); 
    } 
    return select_all; 
} 

private static void selectAllBoxes(ActionEvent e) { 
    CustomTableView<GeneratedPersistableBeanFX> table = getTableViewFromCheckBox(((CheckBox) e.getSource()).getParent()); 
    ObservableList<GeneratedPersistableBeanFX> items = table.getItems(); 
    for (GeneratedPersistableBeanFX item : items) { 
     item.setSelectedInGrid(((CheckBox) e.getSource()).isSelected()); 
     //What I tried to force to trigger updateItem on all rows 
     table.getColumns().get(0).setVisible(false); 
     table.getColumns().get(0).setVisible(true); 
    } 
} 

@SuppressWarnings("unchecked") 
private static CustomTableView<GeneratedPersistableBeanFX> getTableViewFromCheckBox(Parent parent) { 
    if (parent instanceof CustomTableView<?>) { 
     return (CustomTableView<GeneratedPersistableBeanFX>) parent; 
    } 
    else if (parent != null && parent.getParent() != null) { 
     return getTableViewFromCheckBox(parent.getParent()); 
    } 
    else { 
     return null; 
    } 
} 

Например, у меня есть ЮМЭ 3D окно вложена в диалоге, который показывает 3D модели материалов и есть также TableView со всеми материалами. Когда я нажимаю на выделение, только только материалы, видимые в окне просмотра таблицы, выделяются в моем 3D-пространстве, и когда я прокручиваю вниз, у него смешно, что оставшиеся материалы выделяются при прокрутке вниз.

Проблема заключается в том, что метод updateItem вызывается только для ячеек, видимых в настоящее время в окне просмотра TableViews.

Есть ли способ обойти это поведение и заставить его вызвать каждую отдельную ячейку каждого элемента в списке независимо от видимости?

+1

Опубликуйте свой класс «GeneratedPersistableBeanFX» (по крайней мере, части, относящиеся к 'selectedInGridProperty'). –

+0

Выполнено, хотя я действительно думаю, что это не поведение, а поведение javafx. Заметьте это поведение в других табличных представлениях, где мы будем раскрашивать некоторые материалы в таблице с помощью css. И последняя строка не будет окрашена, если бы она говорила только на 1/2 видимой. Если бы отрегулировать размер стола, чтобы строки идеально соответствовали. Хотя это может быть до css, здесь его строго значение связано. – 404KnowledgeNotFound

ответ

0

Так что я читал немного по этому вопросу, и выяснил, что проблема у меня было, так как TableView среди прочего, использует виртуальные ячейки, которые объясняются лучше here.

В принципе один никогда не следует использовать метод updateItem делать что-либо логическое, оно рекомендуется только для изменения визуальных свойств ячейки.

Учитывая это, я просто переместил момент, когда я уволил свое событие от метода updateItem к пользовательским событиям, нажав на флажок «Выбрать все» или щелкнув по самой ячейке. Это не так аккуратно, но оно работает.

private static void selectAllBoxes(ActionEvent e) { 
    CustomTableView<GeneratedPersistableBeanFX> table = getTableViewFromCheckBox(((CheckBox) e.getSource()).getParent()); 
    if (table == null) { 
     return; 
    } 
    ObservableList<GeneratedPersistableBeanFX> items = table.getItems(); 
    for (GeneratedPersistableBeanFX item : items) { 
     item.setSelectedInGrid(((CheckBox) e.getSource()).isSelected()); 
     table.fireEvent(new CustomTableColumnSelectionChangedEvent(item, ((CheckBox) e.getSource()).isSelected())); 
    } 
} 
cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { 
    @SuppressWarnings("unchecked") 
    @Override 
    public void handle(MouseEvent event) { 
     SimpleBooleanProperty sp = (SimpleBooleanProperty) (((TableCell<GeneratedPersistableBeanFX, Boolean>) event.getSource()) 
      .getTableColumn().getCellObservableValue(((TableCell<GeneratedPersistableBeanFX, Boolean>) event.getSource()).getIndex())); 
     if (sp == null) { 
      return; 
     } 
     if (sp.getValue() == false) { 
      sp.setValue(true); 
     } 
     else { 
      sp.setValue(false); 
     } 
     ((TableCell<GeneratedPersistableBeanFX, Boolean>) event.getSource()).getTableView().fireEvent(
      new CustomTableColumnSelectionChangedEvent((GeneratedPersistableBeanFX) ((TableCell<GeneratedPersistableBeanFX, Boolean>) event 
      .getSource()).getTableRow().getItem(), sp.getValue().booleanValue())); 

    } 
}); 

В выходные вдали от кодирования и работы иногда могут творить чудеса! Я просто не понимал этого вообще о.

 Смежные вопросы

  • Нет связанных вопросов^_^