Reputation: 13
I'm doing a project using Java + Flex. I created Java class and used Flex remote object to invoke the method. When I write all the code in an mxml, it runs well. But when I wrap the script in an as file, there's something curious. I need to click twice on Flex button to get the result which returned by the remote object. I think there's something wrong with my as file.
Below is my MXML:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
minWidth="500" minHeight="600">
<fx:Declarations>
<mx:RemoteObject id="Control" destination="Control" showBusyCursor="true" />
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.wntime.ControlUtil;
import mx.rpc.events.ResultEvent;
private var resultOfCmd:String;
private var cmdStr:String;
private var ct:ControlUtil = new ControlUtil();
/* invoke as method */
private function test():void
{
cmdStr = cmdTxt.text;
resultOfCmd = ct.exec(cmdStr);
cmdConsole.text = resultOfCmd;
}
/* */
private function exec():void{
cmdStr = cmdTxt.text;
Control.execCmd(cmdStr);
Control.addEventListener(ResultEvent.RESULT,execCmd_clickHandler);
}
private function execCmd_clickHandler(event:ResultEvent):void
{
cmdConsole.text = event.result.toString();
}
private function clearCmdConsole():void
{
cmdConsole.text = "";
}
]]>
</fx:Script>
<s:Panel id="CmdPanel" x="70" y="50" width="501" height="350" title="Command Execute Panel">
<s:RichText x="20" y="33" fontSize="14" text="Cmd:"/>
<s:TextInput id="cmdTxt" x="60" y="30" width="239"/>
<s:Button id="execCmd" x="312" y="30" width="68" label="execute" click="exec()"/>
<s:Button x="400" y="30" label="CmdTest" click="test()"/>
<s:TextArea id="cmdConsole" x="20" y="85" width="450" editable="false"/>
<s:Button x="400" y="250" label="clear" click="clearCmdConsole()"/>
</s:Panel>
</s:Application>
Here is the as file which named ControlUtil:
package com.wntime{
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.RemoteObject;
public class ControlUtil
{
private var cmd:String = null;
private var result:String = null;
private var roControl:RemoteObject = new RemoteObject();
public function ControlUtil()
{
roControl.destination = "Control";
}
public function exec(_cmd:String):String{
this.cmd = _cmd;
roControl.execCmd(cmd);
roControl.addEventListener(FaultEvent.FAULT, execCmd);
roControl.addEventListener(ResultEvent.RESULT, execCmd);
return result;
}
public function execCmd(event:ResultEvent):void
{
setResult(event.result.toString());
}
public function setResult(_result:String):void
{
this.result = _result;
}
}
}
If I click the execute button. The result will show in the console(the textarea) directly. But I need to click twice on CmdTest button to get the result to show in the console.
Give me a hand plz.Thanks in advance.
Upvotes: 0
Views: 693
Reputation: 6836
Your code has various errors/problem in my opinion, I would do something like that:
package com.wntime{
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.RemoteObject;
public class ControlUtil
{
private var cmd:String = null;
private var result:String = null;
private var roControl:RemoteObject = new RemoteObject();
// the callBack function is the function that is called when the
// remoteobject successfully or not complete the request...
// you can set as parameters anything you want...
private var callBack:Function = null;
public function ControlUtil()
{
roControl.destination = "Control";
}
public function exec(callBack:Function, _cmd:String):void{
this.cmd = _cmd;
this.callBack = callBack;
roControl.addEventListener(FaultEvent.FAULT, errorCmd);
roControl.addEventListener(ResultEvent.RESULT, execCmd);
roControl.execCmd(cmd);
}
private function execCmd(event:ResultEvent):void
{
callBack(true,event.result.toString());
}
private function errorCmd(event:FaultEvent):void
{
callBack(false, event.error); // call the callBack function passing the value you need
}
}
}
the callBack function is something like that:
private function name(b:Boolean, s:String = null){....}
* EDIT *
from your main code you invoke the exec command...
// function invoked when the button is clicked!
private function buttonClick():void
{
var tmp:ControlUtil = new ControlUtil();
//exec(callBack:Function, _cmd:String)
//you pass the function as a reference so when the async request is terminated the function is invoked and you can parse the result....
tmp.exec(getResult, "cmqString");
}
// callBack function for the method ControlUtil.exec
private function getResult(b:Boolean, result:String = ""):void
{
if (b)
{
// the call returned correctly and the result variable contains the value.
}
else
{
// the call failed and the result variable contains the error
}
}
Both the boolean and the result value are returned because I specified it in the ControlUtil when i used callBack(true/false, result/error)
You can create the function as you prefer...
Upvotes: 0
Reputation: 1638
This is just a wild guess, but I think the method you invoke at the Java side returns faster than you add your listeners, hence no event handler is called. The second time all listeners are in place and your call succeeds. Try adding your listeners before you invoke remote method.
Upvotes: 1