PDA

View Full Version : Help:ApplicationEvent can't be published to commands-context


linwei
Nov 21st, 2004, 01:52 PM
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:


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:


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.

linwei
Nov 22nd, 2004, 03:21 PM
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?... )

Keith Donald
Nov 22nd, 2004, 03:32 PM
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. :-)

linwei
Nov 22nd, 2004, 07:15 PM
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.ExportTabletWiza rd" 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.ConnectDBWizard" lazy-init="true">
<constructor-arg index="0">
<ref local="dbConfig"/>
</constructor-arg>
</bean>



In commands-context:

<bean id="exportTabletCommand"
class="org.springframework.richclient.command.TargetableA ctionCommand">
<property name="commandExecutor">
<ref bean="exportTabletWizard"/>
</property>

</bean>

<bean id="connectDBCommand"
class="org.springframework.richclient.command.TargetableA ctionCommand">
<property name="commandExecutor">
<ref bean="connectDBWizard"/>
</property>
</bean>



ConnectDBWizard:


public class ConnectDBWizard extends AbstractWizard implements
ActionCommandExecutor {

protected boolean onFinish(){
wizardForm.commit();
System.out.println(dbConfig);
try{
//Connect to DB here...

DatabaseConnectionEvent evt = new DatabaseConnectionEvent(this);
evt.setType(DatabaseConnectionEvent.IPDB_CONNECTIO N_EVENT);
evt.setIpDbConnected(true);

getApplicationContext().publishEvent(evt);

}catch (Throwable e){
e.printStackTrace(System.err);
}
return true;
}

............................


ExportTabletWizard:



public class ExportTabletWizard extends AbstractWizard implements
GuardedActionCommandExecutor, ApplicationListener {

///////////////////////////////
/*
* Implements GuardedActionCommandExecutor
*/
private ValueModel enabled = new ValueHolder(Boolean.FALSE);

public boolean isEnabled() {
return ((Boolean)enabled.getValue()).booleanValue();
}

public void setEnabled(boolean enabled) {
this.enabled.setValue(Boolean.valueOf(enabled));
}

public void addEnabledListener(ValueChangeListener listener) {
enabled.addValueChangeListener(listener);
}

public void removeEnabledListener(ValueChangeListener listener) {
enabled.removeValueChangeListener(listener);
}

/////////////////////////////////
/*
* Implements ApplicationListener
*/
public void onApplicationEvent(ApplicationEvent event) {
if( event instanceof DatabaseConnectionEvent){
DatabaseConnectionEvent dbevent = (DatabaseConnectionEvent)event;
if( dbevent.isIpDbConnected() == true ){
this.setEnabled(true);
}
}

}
.............................
}
..........................

Keith Donald
Nov 22nd, 2004, 07:18 PM
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

linwei
Nov 22nd, 2004, 07:25 PM
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.