Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI initialization with Inheritance #52

Open
IARI opened this issue Jan 22, 2018 · 3 comments
Open

UI initialization with Inheritance #52

IARI opened this issue Jan 22, 2018 · 3 comments

Comments

@IARI
Copy link

IARI commented Jan 22, 2018

Consider the followingFragment class and its child class:

open class A : Fragment("") {
    override val root = vbox {
        addStuff(this)
        ...
    }
   open fun addStuff(b: VBox) {
      ...
   }
}

class B : A {
   val labelText = SimpleStringProperty()   
   override fun addStuff(b: VBox) {
       super.addStuff(b)
       b.apply {
          label(labelText)
       }
   }
}

I want Classes inheriting from A to be able to add their own stuff in some subpart of the A.root.
This setup leads to an NPE (labelText is null) due to the order in which initialization happens with Kotlin (as explained here).

How can this be achieved properly?

@IARI
Copy link
Author

IARI commented Jan 22, 2018

I have found that initializing the root lazy (by lazy { ... }) does not work out of the box.
The problem is in FX.kt in line 512:

        is UIComponent -> root?.addChildIfPossible(node)

It seems that here it is assumed, that root is not initialized by a getter or delegate - or at least that before initialization root at least yields null at least one time.
If that is not the case (as with by lazy { ... }) it will result in a stackoverflow.

A workaround I found for now is to avoid the builder implementation in FX.kt, by doing something like this:

    override val root by lazy {
        VBox().apply {
            ...
        }
    }

works, but its not exactly what I would call a nice solution ;)

@edvin
Copy link
Owner

edvin commented Jan 23, 2018

You're right, the framework expects the root to be created at once, and there are probably more cases of that than the one you ran into. You might have better success by overriding onDock in your subclass. In general I've not found much need for subclassing UIComponents at all, and I wonder if it's the right solution for your use case as well. If you can elaborate, maybe we can come up with a better solution :)

@IARI
Copy link
Author

IARI commented Jan 23, 2018

Thanks for the advice.
My Application is basically about templatese for (latex) documents.
There is a template for letters, a model datastructure that is used to fill the template, and a view (LetterView : Fragment) , which is used to input or edit the model.

There are special types of Letters (like an invoice) whose models contain additional information.
So far, the most straight forward way to realize the corresponding view seemed to be inheritance for me.

Would you recommend a different approach? composition?

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

No branches or pull requests

2 participants