我目前正在尝试编写一个允许轻松构建Swing用户界面的dsl。为了实现这一目标而不必支持所有类型的组件,我想创建一个通用函数来添加容器,在我的例子中,这意味着扩展JPanel
的所有内容。
我最终得到的是:
fun <T : JPanel> container(containerComponent: T = JPanel(), constraints: LC = LC(), setup: T.() -> Unit): T {
containerComponent.setup()
containerComponent.layout = MigLayout(constraints)
return containerComponent
}
然而,在第一行,在第一个参数,我得到一个错误Type mismatch: Required T, but found JPanel
,但我不明白为什么,因为我指定T将是扩展JPanel
的东西
答案 0 :(得分:2)
正如@shmosel已经指出的那样,T
可能仍然不是JPanel
,这会导致JPanel
不满足T
。
以下是一个人可能做的例子:
val setup: JPanelExtendingClass.() -> Unit = {
//Perform actions on splitpane
}
container(constraints = LC(), setup = setup)
这会导致T
JPanelExtendingClass
JPanel
不符合。{/ p>
因此,我最终将整个事物分成两个方法,一个专门用于JPanel
fun panel(constraints: LC = LC(), setup: JPanel.() -> Unit): JPanel {
return container(JPanel(), constraints, setup)
}
和另一个延长JPanel
fun <T : JPanel> container(containerComponent: T, constraints: LC = LC(), setup: T.() -> Unit): T {
containerComponent.setup()
containerComponent.layout = MigLayout(constraints)
return containerComponent
}
这个没有定义任何默认组件。
答案 1 :(得分:0)
您希望拥有一个可以将任何JPanel类型作为参数的函数,如果没有指定参数值,则它将是JPanel。
现在假设您正在以这种方式调用该函数:
@Input and @Output
在这种情况下,container<JPanelExtendingClass> { ... }
参数的类型将为containerComponent
,值为JPanelExtendingClass
。
JPanel()
不是JPanel
的子类,因此编译器会拒绝它。
在这里,您实际上并不需要该函数是通用的,您可以将函数更改为
JPanelExtendingClass