上一篇大概写了些报文开发初期项目的创建,以及一些开发前需要注意的开发技巧,这一篇大概说说开发中碰到的各种难题,以及对应的解决方法。
问题一:由于在船端开发的是桌面应用程序,主窗口用的是 WindowedApplication,大小为 900×500,如何让窗口在电脑屏幕中居中。
方法:
在窗口的 creationComplete 初始化函数中,加入如下代码即可。
- nativeWindow.x = (Capabilities.screenResolutionX - width) / 2;
- nativeWindow.y = (Capabilities.screenResolutionY - height) / 2;
注意:如果有闪烁的情况(就是先出现在左上角,又弹到屏幕中间),则把代码加入到窗口进入状态事件的回调方法中,如下:
- private function enterDefault():void{
- nativeWindow.x = (Capabilities.screenResolutionX - width) / 2;
- nativeWindow.y = (Capabilities.screenResolutionY - height) / 2;
- }
- <s:states>
- <s:State name="default" enterState="enterDefault()"/>
- </s:states>
问题二:WindowedApplication 窗体下面的状态栏如何去掉?
方法:在 <s:WindowedApplication 标签中添加属性 showStatusBar="false" 即可。
问题三:如何去掉 TitleWindow 标题栏?
方法:
- var tv:TestView = TestView(PopUpManager.createPopUp(this,TestView,true));//定义titilewindow
- UIComponent(tv.titleDisplay).parent.height = 0;//去除titilewindow标题栏
问题四:如何弹出窗口?
方法:
在主窗口外弹出新窗口:tv.open(true);
在主窗口内弹出新窗口:var tv:TestView = TestView(PopUpManager.createPopUp(this, TestView, true));
问题五: 点击按钮创建画面,当已创建画面在其它画面下方时,再次点击按钮,如何让画面浮动到最前方?
方法:
如果应用程序是 Application,用 PopUpManager.bringToFront() 即可。
如果应用程序是 WindowedApplication,则用 orderToFront() 函数。
注意:也别用 alwaysInFront 属性,这会让新创建的画面一直居于上方,无法下沉。
问题六:label 中文本太长,超出画面范围了,如何实现自动换行或者省略效果?
方法:
- label.maxDisplayedLines=0; // 默认多行显示,不截取
- label.maxDisplayedLines=1; // 任意整数,显示单行文本,自动截取(...)
- label.maxDisplayedLines=2; // 撑满label,可多行,显示不了的截取(...)
注意:一定要给 Label 组件同时加上 lineBreak="toFit" 和 width="" 才管用。
问题七:如何遍历对象中包含的所有键值对及其值?
方法:
- var xmlList:XMLList=describeType(obj)..variable;
- for each(var item:XML in xmlList) {
- keyStr += '"' + item.@name + '" : ';
- valStr += '"' + String(eo[item.@name]) + '", ';
- }
问题八:复制数组和清空数组的方法。
方法:
- /**
- * 复制数组
- */
- private function cloneArr(arr:Array):Array {
- var array:ByteArray = new ByteArray();
- array.writeObject (arr);
- array.position = 0;
- return array.readObject();
- }
- /**
- * 清空数组
- */
- public function clearArr(arr:Array):void {
- if (arr.length == 0) return;
- arr.splice(0);
- return;
- }
问题九:对数组排序的方法。
方法:arr.sort();
问题十:替换字符串中所有连续的空格为一个空格。
方法:str.replace(/( )+/g, " ");
问题十一:如何在窗口中添加菜单?
方法:
- /**
- * MenuBar点击事件
- */
- protected function menuBar_changeHandler(event:MenuEvent):void
- {
- switch (event.label as String) {
- case "SETTING":
- settingPanel = SettingPanel(PopUpManager.createPopUp(this, SettingPanel, true));
- PopUpManager.centerPopUp(settingPanel);
- break;
- }
- }
- <fx:Declarations>
- <fx:XMLList id="menuList">
- <menuitem id="setting" label="SETTING">
- </menuitem>
- </fx:XMLList>
- </fx:Declarations>
- <mx:MenuBar id="menuBar" y="0" width="900" dataProvider="{menuList}" labelField="@label"
- change="menuBar_changeHandler(event)" cornerRadius="0"/>
问题十二:Flex Air 桌面应用程序如何读写文本文件?(WEB 程序读文件详见问题十六)
方法:
- /**
- * 从指定文件读取数据
- */
- public function readFromFile(path:String, filename:String):String {
- var fs:FileStream = new FileStream();
- var txt:String = "";
- try {
- var file:File = File.applicationDirectory.resolvePath(changePath(path) + filename);
- fs.open(file, FileMode.READ);
- txt = fs.readUTFBytes(fs.bytesAvailable);
- } catch(e:Error) {
- trace("读取文件"+ filename +"时发生错误!");
- } finally {
- fs.close();
- }
- return txt;
- }
- /**
- * 向指定文件写入数据
- */
- public function writeToFile(path:String, filename:String, content:String):void {
- var fs:FileStream = new FileStream();
- try{
- var file:File = File.applicationDirectory.resolvePath(changePath(path) + filename);
- // var fp:File = file.parent;
- // fp.createDirectory();
- fs.open(file, FileMode.WRITE);
- fs.writeUTFBytes(content);
- } catch(e:IOErrorEvent) {
- Alert.show("写入文件"+ filename +"时发生错误!", "错误信息");
- } finally {
- fs.close();
- }
- }
- /**
- * 装换path路径
- */
- private function changePath(path:String):String {
- return path.replace(/\\/g, '\\\\') + "\\\\";
- }
问题十三:如何对 ArrayCollection 排序?
方法:
- private function sortByOrder(ac:ArrayCollection):Array {
- if (ac == null || ac.length == 0) {
- return null;
- } else {
- var sort:Sort = new Sort();
- sort.fields = [new SortField("name"),new SortField("code")];
- ac.sort = sort;
- ac.refresh();
- return ac.toArray();
- }
- }
问题十四:如何取得画面中所有组件的 id?
方法:
- /**
- * 取得画面中所有组件的ID并放入数组放回
- */
- private function getAllKey(obj:Object):Array {
- if (obj.hasOwnProperty("numElements")) {
- for (var i:int = 0; i < obj.numElements; i++) {
- // 获取子对象
- var child:Object = obj.getElementAt(i);
- // 如果该对象是下面的自定义组件,则不递归。
- if (child is OcnTextInputForDyna || child is OcnDropListButton
- || child is OcnDateMinuteButton || child is OcnTextAreaForDyna
- || child.hasOwnProperty("ocnGetStr")) {
- keyArr.push(child["id"]);
- continue;
- } else {
- getAllKey(child);//递归
- }
- }
- }
- return keyArr.sort();
- }
问题十五:自动保留小数点后几位?
方法:
- /**
- * 自动截取小数点后几位
- */
- public static function pointAftNBit(num:Number, n:int):String {
- var ns:String = num.toString();
- var pos:int = ns.indexOf(".");
- var s:String = ns.substring(pos+1, ns.length);
- // 不够指定小数位数则自动补齐
- if (pos == -1 || (pos != -1 && s.length < n)) {
- ns = num.toFixed(n);
- }
- return ns;
- }
问题十六:Flex Web 应用程序如何读文本文件?(Flex 桌面应用程序读写文本文件详细见问题十二)
方法:
注意:首先需要把 *.txt 重命名为 *.xml,然后修改文本内容,前后加上标签,如下:
- *.txt内容:
- aaaaa
- bbbbb
- ccccc
- 修改后的 *.xml内容:
- <config>
- <tag>
- aaaaa
- bbbbb
- ccccc
- </tag>
- </config>
需要初始化读取,并且需要配置加载文件:
- /**
- * 画面初始化中读取配置文件内容
- */
- protected function blmtitlewindow1_creationCompleteHandler(event:FlexEvent):void
- {
- var tagStr:String = taglist.tag;
- }
- <fx:Declarations>
- <fx:Model id="taglist" source="../assets/*.xml"/>
- </fx:Declarations>
问题十七:Flex 如何添加定时器?
方法:
- private var time:Timer = new Timer(10000);//定时器,定时刷新画面
- /**
- * 画面关闭按钮方法
- */
- protected function blmtitlewindow1_closeHandler(event:CloseEvent):void
- {
- if (time.running) {
- time.stop();
- }
- PopUpManager.removePopUp(this);
- }
- /**
- * 画面初始化
- */
- protected function blmtitlewindow1_creationCompleteHandler(event:FlexEvent):void
- {
- // 给定时器添加监听事件
- time.addEventListener(TimerEvent.TIMER,timeHandler);
- time.start();// 启动定时器
- }
另外,项目的主要思想就是,船端填写表单,如果通过校验后,可以拼串生成报文字符串,用 / 分割,而且组与组之间需要添加序号,点击保存后,保存到船端电脑硬盘中,格式为文本文件。
船上通过手动发送邮件的形式,把填写的各种报文发送到岸端服务器中,服务器得到邮件中的报文,自动下载,并保存到服务器中,同时自动保存到岸端数据库中,如果再岸端的 Web 程序中,打开报文画面,就可以查询出数据库中保存的报文。
点击后,需要把一个很长的报文字符串,通过解串,分别填写到画面中,画面与船端几乎相同。岸端可以修改船端填写并发送过来的报文,然后可以直接保存到数据库,当然,也需要通过校验才行。
一个多月的调研、开发、修改、测试,感觉东西老多了,可写完文章后,也就这么点东西。时间都花在绘制画面部分了!唯一最难的拼接串和解串的函数太庞大,也很乱套,这里就不贴了。还有一些杂七杂八的小知识,小想法,也一时说不明白,就这样吧。贴出来的东西是最基本的,方便以后查找,也给需要的朋友们一点参考吧。
备注:还有其它一些查询的资料,也备份一下。
注1:zip 打包,下面是一些第三方的类库地址以及介绍:
AS3 Zip: AS 3 下用来读取和写入zip文件的类库
FZip: FZip 是一个用于AS 3 下读取、创建、修改zip压缩包的类库
ASZip: AS 3 用于创建zip文件的类库
LZMA Encoder: AS3下使用LZMA算法压缩数据的类库.
LZMA Decoder: 跟上面类库对应的用于LZMA算法解压缩数据.
AsCompress: AS3下 GZIP压缩和解压缩类库,好像需要SDK版本在4.x以上,flash cs3下不可用。
Gzip for HTTPService/URLLoader: 给你的 Flex/AIR HTTPService/URLLoader增加gzip支持
airxzip: AIR的zip类库
注2:WindowedApplication 的一些属性和事件等,详细情况请参考官网API。
- The <mx:WindowedApplication> tag inherits all of the tag attributes of its superclass and adds the following tag attributes:
- <s:WindowedApplication
- Properties
- alwaysInFront="false"
- autoExit="true"
- backgroundFrameRate="1"
- dockIconMenu="null"
- menu="null"
- showStatusBar="true"
- status=""
- systemTrayIconMenu="null"
- title=""
- titleIcon="null"
- useNativeDragManager="true"
- Styles
- backgroundAlpha="1.0"
- backgroundColor="0xFFFFFF"
- resizeAffordanceWidth="6"
- Effects
- closeEffect="No default"
- minimizeEffect="No default"
- unminimizeEffect="No default"
- Events
- applicationActivate="No default"
- applicationDeactivate="No default"
- close="No default"
- closing="No default"
- displayStateChange="No default"
- displayStateChanging="No default"
- invoke="No default"
- moving="No default"
- networkChange="No default"
- resizing="No default"
- windowActivate="No default"
- windowComplete="No default"
- windowDeactivate="No default"
- windowMove="No default"
- windowResize="No default"
- />