2016-12-07 2 views
0

Я создал пользовательский элемент управления JavaFX, назовите его ComboBoxTablePopup, это универсальный элемент управления, который получает список элементов типа S от пользователя. Внутренне я использовал какой-то фильтрации в TableView (ребенка ComboboxTablePopup Contrl) .so я использовал:Сделать Custom Control Generic

FiltredList.setPridcate(S -> { 
      if (pr == null || pr.isEmpty() || pr.length() == 0) 
       return true; 
      if (((Engine) S).getDesignation().toLowerCase().contains(pr.toLowerCase())) { 
       return true; 
      } else 
       return false;). 

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

Итак, как я могу сделать функцию предиката общей, поэтому я могу работать с любым объектом и фильтром?

Вот код моего CustomControl:

public class ComboBoxTablePopup<S> extends ComboBoxBase { 

    private 
    ObservableList<TableColumn> columns = FXCollections.emptyObservableList(); 

    public ObservableList<TableColumn> getColumns() { 
     return columns; 
    } 

    public void setColumns(ObservableList<TableColumn> columns) { 
     this.columns = columns; 
    } 




    /*************************************************************************** 
    * * 
    * Static properties and methods           * 
    * * 
    **************************************************************************/ 

    private static <T> StringConverter<T> defaultStringConverter() { 
     return new StringConverter<T>() { 
      @Override 
      public String toString(T t) { 
       return t == null ? null : t.toString(); 
      } 

      @Override 
      public T fromString(String string) { 
       return (T) string; 
      } 
     }; 
    } 

    /*************************************************************************** 
    *                   * 
    * Constructors               * 
    *                   * 
    **************************************************************************/ 

    /** 
    * Creates a default ComboboxTablePopup instance with an empty 
    * {@link #itemsProperty() items} list and default 
    * {@link #selectionModelProperty() selection model}. 
    */ 


    public ComboBoxTablePopup() { 
     this(FXCollections.<S>emptyObservableList()); 

    } 


    /** 
    * Creates a default ComboboxTablePopup instance with the provided items list and 
    * a default {@link #selectionModelProperty() selection model}. 
    */ 

    public ComboBoxTablePopup(ObservableList<S> items) { 
     setItems(items); 
     getStyleClass().add(DEFAULT_STYLE_CLASS); 
     setEditable(true); 
     setPromptText("Plz Search for a pirticular term"); 


    } 

    public ComboBoxTablePopup(ObservableList<S> items, ObservableList<TableColumn> columns) { 
     this(items); 
     this.columns = columns; 

    } 


    private static final String DEFAULT_STYLE_CLASS = "combobox-table-popup"; 
    private ReadOnlyObjectWrapper<TextField> editor; 

    private ObjectProperty<ObservableList<S>> items = new SimpleObjectProperty<ObservableList<S>>(this, "items"); 

    public final void setItems(ObservableList<S> value) { 
     itemsProperty().set(value); 
    } 

    public final ObservableList<S> getItems() { 
     return items.get(); 
    } 

    public ObjectProperty<ObservableList<S>> itemsProperty() { 
     return items; 
    } 


    // Converter 
    public ObjectProperty<StringConverter<S>> converterProperty() { 
     return converter; 
    } 

    private ObjectProperty<StringConverter<S>> converter = 
      new SimpleObjectProperty<StringConverter<S>>(this, "converter", ComboBoxTablePopup.<S>defaultStringConverter()); 

    public final void setConverter(StringConverter<S> value) { 
     converterProperty().set(value); 
    } 

    public final StringConverter<S> getConverter() { 
     return converterProperty().get(); 
    }// Create a symmetric (format/parse) converter with the default locale. 


    // Editor 
    public TextField getEditor() { 
     return editorProperty().get(); 
    } 

    public ReadOnlyObjectProperty<TextField> editorProperty() { 
     if (editor == null) { 
      editor = new ReadOnlyObjectWrapper<TextField>(this, "editor"); 
      editor.set(new ComboBoxListViewSkin.FakeFocusTextField()); 

     } 


     return editor.getReadOnlyProperty(); 

    } 


    @Override 
    protected Skin<?> createDefaultSkin() { 
     return new ComboBoxTablePopupSkin<>(this); 
    } 


} 

public class ComboBoxTablePopupSkin<S> extends ComboBoxPopupControl { 

    private ComboBoxTablePopup comboBoxTablePopup; 
    private ObservableList<S> comboboxTablePopupItems; 

    private TextField displayNode; 

    private TableView<S> tableViewPopupContent; 


    FilteredList<S> filtredList; 
    private SortedList<S> sortedList; 

    private Predicate<S> predicate; 

    private final InvalidationListener itemsObserver; 

    private final ListChangeListener<S> tableViewItemsListener = new ListChangeListener<S>() { 
     @Override 
     public void onChanged(ListChangeListener.Change<? extends S> c) { 
      getSkinnable().requestLayout(); 
     } 
    }; 

    private final WeakListChangeListener<S> weakListViewItemsListener = 
      new WeakListChangeListener<S>(tableViewItemsListener); 

    public ComboBoxTablePopupSkin(ComboBoxTablePopup comboBoxTablePopup) { 
     super(comboBoxTablePopup, new ComboBoxTablePopupBehavior(comboBoxTablePopup)); 
     this.comboBoxTablePopup = comboBoxTablePopup; 

     setupTablePredicate(); 
     updateComboBoxTablePopupItems(); 


     itemsObserver = observable -> { 
      updateComboBoxTablePopupItems(); 
      updateTableViewItems(); 

     }; 
     this.comboBoxTablePopup.itemsProperty().addListener(new WeakInvalidationListener(itemsObserver)); 

     tableViewPopupContent = createTableView(); 
     tableViewPopupContent.setManaged(false); 

     getChildren().add(tableViewPopupContent); 

     updateTableViewItems(); 


     getEditor().textProperty().addListener((obv, oldValue, newValue) -> { 
      if (!newValue.isEmpty()) 
       comboBoxTablePopup.show(); 
      filtreData(newValue); 
     }); 

     registerChangeListener(comboBoxTablePopup.itemsProperty(), "ITEMS"); 
     registerChangeListener(comboBoxTablePopup.valueProperty(), "VALUE"); 
     registerChangeListener(comboBoxTablePopup.editorProperty(), "EDITABLE"); 


    } 

    private void setupTablePredicate() { 

    } 

    private void updateTableViewItems() { 
     filtredList = new FilteredList<S>(comboboxTablePopupItems, p -> true); 

     sortedList = new SortedList<S>(filtredList); 

     sortedList.comparatorProperty().bind(tableViewPopupContent.comparatorProperty()); 
     tableViewPopupContent.setItems(sortedList); 

    } 

    private void filtreData(String pr) { 
     String data = pr; 
     filtredList.setPredicate(engine -> { 
      if (pr == null || pr.isEmpty() || pr.length() == 0) 
       return true; 
      if (((Engine) engine).getDesignation().toLowerCase().contains(pr.toLowerCase())) { 
       return true; 
      } else 
       return false; 

     }); 


    } 


    public void updateComboBoxTablePopupItems() { 
     comboboxTablePopupItems = comboBoxTablePopup.getItems(); 
     comboboxTablePopupItems = comboboxTablePopupItems == null ? FXCollections.<S>emptyObservableList() : comboboxTablePopupItems; 
    } 

    private TableView<S> createTableView() { 
     final TableView<S> tableView = new TableView<>(); 

     tableView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE); 
     tableView.setFocusTraversable(false); 

     tableView.getSelectionModel().selectedItemProperty().addListener(o -> { 
      int index = tableView.getSelectionModel().getSelectedIndex(); 
      System.out.println("selected item changed"); 
     }); 

     for (TableColumn tblColumn : tableColumns()) { 
      tableView.getColumns().add(tblColumn); 
     } 


     tableView.setOnKeyPressed(e -> { 
      if (e.getCode() == KeyCode.ENTER || 
        e.getCode() == KeyCode.ESCAPE || 
        e.getCode() == KeyCode.SPACE) { 
       S selectedItem = tableView.getSelectionModel().getSelectedItem(); 
       if (selectedItem != null) { 

        System.out.println(((Engine) selectedItem).getDesignation()); 
        getEditor().setText(((Engine) selectedItem).getDesignation()); 
        comboBoxTablePopup.setValue(selectedItem); 
        comboBoxTablePopup.hide(); 


       } 
      } 
     }); 


     return tableView; 
    } 

    private ObservableList<TableColumn> tableColumns() { 
     return ((ComboBoxTablePopup) getSkinnable()).getColumns(); 
    } 

    @Override 
    protected Node getPopupContent() { 
     return this.tableViewPopupContent; 
    } 

    @Override 
    protected TextField getEditor() { 
     return ((ComboBoxTablePopup) getSkinnable()).getEditor(); 
    } 

    @Override 
    protected StringConverter getConverter() { 
     return ((ComboBoxTablePopup) getSkinnable()).getConverter(); 
    } 

    @Override 
    public Node getDisplayNode() { 
     if (displayNode == null) { 
      displayNode = getEditableInputNode(); 
      displayNode.getStylesheets().add("ComboBoxTable-display-node"); 
      updateDisplayNode(); 

     } 

     displayNode.setEditable(comboBoxTablePopup.isEditable()); 


     return displayNode; 


    } 

    @Override 
    protected void handleControlPropertyChanged(String p) { 
     super.handleControlPropertyChanged(p); 

     if ("TEXT".equals(p)) { 
      if (!getEditor().textProperty().get().isEmpty()) { 
       comboBoxTablePopup.show(); 
      } 
      filtreData(getEditor().textProperty().get()); 

     } else if ("ITEMS".equals(p)) { 
      updateComboBoxTablePopupItems(); 

     } else if ("EDITABLE".equals(p)) { 
      getEditableInputNode(); 
     } 

    } 


} 

ответ

1

Используйте StringConverter для преобразования элемента в String или использовать подобную недвижимость.

public class ComboBoxTablePopupSkin<S> extends ComboBoxPopupControl<S> { 

    ... 

    private static final StringConverter DEFAULT_CONVERTER = new StringConverter() { 

     @Override 
     public String toString(Object o) { 
      return o == null ? null : o.toString(); 
     } 

     @Override 
     public Object fromString(String s) { 
      throw new UnsupportedOperationException(); 
     } 
    }; 

    public final StringConverter<S> getConverter() { 
     StringConverter<S> converter = converterProperty().get(); 
     // fix in case the property is set to a null 
     return converter == null ? DEFAULT_CONVERTER : converter; 
    } 
private void filtreData(String pr) { 
    if (pr == null || pr.isEmpty()) { 
     filtredList.setPredicate(null); 
    } else { 
     final StringConverter<S> converter = ((ComboBoxTablePopup<S>) getSkinnable()).getConverter(); 

     final String data = pr.toLowerCase(); 
     filtredList.setPredicate(object -> { 
      String s = converter.toString(object); 
      return s != null && s.toLowerCase().contains(data); 
     }); 
    } 
}