3 Replies Latest reply on Jul 2, 2013 3:26 AM by Marko Lukša

    Creating a custom context for JavaFX

    philipp91 Newbie

      Hi everyone,

       

      I am trying to create something like a @WindowScoped Context for JavaFX, similar to @ViewScoped in JSF. It should be a scope per "Scene" or "Stage". In order to, I implemented the Context-interface (using AbstractContext) and whenever I want to open a new Stage, I fire a CDI event with the content for the new window and have it handled by a management bean that creates a new BeanStore, hands it to the Context-implementation and then instantiates the Stage and everything else. This way, my JavaFX-Controllers are CDI-Beans.

      All this works perfectly fine at the beginning, because the injection happens right when the window is being created.

       

      But when I access an injected bean at later time (e.g. because of some mouse-event), the injected proxy calls my Context implementation (again!), which is now supposed to still remember the "window from before" and return the corresponding bean. However, I don't manage to assign that call to the corresponding scope.

      Looking at other Context implementations, I noticed that most of them are based on ThreadLocal to solve this problem, which is not possible with JavaFX.

       

      So in short, my problem is:

      In Context.get(), I am supposed to know "out of the blue", which bean to return. I have a list of all windows and their BeanStores, but which one to take?

       

      I am aware, that it is not possible to handle all requests here, e.g. one coming from an @ApplicationScoped bean cannot be assigned to a window scope, of course. But I want to handle all requests coming from a specific window by returning the corresponding scope instance. However, I can't get any information about where the call came from.

       

      Any help is appreciated! Thanks in advance.

        • 1. Re: Creating a custom context for JavaFX
          Marko Lukša Apprentice

          When a button is clicked, the button event (or whatever it's called) has a reference to the button. You can then traverse up the component tree from the button up until you find the window. Storing this window in a threadLocal would allow your context to know what beans to return. Of course you do need to make sure you set the threadlocal before any of your application's button listeners are called.

          1 of 1 people found this helpful
          • 2. Re: Creating a custom context for JavaFX
            philipp91 Newbie

            That would require me to do that for every button I need to use for this, right? I'm pretty sure it would work that way. But if I need to have some code for every button, I wouldn't need any dependency injection in the first place - I could just work with local variables in the window and retrieve them after traversing up the component tree.

            • 3. Re: Creating a custom context for JavaFX
              Marko Lukša Apprentice

              You can probably avoid adding a listener to every button by hooking into the class that actually dispatches events. In Swing, you can do this through Toolkit.getDefaultToolkit().getSystemEventQueue().push(new MyEventQueue()). JavaFX probably has something similar to this.

               

              Dependency injection (or even just a simple ThreadLocal without DI) would allow you to access the window in which the event occured in any class that needs it. Without the ThreadLocal, you'd have to pass a reference pointing to the window to every method that needs it.