我有两种类,它们扩展了类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;
}
答案 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
的类型。此后所有通用变量都使用此类型参数,因此编译器可以知道所有匹配项。