【问题标题】:JavaFX custom ComboBox with generic class具有泛型类的 JavaFX 自定义 ComboBox
【发布时间】:2017-04-06 10:29:47
【问题描述】:

我有两种扩展类 X 的类

public class A extends X

public class B extends X

在我的 JavaFX 应用程序中,需要有一个组合框。此组合框是使用类 A 或 B 构造的,并使用该类的相应 toString() 方法进行填充。减少代码重复。

我正在尝试修改当前生成组合框的方法,以便允许 A 或 B 类型的 ObservableList。

protected ComboBox<? extends X> getComboBox(ObservableList<? extends X> list){
    ComboBox<? extends X> comboBox = new ComboBox<>();
    comboBox.setItems(list);
    comboBox.setCellFactory(new Callback<ListView<? extends X>, ListCell<? extends X>>() {
        @Override
        public ListCell<Controller> call(ListView<Controller> param) {

            return new ListCell<? extends X>(){
                @Override
                public void updateItem(Class<? extends X> content, boolean empty){
                    super.updateItem(content, empty);
                    if(!empty) {
                        setText(content.toString());
                    } else {
                        setText(null);
                    }
                }
            };
        }
    });
    return comboBox;
}

由于两个类都有一个超类,是否有可能实现这样的事情(并且可能但不是本质上,将其作为原始类类型返回)

@SillyFly - 我使用 Reflections 依赖项检索列表。它返回特定类型(即 A)的所有类

public ObservableList<A> getAList() {
    Reflections reflection = new Reflections("com.classes.aClasses");
    ObservableList<A> classesList = FXCollections.observableArrayList();
    for (Class<? extends A> thisClass : reflection.getSubTypesOf(A.class)) {
        try {
            classesList.add(thisClass.newInstance());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    return classesList;
}

【问题讨论】:

  • 什么是Input?这是基类(您之前称为X)吗?
  • 更正了这个@sillyfly

标签: java inheritance javafx combobox superclass


【解决方案1】:

我很确定默认的ListCell 实现使用toString 来呈现项目,因此设置单元工厂可能是多余的。

至于您的问题 - 问题是 ComboBox&lt;T&gt; 需要其 items 属性为 ObservableList&lt;T&gt;。由于您使用generic wildcard 作为类型参数,编译器无法知道这是否是同一类型。

你需要做的是给方法一个generic type parameter

protected <T extends X> ComboBox<T> getComboBox(ObservableList<T> list){
    ComboBox<T> comboBox = new ComboBox<>();
    comboBox.setItems(list);
    // Setting a cell factory is probably redundant if you're only using toString...
    return comboBox;
} 

请注意,我们定义了一个类型参数T 并强制它是扩展X 的类型。此后所有泛型变量都使用此类型参数,因此编译器可以知道它全部匹配。

【讨论】:

  • 了解冗余方面。我想我之前出于不同的原因实现了这一点,但现在没有意义。但是,返回列表(被插入到该方法中)的方法是: public ObservableList getAList() - 当我稍后调用它时,我收到错误 ObservableList cannot be applied to ObservableList跨度>
  • 请在原始问题中添加其他方法以及如何调用每个方法 - 很难理解或知道出了什么问题,如果有一个完整的例子会更容易理解。
  • 我已将此添加到您的原始问题中。我使用反射包,因为我需要添加某个包下的每个类。例如,在 com.animals 包中,我会添加 dog.class、cat.class、rabbit.class - 这是有意为之,因为我希望在此包中添加每个类作为选项。
猜你喜欢
  • 2016-01-13
  • 1970-01-01
  • 1970-01-01
  • 2020-09-12
  • 2019-10-02
  • 2020-01-07
  • 1970-01-01
  • 1970-01-01
  • 2019-12-07
相关资源
最近更新 更多