现在位置: 首页 > 博客文章 > 电脑相关 > IT开发 > 开发语言 > Flex > 正文
船舶报文系统项目之开发篇
2015年08月04日 17:04:56 Flex ⁄ 共 8137字 暂无评论 ⁄ 被围观 1,917次

上一篇大概写了些报文开发初期项目的创建,以及一些开发前需要注意的开发技巧,这一篇大概说说开发中碰到的各种难题,以及对应的解决方法。

问题一:由于在船端开发的是桌面应用程序,主窗口用的是 WindowedApplication,大小为 900×500,如何让窗口在电脑屏幕中居中。

方法:

在窗口的 creationComplete 初始化函数中,加入如下代码即可。

Code   ViewPrint
  1. nativeWindow.x = (Capabilities.screenResolutionX - width) / 2;
  2. nativeWindow.y = (Capabilities.screenResolutionY - height) / 2;

 

注意:如果有闪烁的情况(就是先出现在左上角,又弹到屏幕中间),则把代码加入到窗口进入状态事件的回调方法中,如下:

Code   ViewPrint
  1. private function enterDefault():void{
  2.     nativeWindow.x = (Capabilities.screenResolutionX - width) / 2;
  3.     nativeWindow.y = (Capabilities.screenResolutionY - height) / 2;
  4. }
  5. <s:states>
  6.     <s:State name="default" enterState="enterDefault()"/>
  7. </s:states>

 

问题二:WindowedApplication 窗体下面的状态栏如何去掉?

方法:在 <s:WindowedApplication 标签中添加属性 showStatusBar="false" 即可。

问题三:如何去掉 TitleWindow 标题栏?

方法:

Code   ViewPrint
  1. var tv:TestView = TestView(PopUpManager.createPopUp(this,TestView,true));//定义titilewindow
  2. 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 中文本太长,超出画面范围了,如何实现自动换行或者省略效果?

方法:

Code   ViewPrint
  1. label.maxDisplayedLines=0; // 默认多行显示,不截取
  2. label.maxDisplayedLines=1; // 任意整数,显示单行文本,自动截取(...)
  3. label.maxDisplayedLines=2; // 撑满label,可多行,显示不了的截取(...)

 

注意:一定要给 Label 组件同时加上 lineBreak="toFit" 和 width="" 才管用。

问题七:如何遍历对象中包含的所有键值对及其值?

方法:

Code   ViewPrint
  1. var xmlList:XMLList=describeType(obj)..variable;
  2. for each(var item:XML in xmlList) {
  3.     keyStr += '"' + item.@name + '" : ';
  4.     valStr += '"' + String(eo[item.@name]) + '", ';
  5. }

 

问题八:复制数组和清空数组的方法。

方法:

Code   ViewPrint
  1. /**
  2.  * 复制数组
  3.  */
  4. private function cloneArr(arr:Array):Array {
  5.     var array:ByteArray = new ByteArray();
  6.     array.writeObject (arr);
  7.     array.position = 0;
  8.     return array.readObject();
  9. }
  10. /**
  11.  * 清空数组
  12.  */
  13. public function clearArr(arr:Array):void {
  14.     if (arr.length == 0return;
  15.     arr.splice(0);
  16.     return;
  17. }

 

问题九:对数组排序的方法。

方法:arr.sort();

问题十:替换字符串中所有连续的空格为一个空格。

方法:str.replace(/( )+/g, " ");

问题十一:如何在窗口中添加菜单?

方法:

Code   ViewPrint
  1. /**
  2.  * MenuBar点击事件
  3.  */
  4. protected function menuBar_changeHandler(event:MenuEvent):void
  5. {
  6.     switch (event.label as String) {
  7.         case "SETTING":
  8.             settingPanel = SettingPanel(PopUpManager.createPopUp(this, SettingPanel, true));
  9.             PopUpManager.centerPopUp(settingPanel);
  10.             break;
  11.     }
  12. }
  13. <fx:Declarations>
  14.     <fx:XMLList id="menuList">
  15.         <menuitem id="setting" label="SETTING">
  16.         </menuitem>
  17.     </fx:XMLList>
  18. </fx:Declarations>
  19. <mx:MenuBar id="menuBar" y="0" width="900" dataProvider="{menuList}" labelField="@label"
  20.                 change="menuBar_changeHandler(event)" cornerRadius="0"/>

 

问题十二:Flex Air 桌面应用程序如何读写文本文件?(WEB 程序读文件详见问题十六)

方法:

Code   ViewPrint
  1. /**
  2.  * 从指定文件读取数据
  3.  */
  4. public function readFromFile(path:String, filename:String):String {
  5.     var fs:FileStream = new FileStream();
  6.     var txt:String = "";
  7.     try {
  8.         var file:File = File.applicationDirectory.resolvePath(changePath(path) + filename);
  9.         fs.open(file, FileMode.READ);
  10.         txt = fs.readUTFBytes(fs.bytesAvailable);
  11.     } catch(e:Error) {
  12.         trace("读取文件"+ filename +"时发生错误!");
  13.     } finally {
  14.         fs.close();
  15.     }
  16.     return txt;
  17. }
  18. /**
  19.  * 向指定文件写入数据
  20.  */
  21. public function writeToFile(path:String, filename:String, content:String):void {
  22.     var fs:FileStream = new FileStream();
  23.     try{
  24.         var file:File = File.applicationDirectory.resolvePath(changePath(path) + filename);
  25. //              var fp:File = file.parent;
  26. //              fp.createDirectory();
  27.         fs.open(file, FileMode.WRITE);
  28.         fs.writeUTFBytes(content);
  29.     } catch(e:IOErrorEvent) {
  30.         Alert.show("写入文件"+ filename +"时发生错误!""错误信息");
  31.     } finally {
  32.         fs.close();
  33.     }
  34. }
  35. /**
  36.  * 装换path路径
  37.  */
  38. private function changePath(path:String):String {
  39.     return path.replace(/\\/g, '\\\\') + "\\\\";
  40. }

 

问题十三:如何对 ArrayCollection 排序?

方法:

Code   ViewPrint
  1. private function sortByOrder(ac:ArrayCollection):Array {
  2.     if (ac == null || ac.length == 0) {
  3.         return null;
  4.     } else {
  5.         var sort:Sort = new Sort();
  6.         sort.fields = [new SortField("name"),new SortField("code")];
  7.         ac.sort = sort;
  8.         ac.refresh();
  9.         return ac.toArray();
  10.     }
  11. }

 

问题十四:如何取得画面中所有组件的 id?

方法:

Code   ViewPrint
  1. /**
  2.  * 取得画面中所有组件的ID并放入数组放回
  3.  */
  4. private function getAllKey(obj:Object):Array {
  5.     if (obj.hasOwnProperty("numElements")) {
  6.         for (var i:int = 0; i < obj.numElements; i++) {
  7.             // 获取子对象
  8.             var child:Object = obj.getElementAt(i);
  9.             // 如果该对象是下面的自定义组件,则不递归。
  10.             if (child is OcnTextInputForDyna || child is OcnDropListButton
  11.                 || child is OcnDateMinuteButton || child is OcnTextAreaForDyna
  12.                 || child.hasOwnProperty("ocnGetStr")) {
  13.                 keyArr.push(child["id"]);
  14.                 continue;
  15.             } else {
  16.                 getAllKey(child);//递归
  17.             }
  18.         }
  19.     }
  20.     return keyArr.sort();
  21. }

 

问题十五:自动保留小数点后几位?

方法:

Code   ViewPrint
  1. /**
  2.  * 自动截取小数点后几位
  3.  */
  4. public static function pointAftNBit(num:Number, n:int):String {
  5.     var ns:String = num.toString();
  6.     var pos:int = ns.indexOf(".");
  7.     var s:String = ns.substring(pos+1, ns.length);
  8.     // 不够指定小数位数则自动补齐
  9.     if (pos == -1 || (pos != -1 && s.length < n)) {
  10.         ns = num.toFixed(n);
  11.     }
  12.     return ns;
  13. }

 

问题十六:Flex Web 应用程序如何读文本文件?(Flex 桌面应用程序读写文本文件详细见问题十二)

方法:

注意:首先需要把 *.txt 重命名为 *.xml,然后修改文本内容,前后加上标签,如下:

Code   ViewPrint
  1. *.txt内容:
  2. aaaaa
  3. bbbbb
  4. ccccc
  5. 修改后的 *.xml内容:
  6. <config>
  7. <tag>
  8. aaaaa
  9. bbbbb
  10. ccccc
  11. </tag>
  12. </config>

 

需要初始化读取,并且需要配置加载文件:

Code   ViewPrint
  1. /**
  2.  * 画面初始化中读取配置文件内容
  3.  */
  4. protected function blmtitlewindow1_creationCompleteHandler(event:FlexEvent):void
  5. {
  6.     var tagStr:String = taglist.tag;
  7. }
  8. <fx:Declarations>
  9.     <fx:Model id="taglist" source="../assets/*.xml"/>
  10. </fx:Declarations>

 

问题十七:Flex 如何添加定时器?

方法:

Code   ViewPrint
  1. private var time:Timer = new Timer(10000);//定时器,定时刷新画面
  2. /**
  3.  * 画面关闭按钮方法
  4.  */
  5. protected function blmtitlewindow1_closeHandler(event:CloseEvent):void
  6. {
  7.     if (time.running) {
  8.         time.stop();
  9.     }
  10.     PopUpManager.removePopUp(this);
  11. }
  12. /**
  13.  * 画面初始化
  14.  */
  15. protected function blmtitlewindow1_creationCompleteHandler(event:FlexEvent):void
  16. {
  17.     // 给定时器添加监听事件
  18.     time.addEventListener(TimerEvent.TIMER,timeHandler);
  19.     time.start();// 启动定时器
  20. }

 

 另外,项目的主要思想就是,船端填写表单,如果通过校验后,可以拼串生成报文字符串,用 / 分割,而且组与组之间需要添加序号,点击保存后,保存到船端电脑硬盘中,格式为文本文件。

船上通过手动发送邮件的形式,把填写的各种报文发送到岸端服务器中,服务器得到邮件中的报文,自动下载,并保存到服务器中,同时自动保存到岸端数据库中,如果再岸端的 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

Code   ViewPrint
  1. The <mx:WindowedApplication> tag inherits all of the tag attributes of its superclass and adds the following tag attributes:
  2.   <s:WindowedApplication
  3.     Properties
  4.     alwaysInFront="false"
  5.     autoExit="true"
  6.     backgroundFrameRate="1"
  7.     dockIconMenu="null"
  8.     menu="null"
  9.     showStatusBar="true"
  10.     status=""
  11.     systemTrayIconMenu="null"
  12.     title=""
  13.     titleIcon="null"
  14.     useNativeDragManager="true"
  15.     Styles
  16.     backgroundAlpha="1.0"
  17.     backgroundColor="0xFFFFFF"
  18.     resizeAffordanceWidth="6"
  19.     Effects
  20.     closeEffect="No default"
  21.     minimizeEffect="No default"
  22.     unminimizeEffect="No default"
  23.     Events
  24.     applicationActivate="No default"
  25.     applicationDeactivate="No default"
  26.     close="No default"
  27.     closing="No default"
  28.     displayStateChange="No default"
  29.     displayStateChanging="No default"
  30.     invoke="No default"
  31.     moving="No default"
  32.     networkChange="No default"
  33.     resizing="No default"
  34.     windowActivate="No default"
  35.     windowComplete="No default"
  36.     windowDeactivate="No default"
  37.     windowMove="No default"
  38.     windowResize="No default"
  39.   />

 

给我留言

留言无头像?