I'm trying create some JavaFX buttons with FontAwesomeFX icons using TornadoFX. This is the code
data class ButtonInfo(val texto: String, val icon: GlyphIcon<*>)
val list = listOf(
ButtonInfo("Cadastro", FontAwesomeIconView(FontAwesomeIcon.ADDRESS_BOOK)),
ButtonInfo("Corrida", MaterialDesignIconView(MaterialDesignIcon.RUN)),
ButtonInfo("Classificacao", FontAwesomeIconView(FontAwesomeIcon.LIST)))
list.forEach {
it.icon.size = "3em"
val bt = Button(it.texto, it.icon)
bt.contentDisplay = ContentDisplay.TOP
bt.minWidth = 200.0
root += bt
}
In compilation I get this error:
Type parameter bound for T in var <T : Enum<T!>!> GlyphIcon<T>.size: String! where T : GlyphIcons!
is not satisfied: inferred type CapturedTypeConstructor(*) is not a subtype of GlyphIcons!
The GlyphIcon is a Java abstract class with this declaration:
public abstract class GlyphIcon<T extends Enum<T> & GlyphIcons> extends Text
I don't know how turn around this error. If I declare:
data class ButtonInfo(val texto: String, val icon: Text)
I don't get the above mentioned error, but I miss '.size' property. How I can declare my class 'ButtonInfo' so that this code works?
You didn't post your complete class, but it looks like you try to run the list.forEach
instruction outside any method or init block? Kotlin gets confused by the size
accessor, use setSize()
to avoid the issue.
Here is a complete class with minimal changes to your sample that compiles and runs, and shows you the icons in a vbox.
data class ButtonInfo(val texto: String, val icon: GlyphIcon<*>)
class IconView : View() {
val list = listOf(
ButtonInfo("Cadastro", FontAwesomeIconView(FontAwesomeIcon.ADDRESS_BOOK)),
ButtonInfo("Corrida", MaterialDesignIconView(MaterialDesignIcon.RUN)),
ButtonInfo("Classificacao", FontAwesomeIconView(FontAwesomeIcon.LIST)))
override val root = vbox {
list.forEach {
it.icon.setSize("3em")
button(it.texto, it.icon) {
contentDisplay = ContentDisplay.TOP
minWidth = 200.0
}
}
}
}
I used the button
builder instead of manually adding to the root node.
Let me offer an alternative:
class IconView : View() {
override val root = vbox {
button("Cadastro").icon(FontAwesomeIcon.ADDRESS_BOOK)
button("Corrida").icon(MaterialDesignIcon.RUN)
button("Classificacao").icon(FontAwesomeIcon.LIST)
}
}
Then you define this function in a utility file:
fun Button.icon(icon: GlyphIcons, minButtonWidth: Double = 200.0) {
graphic = when (icon) {
is FontAwesomeIcon -> FontAwesomeIconView(icon)
is MaterialDesignIcon -> MaterialDesignIconView(icon)
else -> throw IllegalArgumentException("Unknown font family ${icon.fontFamily}")
}
with(graphic as GlyphIcon<*>) {
contentDisplay = ContentDisplay.TOP
setSize("3em")
}
minWidth = minButtonWidth
}
It makes it much easier to see what's going on at the call site.
Also, the setSize("3em")
is only there to support Scene Builder. Consider using the glyphSize
accessor instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With