Kotlin-通用功能

时间:2018-04-18 21:55:40

标签: swing generics kotlin

我目前正在尝试编写一个允许轻松构建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的东西

2 个答案:

答案 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