Skip to content
This repository has been archived by the owner on Sep 28, 2024. It is now read-only.

[QUESTION] Make own abstract TornadoFX Fragment class with own root #1333

Open
fichtelmann opened this issue Jun 24, 2021 · 4 comments
Open

Comments

@fichtelmann
Copy link

I want to avoid duplicate code. I want to implement something like a dashboard. Within this dashboard, I want to involve different small fragments with a title. So in general, every dashboard fragment looks the same, but the content should be different. I tried different approaches but I wasn't able to implement them. Basically what I want to reach is to have a new abstract class that acts the same as a fragment but the root of this fragment is already inside of this new dashboard fragment. The following code snippet will generally explain what I want to reach:

abstract class DashboardFragment : Fragment() {

val titleName = SimpleStringProperty("Title of this fragment")
val fragment = anchorpane {
    val titleLabel = label(titleName) {
        style {
            prefHeight = 50.0.px
            minHeight += 50.0.px
            maxHeight += 50.0.px
            backgroundColor += Color.BLUE
        }
        anchorpaneConstraints {
            leftAnchor = 0.0
            rightAnchor = 0.0
            topAnchor = 0.0
        }
    }
    
    anchorpane {
        anchorpaneConstraints {
            topAnchor = 50.0 //height of the title label
            leftAnchor = 0.0
            rightAnchor = 0.0
            bottomAnchor = 0.0
        }
        style {
            backgroundColor += Color.RED
        }
        //Space for fragment content. The new root
    }
}
}

And I want to be able to use it like this:

class AnalyzeFragment : DashboardFragment() {

    override val root = anchorpane {
        label("My analyzed data")
    }
}

And what I want to reach is that my label with "My analyzed data" is inside the anchorpane of my DashboardFragment. So that the title label above is always there and is adaptable by its property.

@SchweinchenFuntik
Copy link
Contributor

If you only have a GUI build, why not just create a function, or Create a class inherited from Parent? Or do you want it through Fragment (UICOmponent)?

@fichtelmann
Copy link
Author

If you only have a GUI build, why not just create a function, or Create a class inherited from Parent? Or do you want it through Fragment (UICOmponent)?

Can't follow you. Can you give an example? As I understood you want that my DashboardView provides a method to add new fragments?
I think the smartest way would be an own abstract class. At least each implementation of it should be flexible in size and content. Just the frame is defined.

@SchweinchenFuntik
Copy link
Contributor

SchweinchenFuntik commented Jun 26, 2021

No.

fun EventTarget.dashboard(builder: AnchorPane.() -> Unit) {
anchorpane {
    val titleLabel = label(titleName) {
        style {
            prefHeight = 50.0.px
            minHeight += 50.0.px
            maxHeight += 50.0.px
            backgroundColor += Color.BLUE
        }
        anchorpaneConstraints {
            leftAnchor = 0.0
            rightAnchor = 0.0
            topAnchor = 0.0
        }
    }
    
    anchorpane {
        anchorpaneConstraints {
            topAnchor = 50.0 //height of the title label
            leftAnchor = 0.0
            rightAnchor = 0.0
            bottomAnchor = 0.0
        }
        style {
            backgroundColor += Color.RED
        }
        //Space for fragment content. The new root
        builder()
    }
}
}
}

@fichtelmann
Copy link
Author

Hey, extension function is a good idea. But I don't know why its not working. I've tried it in two ways. First:

class DashboardInfoFragment : Fragment() {
    override val root = anchorpane {
        dashboard {
            button("Content")
        }
    }
}

But I get an exception when load the view:

SEVERE: Uncaught error
kotlin.TypeCastException: null cannot be cast to non-null type tornadofx.Dimension<tornadofx.Dimension.LinearUnits>
	at tornadofx.PropertyHolder$$special$$inlined$cssprop$57.getValue(CSS.kt:849)
	at tornadofx.PropertyHolder$$special$$inlined$cssprop$57.getValue(CSS.kt:845)
	at tornadofx.PropertyHolder.getMinHeight(CSS.kt)

If I remove minHeight and maxHeight of the style part its working, but why?

And when I try to use it this way (which would be my preferred way):

override val root = dashboard {
            button("Content")
        }
    }

I need to add a return type of parent to the function but to be frank I don't know what I shall return or how.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants