Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
CDI and custom components basic question
Hey guys, I'm new to vaadin and CDI but I am liking the combination a lot. I have a general question about crating custom components and the best practices to use them with CDI, hopefuly someone will understand it and be able to guide me :)
I won't be posting a lot of code example right now, as I don't think it will be necessary since the question isn't really complex. But if it eventually becomes necessary, i will create an example project.
Let's start then. I created a custom component (lets call it CC) that extends VerticalLayout and has a proprietary Service injected into it, but I didn't make CC's scope explicit yet (like @NormalViewScoped). In this component, I declared an init method (not a @PostConstruct) which receives a pojo as parameter and populates its fields.
After this, i declared a CDIView that has a TabSheet. It starts with one tab, which will have a table on it, populated by the same type of pojo as before. I added a clicklistener to the table so that once someone clicks on one of the items it does the following:
- Checks if a Tab with caption equals to the pojo's name attribute already exists in the TabSheet.
- If it does, set such tab as selected.
- If it doesn't, then it creates a CC, calls its init method with the clicked pojo, and adds CC as a new tab with the pojo name as caption.
Before utilizing cdi, I would simply call new CC() and then init(pojo). However, now i am Injecting something into CC, therefore i can't actually call new, otherwise the injection will not work. I thought of injecting CC into the CDIVIew, but it would only be one attribute which would have its fields overwritten, whereas what i actually need is always a new instance of CC to be added to the tabsheet.
Is there an elegant way to solve this with vaadin and cdi? The approach i had to take was the following:
I created a class that handles CC production, CCProducer. I injected the service into it and created a getCC method, that:
- Receives the pojo as param
- Creates a new CC (removed injection from it, went back to using new CC() )
- Initializes the CC with the POJO
- Sets the new CC service with the producer's injected service
- Returns CC
Then i injected this new producer class to my cdi view, and where i would create the new tabs i replaced the calls for the producer's getCC method.
The problem i see with this approach, is that if i ever want to add something to CC, like say a button that opens a custom window with injected stuff, I won't be able to inject the window to it and etc, because CC went back to being a non JEE class..
Suggestions?
Hello Jorge,
You can inject an Instance of your CC, like this:
@Inject Instance<CC> myCC;
Then, when you need a new instance of the CC, do this:
addComponent(myCC.get());
Hope this helps!
-Petter-
Petter,
Only had time to test it now, but using Instance<> solved everything i needed and more. Thank you so much for the reply :)
Jorge