Announcement Announcement Module
Collapse
No announcement yet.
Help:ApplicationEvent can't be published to commands-context Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Help:ApplicationEvent can't be published to commands-context

    Hi,

    I encountered a problem on pulishing ApplicaitionEvent from "application-context" to "commands-context". I have a button, "exportTabletCommand", defined in "commands-context". This button is disabled in intialization, and depends on the database connection status to enable it. The db connection operation is in a wizard defined in "application-context", and the wizard's "onFinish" will pulish an ApplicatinEvent:

    Code:
    protected boolean onFinish(){
        wizardForm.commit();
        try{
            //Connect to DB
           ...............
    
        DatabaseConnectionEvent evt = new DatabaseConnectionEvent(this);
        evt.setIpDbConnected(true);
    			
        getApplicationContext().publishEvent(evt);
    
       .....
    			
        return true;
    }
    ( My "DatabaseConnectionEvent" extends from ApplicationEvent ).

    The "exportTabletCommand" is listening on ApplicationEvent to set itself enabled/disabled:

    Code:
    public class ExportTabletCommand extends TargetableActionCommand implements   ApplicationListener {
    	
      public void onApplicationEvent(ApplicationEvent event) {
        if( event instanceof DatabaseConnectionEvent){
          DatabaseConnectionEvent dbevent = (DatabaseConnectionEvent)event;
          if( dbevent.isIpDbConnected() ){
              this.setEnabled(true);
          }
    
          .......................
    }
    I assume that all the beans which implement "ApplicationListener" could capture the ApplicationEvent, whether the beans are defined in "application-context" or "commands-context". But I found that, the " ExportTabletCommand" listener can't capture any ApplicationEvent( it is defined in "commands-context"). But, when I tried to move its definition to "application-context", it can capture ApplicaitonEvent!

    I am wondering: could the ApplicationEvent be published from beans defined in "application-context" to the beans defined in "commands-context"? In my case, I do believe this is neccessary. Or, is there any better way to do it?

    Thanks a lot in advance.

  • #2
    Browsed the rcp pet-clinic, and found that the new "Owner" is created and then populated to the "OwnerView" through ApplicationEvent. The way it works is that both wizard and owner view are defined in "application context".

    Another thing I found out is that the "commands context" is read into a BeanFactory rather than ApplicationContext. I think this is the reason why the beans defined in "commands-context" can't receive application event...

    Am I all right? Thoughts?

    ( I still can't figure out how can I enable/disable the command button dynamaticly, based on the Wizard execution result?... )

    Comment


    • #3
      I'll think on this, but yes, define that Wizard controller as a singleton in your app context: not in the command context. There is no problem, a GUI executes single threaded remember.

      The command context should contained window-scoped command definitions only.

      To disable: make your Wizard implement GuardedActionCommandExecutor: IT SHOULD TRACK WHEN IT SHOULD BE ENABLED. Fire an event when it should be enabled/disabled.

      I'm beginning to think the inheritent un-OOness of a web environment is causing us to forget those OO principles. :-)

      Comment


      • #4
        keith,

        It sovled my problem! Thanks so much.

        The only little annoying thing is, I can't find a proper abstract class to extend from -- which implements both Wizard interface and GuardedActionCommandExecutor interface. So, I choose made my wizard continueing extends from "AbstractWizard", and have to copy code from "AbstractActionCommandExecutor"( which implements GuardedActionCommandExecutor ) and paste to my wizard. Is this you are thinking about?

        I paste my code here, hope could help others who could run into the same problem as me:


        In application-context:


        <bean id="exportTabletWizard"
        class="com.sjv.iptools.export.vtablet.ui.ExportTab letWizard" lazy-init="true">
        <constructor-arg index="0">
        <ref local="exportConfig"/>
        </constructor-arg>
        <property name="enabled"><value>false</value></property>
        </bean>

        <bean id="connectDBWizard"
        class="com.sjv.iptools.export.vtablet.ui.ConnectDB Wizard" lazy-init="true">
        <constructor-arg index="0">
        <ref local="dbConfig"/>
        </constructor-arg>
        </bean>
        In commands-context:
        <bean id="exportTabletCommand"
        class="org.springframework.richclient.command.Targ etableActionCommand">
        <property name="commandExecutor">
        <ref bean="exportTabletWizard"/>
        </property>

        </bean>

        <bean id="connectDBCommand"
        class="org.springframework.richclient.command.Targ etableActionCommand">
        <property name="commandExecutor">
        <ref bean="connectDBWizard"/>
        </property>
        </bean>
        ConnectDBWizard:

        Code:
        public class ConnectDBWizard extends AbstractWizard implements
        		ActionCommandExecutor &#123;
        	 
        	protected boolean onFinish&#40;&#41;&#123;
        		wizardForm.commit&#40;&#41;;
        		System.out.println&#40;dbConfig&#41;;
        		try&#123;
                                                       //Connect to DB here...
        			
        			DatabaseConnectionEvent evt = new DatabaseConnectionEvent&#40;this&#41;;
        			evt.setType&#40;DatabaseConnectionEvent.IPDB_CONNECTION_EVENT&#41;;
        			evt.setIpDbConnected&#40;true&#41;;
        			
        			getApplicationContext&#40;&#41;.publishEvent&#40;evt&#41;;
        			
        		&#125;catch &#40;Throwable e&#41;&#123;
        			e.printStackTrace&#40;System.err&#41;;		
        		&#125;
        		return true;
        	&#125;
        
        ............................
        ExportTabletWizard:

        Code:
        public class ExportTabletWizard extends AbstractWizard implements
        		GuardedActionCommandExecutor, ApplicationListener &#123;
        	
        	///////////////////////////////
        	/*
        	 * Implements GuardedActionCommandExecutor
        	 */
            private ValueModel enabled = new ValueHolder&#40;Boolean.FALSE&#41;;
        
            public boolean isEnabled&#40;&#41; &#123;
                return &#40;&#40;Boolean&#41;enabled.getValue&#40;&#41;&#41;.booleanValue&#40;&#41;;
            &#125;
        
            public void setEnabled&#40;boolean enabled&#41; &#123;
                this.enabled.setValue&#40;Boolean.valueOf&#40;enabled&#41;&#41;;
            &#125;
        
            public void addEnabledListener&#40;ValueChangeListener listener&#41; &#123;
                enabled.addValueChangeListener&#40;listener&#41;;
            &#125;
        
            public void removeEnabledListener&#40;ValueChangeListener listener&#41; &#123;
                enabled.removeValueChangeListener&#40;listener&#41;;
            &#125;
        
            /////////////////////////////////
            /*
             * Implements ApplicationListener
             */
        	public void onApplicationEvent&#40;ApplicationEvent event&#41; &#123;
        		if&#40; event instanceof DatabaseConnectionEvent&#41;&#123;
        			DatabaseConnectionEvent dbevent = &#40;DatabaseConnectionEvent&#41;event;
        			if&#40; dbevent.isIpDbConnected&#40;&#41; == true &#41;&#123;
        				this.setEnabled&#40;true&#41;;
        			&#125;
        		&#125;
        		
        	&#125;	
        .............................
        &#125;
        ..........................

        Comment


        • #5
          We need to make this easier.

          Can you open a JIRA issue saying "make this easier" so it doesn't get lost?

          Thanks and glad you got it working!

          Keith

          Comment


          • #6
            sure. I am glad to do it

            By the way, I like your way that set the "command button" enabled/disabled based on the underlying "Executor" status -- this is more reasonable.

            Thanks again.

            Comment

            Working...
            X