JavaFX自定义ComboBox与泛型类

时间:2016-11-22 16:35:48

标签: java inheritance javafx combobox superclass

我有两种类,它们扩展了类X

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />

    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="format-detection" content="telephone=no" />
    <meta name="msapplication-tap-highlight" content="no" />
    <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width" />

    <!-- This is a wide open CSP declaration. To lock this down for production, see below. -->
    <meta http-equiv="Content-Security-Policy" content="default-src * 'unsafe-inline'; style-src 'self' 'unsafe-inline'; media-src *" />

    <link rel="stylesheet" href="./css/mobile-angular-ui-hover.min.css" />
    <link rel="stylesheet" href="./css/mobile-angular-ui-base.min.css" />
    <link rel="stylesheet" href="./css/mobile-angular-ui-desktop.min.css" />

    <link rel="stylesheet" type="text/css" href="./css/index.css" />

    <title>Hello World</title>

</head>

<body ng-app="myApp">

    <div class="app">

        <!-- Top Navbar -->

        <div class="navbar navbar-app navbar-absolute-top">

              <div class="btn-group justified">
                <a href="#/page1" class="btn btn-navbar">Page 1</a>
              </div>

        </div>

        <!-- Bottom Navbar -->

        <div class="navbar navbar-app navbar-absolute-bottom"></div>

        <!-- App Body -->
        <div class="app-body">

            <div class="app-content">

              <ng-view></ng-view>

            </div>

        </div>

    </div><!-- ~ .app -->

    <!-- Modals and Overlays -->
    <div ui-yield-to="modals"></div>

</body>

<!-- Libs -->
<script src="cordova.js"></script>

<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.6/angular-route.min.js"></script>

<script src="/js/mobile-angular-ui.min.js"></script>
<script src="/js/mobile-angular-ui.gestures.min.js"></script>

<!-- App -->
<script>
var app = {
    initialize: function()
    {
        this.bindEvents();
    },
    bindEvents: function()
    {
        document.addEventListener('deviceready', this.onDeviceReady, true);
    },

    onDeviceReady: function()
    {
        angular.element(document).ready(function()
        {
            angular.bootstrap(document, ['myApp']);
        });
    },
};


angular.module('myApp', ['ngRoute']).config(function($routeProvider)
{
    $routeProvider
    .when('/', {
        templateUrl: './views/page1.html'
    })
    .when('/page1', {
        templateUrl: './views/page1.html'
    });

});

app.initialize();
</script>

</html>

public class A extends X

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

我试图修改我当前生成comboBox的方法,这样它就会允许一个类型为A或B的ObservableList。

public class B extends X

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

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

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;
}

1 个答案:

答案 0 :(得分:1)

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

至于您的问题 - 问题是ComboBox<T>需要items属性为ObservableList<T>。由于您使用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的类型。此后所有通用变量都使用此类型参数,因此编译器可以知道所有匹配项。