记得第一次接触FLEX3是在毕业那一年,那时已经工作了大半年了,时隔两年多,终于有机会拿来露一手了,虽然只是当做课程设计来交付作业,但总算比以往有所突破吧。
先上截图:
事先声明下这个仅是课程设计,供各位过客参观学习。
进入正题,大家一看就知道前端是Flash,采用Flex3开发的,后端采用java做应用服务器(spring架构),至于Flex3和服务端的通信采用了BlazedDS。
用户:demo
密码 :111111
DEMO:
http://dyml.v108.10000net.cn/family_financial/financial/index.html(服务器不给力,速度很差劲,估计BlazedDS的通信效率也不高吧)
桌面版本下载:
http://dyml.v108.10000net.cn/family_financial/download.jsp
家庭财务管理系统主要分为三个模块:
财务分析:主要分析从今年01月01日开始的家庭收入、支出情况,按照月份进行统计,从图表中可以很容易看出每个月的收支是否平衡。
收入:对家庭成员的收入进行管理分析,记录每位家庭成员的收入情况,以及家庭成员占家庭财务收入的比重分析。
支出:分析每位家庭成员的开销情况,以及按照分类显示当前的开销分析图表。
贴上Flex端部分源码:
<?xml version="1.0" encoding="utf-8"?>
<!-- Simple example to demonstrate the Application container. -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
backgroundGradientColors="[0xCCCCCC, 0x66CCFF]"
backgroundColor="0xCCCCCC"
horizontalAlign="center" verticalAlign="center"
xmlns:module="module.*"
initialize="init()"
minWidth="800" minHeight="620"
>
<mx:Script>
<![CDATA[
import mx.events.CloseEvent;
import com.adobe.serialization.json.JSON;
import mx.rpc.remoting.mxml.RemoteObject;
import mx.rpc.events.ResultEvent;
import flash.net.navigateToURL;
import module.form.LoginForm;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
import module.form.SettingForm;
import mx.controls.Alert;
public var curentVersion : String = "1.2";
public var downloadUrl :String = "/family_financial/download.jsp";
public function init():void{
//Alert.show((Session.getSession("userInfo")==null).toString());
if(Session.getSession("server_url") == null || Session.getSession("server_url").toString() == ""){
//设置服务器地址
Session.setSession("server_url", "http://dyml.v108.10000net.cn");
}
openLoginForm();
}
public function destory():void{
Session.clearSession("userInfo");
}
private function addCallback(evt:Event):void{
if(Session.getSession("userInfo") != null && Session.getSession("userInfo").userId != ""){
Session.setSession("_userId",Session.getSession("userInfo").userId);
cwfx.init();
checkVersion();
}
}
// Event handler function for displaying the selected Alert button.
private function alertClickHandler(event:CloseEvent):void {
if (event.detail==Alert.YES){
//打开下载页面
var url:URLRequest = new URLRequest(Session.getSession("server_url").toString() + downloadUrl);
navigateToURL(url, "_blank");
}
}
private function checkVersion():void{
var remote:RemoteObject = CustomRemoteObject.getRemogeObject("versionService");
//监听调用成功事件
remote.addEventListener(ResultEvent.RESULT,function(evt:ResultEvent):void{
var object:Object = (JSON.decode(evt.result.toString()) as Object);
if(object.success){
if(object.object != null){
downloadUrl = object.object;
}
Alert.show(object.msg, "更新提示", Alert.YES|Alert.NO, null, alertClickHandler);
}
});
//调用J2EE端类中的方法
remote.checkVersion(curentVersion);
}
private function openLoginForm():void{
var form:LoginForm = LoginForm(PopUpManager.createPopUp(this, LoginForm , true));
PopUpManager.centerPopUp(form);
if(Session.getSession("_userId") != null && Session.getSession("_userId") != ""){
form.username.text = Session.getSession("_userId").toString();
}
form.addEventListener(FlexEvent.REMOVE, addCallback);
}
private function openBlog(event:Event):void {
var url:URLRequest = new URLRequest("http://lym6520.iteye.com");
navigateToURL(url, "_blank");
}
]]>
</mx:Script>
<mx:Style>
Label{
paddingTop:-18px;
}
</mx:Style>
<mx:Label text="家庭财务管理系统" width="100%" height="10"
fontSize="18" color="#D1FC09" fontWeight="bold" enabled="true" alpha="0.9" >
</mx:Label>
<mx:ApplicationControlBar dock="false" width="100%">
<mx:Button label="财务分析" click="containerViewStack.selectedChild=cwfx;"/>
<mx:Button label="成员管理" click="containerViewStack.selectedChild=cygl;"/>
<mx:Button label="收 入" click="containerViewStack.selectedChild=sr;"/>
<mx:Button label="支 出" click="containerViewStack.selectedChild=zc;"/>
</mx:ApplicationControlBar>
<mx:ViewStack id="containerViewStack" borderStyle="solid" width="100%" height="100%">
<module:analyze id="cwfx" title="家庭财务分析" >
</module:analyze>
<module:memberMgr id="cygl" title="家庭成员管理" >
</module:memberMgr>
<module:income id="sr" title="家庭收入" >
</module:income>
<module:expend id="zc" title="家庭支出">
</module:expend>
</mx:ViewStack>
<mx:HBox paddingTop="5">
<mx:LinkButton label="Copyright © 2012脉兜课程设计" color="blue" click="openBlog(event);"/>
</mx:HBox>
</mx:Application>
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" width="100%" height="100%"
xmlns:chart="module.chart.*" initialize="init();" xmlns:form="module.form.*">
<mx:Script>
<![CDATA[
import mx.events.ListEvent;
import com.adobe.utils.IntUtil;
import mx.events.ScrollEvent;
import com.adobe.utils.DateUtil;
import mx.formatters.DateFormatter;
import module.form.IncomeForm;
import mx.events.CloseEvent;
import mx.core.Application;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
import mx.collections.ArrayCollection;
import com.adobe.serialization.json.JSON;
import mx.rpc.remoting.mxml.RemoteObject;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.controls.Alert;
var beforePage:int = 0;
public function init():void{
var remote:RemoteObject = CustomRemoteObject.getRemogeObject("incomeService");
var pageSize : Number = 12;
//监听调用成功事件
remote.addEventListener(ResultEvent.RESULT,
function(evt:ResultEvent):void{
var object:Object = (JSON.decode(evt.result.toString()) as Object);
if(object.success){
var arr:Array = (object.object.objectList as Array);
var dp:ArrayCollection = new ArrayCollection();
var totalPage : int = (object.object.total as int)/pageSize ;
if((object.object.total % pageSize) > 0){
pageBar.maxScrollPosition = totalPage;
}else{
pageBar.maxScrollPosition = totalPage -1 ;
}
if(object.object.total <= pageSize){
pageBar.setVisible(false);
pageBarSpacer.width = -30;
}else{
pageBar.setVisible(true);
pageBarSpacer.width = -20;
}
for(var i = 0, len=arr.length; i < len; i++){
var bean:Object = new Object();
bean.id = arr[i]["id"];
bean.jtcy = arr[i]["cyid"];
bean.cyname = arr[i]["cyname"];
bean.lb = arr[i]["lb"];
bean.lbname = arr[i]["lbname"];
bean.je = arr[i]["je"];
bean.sm = arr[i]["sm"];
bean.sj = arr[i]["sj"];
bean.bcsj = arr[i]["bcsj"];
dp.addItem(bean);
}
dataGrid.dataProvider = dp;
}else{
Alert.show(object.msg);
}
}
);
var str_startDate : String = startDate.text;
var str_endDate :String = endDate.text;
var date:Date = new Date();
var df : DateFormatter = new DateFormatter();
if(str_startDate == ""){
df.formatString = "YYYY";
str_startDate = df.format(date) + "-01-01";
startDate.text = str_startDate;
}
if(endDate.text == ""){
df.formatString = "YYYY-MM-DD";
str_endDate = df.format(date);
endDate.text = str_endDate;
}
var param:Object = new Object();
param.userId = Session.getSession("userInfo").userId;
param.startDate = str_startDate;
param.endDate = str_endDate;
param.pageSize = pageSize.toString();
param.pageNumber = (pageBar.maxScrollPosition >= pageBar.scrollPosition ? pageBar.scrollPosition +1 : pageBar.maxScrollPosition).toString();
beforePage = param.pageNumber;
//调用J2EE端类中的方法
remote.list(param);
incomePieChart.str_startDate = str_startDate;
incomePieChart.str_endDate = str_endDate;
incomePieChart.init();
}
private function pageScroll(event:ScrollEvent):void {
//event.currentTarget.scrollPosition ;
//event.currentTarget.maxScrollPosition;
if(beforePage != (event.currentTarget.scrollPosition+1)){
init();
}
}
private function addCallback(evt:Event):void{
init();
}
private function showAddFormWindow():void {
var date:Date = new Date();
var df : DateFormatter = new DateFormatter();
df.formatString = "YYYY-MM-DD";
var form:IncomeForm = IncomeForm(PopUpManager.createPopUp(this, IncomeForm , true));
form.rq.text = df.format(date);
PopUpManager.centerPopUp(form);
form.addEventListener(FlexEvent.REMOVE, addCallback);
}
private function showModifyFormWindow():void {
if(dataGrid.selectedItem != null){
var form:IncomeForm = IncomeForm(PopUpManager.createPopUp(this, IncomeForm , true));
PopUpManager.centerPopUp(form);
form.addEventListener(FlexEvent.REMOVE, addCallback);
form.fid.text = dataGrid.selectedItem.id;
form.je.text = dataGrid.selectedItem.je;
form.rq.text = dataGrid.selectedItem.sj;
form.sm.text = dataGrid.selectedItem.sm;
form.addBtn.visible = false;
var xmList1 : ArrayCollection = (form.lb.dataProvider as ArrayCollection);
for(var i=0, len=xmList1.length; i < len; i++){
if(xmList1[i].data == dataGrid.selectedItem.lb){
form.lb.selectedIndex = i;
break;
}
}
var xmList2 : ArrayCollection = (form.xm.dataProvider as ArrayCollection);
for(var i=0, len=xmList2.length; i < len; i++){
if(xmList2[i].data == dataGrid.selectedItem.jtcy){
form.xm.selectedIndex = i;
break;
}
}
}else{
Alert.show("请选中一条记录!");
}
}
private function deleteItemConfirm(event:Event):void {
if(dataGrid.selectedItem != null){
Alert.show("是否确认删除当前选中记录?", "删除提示", 3, this, deleteItem);
}else{
Alert.show("请选中一条记录!");
}
}
private function deleteItem(event:CloseEvent):void {
if (event.detail==Alert.YES){
var remote:RemoteObject = CustomRemoteObject.getRemogeObject("incomeService");
//监听调用成功事件
remote.addEventListener(ResultEvent.RESULT,
function(evt:ResultEvent):void{
var object:Object = (JSON.decode(evt.result.toString()) as Object);
if(object.success){
init();
}else{
Alert.show(object.msg);
}
}
);
var object: Object = new Object();
object.id = dataGrid.selectedItem.id;
object.userId = Session.getSession("userInfo").userId;
//调用J2EE端类中的方法
remote.deleteItem(object);
}
}
private function doubleClick(event: ListEvent):void{
showModifyFormWindow();
}
]]>
</mx:Script>
<mx:ApplicationControlBar dock="true" width="100%" alpha="1.0"
fillAlphas="[1.0, 0.0]"
fillColors="[#F7F7F1, #C7E6F6]" themeColor="#D8ECF8" cornerRadius="0">
<mx:Button label="添加" click="showAddFormWindow()"/>
<mx:Button label="修改" click="showModifyFormWindow()"/>
<mx:Button label="删除" click="deleteItemConfirm(event);"/>
</mx:ApplicationControlBar>
<mx:HBox width="80%" paddingTop="5">
<mx:Spacer width="10"/>
<form:MyDateField id="startDate" yearNavigationEnabled="true" width="200" formatString="YYYY-MM-DD"/>
<form:MyDateField id="endDate" yearNavigationEnabled="true" width="200" formatString="YYYY-MM-DD"/>
<mx:Button label="确 定" click="init();"/>
</mx:HBox>
<mx:HBox width="100%" height="85%" paddingLeft="5" paddingRight="5">
<mx:DataGrid id="dataGrid" width="100%" height="100%" verticalScrollPolicy="off" doubleClickEnabled="true" itemDoubleClick="doubleClick(event);">
<mx:columns>
<mx:DataGridColumn dataField="id" visible="false"/>
<mx:DataGridColumn dataField="jtcy" visible="false"/>
<mx:DataGridColumn dataField="cyname" headerText="家庭成员"/>
<mx:DataGridColumn dataField="lb" visible="false"/>
<mx:DataGridColumn dataField="lbname" headerText="类别"/>
<mx:DataGridColumn dataField="je" headerText="金额"/>
<mx:DataGridColumn dataField="sm" headerText="说明"/>
<mx:DataGridColumn dataField="sj" headerText="收入日期"/>
<mx:DataGridColumn dataField="bcsj" headerText="保存时间"/>
</mx:columns>
</mx:DataGrid>
<mx:Spacer id="pageBarSpacer" width="-30"/>
<mx:VScrollBar id="pageBar" height="100%" visible="false"
minScrollPosition="0" maxScrollPosition="1"
lineScrollSize="1" pageScrollSize="1"
repeatDelay="1000" repeatInterval="500" scroll="pageScroll(event);"/>
<chart:IncomePieChart id="incomePieChart" title="收入比重分析" width="350" height="300"/>
</mx:HBox>
</mx:Panel>
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" width="100%" height="100%"
initialize="init();" xmlns:chart="module.chart.*" xmlns:form="module.form.*">
<mx:Script>
<![CDATA[
import mx.events.ListEvent;
import mx.events.ScrollEvent;
import com.adobe.utils.DateUtil;
import mx.formatters.DateFormatter;
import module.form.ExpendForm;
import mx.events.CloseEvent;
import mx.core.Application;
import mx.events.FlexEvent;
import mx.managers.PopUpManager;
import mx.collections.ArrayCollection;
import com.adobe.serialization.json.JSON;
import mx.rpc.remoting.mxml.RemoteObject;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.controls.Alert;
public var beforePage:int = 0;
public function init():void{
var remote:RemoteObject = CustomRemoteObject.getRemogeObject("expendService");
var pageSize : Number = 12;
//监听调用成功事件
remote.addEventListener(ResultEvent.RESULT,
function(evt:ResultEvent):void{
var object:Object = (JSON.decode(evt.result.toString()) as Object);
if(object.success){
var arr:Array = (object.object.objectList as Array);
var dp:ArrayCollection = new ArrayCollection();
var totalPage : int = (object.object.total as int)/pageSize ;
if((object.object.total % pageSize) > 0){
pageBar.maxScrollPosition = totalPage;
}else{
pageBar.maxScrollPosition = totalPage -1 ;
}
if(object.object.total <= pageSize){
pageBar.setVisible(false);
pageBarSpacer.width = -30;
}else{
pageBar.setVisible(true);
pageBarSpacer.width = -20;
}
for(var i = 0, len=arr.length; i < len; i++){
var bean:Object = new Object();
bean.id = arr[i]["id"];
bean.jtcy = arr[i]["cyid"];
bean.cyname = arr[i]["cyname"];
bean.lb = arr[i]["lb"];
bean.lbname = arr[i]["lbname"];
bean.je = arr[i]["je"];
bean.sm = arr[i]["sm"];
bean.sj = arr[i]["sj"];
bean.bcsj = arr[i]["bcsj"];
dp.addItem(bean);
}
dataGrid.dataProvider = dp;
}else{
Alert.show(object.msg);
}
}
);
var str_startDate : String = startDate.text;
var str_endDate :String = endDate.text;
var date:Date = new Date();
var df : DateFormatter = new DateFormatter();
if(str_startDate == ""){
df.formatString = "YYYY";
str_startDate = df.format(date) + "-01-01";
startDate.text = str_startDate;
}
if(endDate.text == ""){
df.formatString = "YYYY-MM-DD";
str_endDate = df.format(date);
endDate.text = str_endDate;
}
var param:Object = new Object();
param.userId = Session.getSession("userInfo").userId;
param.startDate = str_startDate;
param.endDate = str_endDate;
param.pageSize = pageSize.toString();
param.pageNumber = (pageBar.maxScrollPosition >= pageBar.scrollPosition ? pageBar.scrollPosition +1 : pageBar.maxScrollPosition).toString();
beforePage = param.pageNumber;
//调用J2EE端类中的方法
remote.list(param);
expendBarChart.str_startDate = str_startDate;
expendBarChart.str_endDate = str_endDate;
expendBarChart.init();
}
private function pageScroll(event:ScrollEvent):void {
if(beforePage != (event.currentTarget.scrollPosition+1)){
init();
}
}
private function addCallback(evt:Event):void{
init();
}
private function showAddFormWindow():void {
var date:Date = new Date();
var df : DateFormatter = new DateFormatter();
df.formatString = "YYYY-MM-DD";
var form:ExpendForm = ExpendForm(PopUpManager.createPopUp(this, ExpendForm , true));
form.rq.text = df.format(date);
PopUpManager.centerPopUp(form);
form.addEventListener(FlexEvent.REMOVE, addCallback);
}
private function showModifyFormWindow():void {
if(dataGrid.selectedItem != null){
var form:ExpendForm = ExpendForm(PopUpManager.createPopUp(this, ExpendForm , true));
PopUpManager.centerPopUp(form);
form.addEventListener(FlexEvent.REMOVE, addCallback);
form.fid.text = dataGrid.selectedItem.id;
form.je.text = dataGrid.selectedItem.je;
form.rq.text = dataGrid.selectedItem.sj;
form.sm.text = dataGrid.selectedItem.sm;
form.addBtn.visible = false;
var xmList1 : ArrayCollection = (form.lb.dataProvider as ArrayCollection);
for(var i=0, len=xmList1.length; i < len; i++){
if(xmList1[i].data == dataGrid.selectedItem.lb){
form.lb.selectedIndex = i;
break;
}
}
var xmList2 : ArrayCollection = (form.xm.dataProvider as ArrayCollection);
for(var i=0, len=xmList2.length; i < len; i++){
if(xmList2[i].data == dataGrid.selectedItem.jtcy){
form.xm.selectedIndex = i;
break;
}
}
}else{
Alert.show("请选中一条记录!");
}
}
private function deleteItemConfirm(event:Event):void {
if(dataGrid.selectedItem != null){
Alert.show("是否确认删除当前选中记录?", "删除提示", 3, this, deleteItem);
}else{
Alert.show("请选中一条记录!");
}
}
private function deleteItem(event:CloseEvent):void {
if (event.detail==Alert.YES){
var remote:RemoteObject = CustomRemoteObject.getRemogeObject("expendService");
//监听调用成功事件
remote.addEventListener(ResultEvent.RESULT,
function(evt:ResultEvent):void{
var object:Object = (JSON.decode(evt.result.toString()) as Object);
if(object.success){
init();
}else{
Alert.show(object.msg);
}
}
);
var object: Object = new Object();
object.id = dataGrid.selectedItem.id;
object.userId = Session.getSession("userInfo").userId;
//调用J2EE端类中的方法
remote.deleteItem(object);
}
}
private function doubleClick(event: ListEvent):void{
showModifyFormWindow();
}
]]>
</mx:Script>
<mx:ApplicationControlBar dock="true" width="100%" alpha="1.0"
fillAlphas="[1.0, 0.0]"
fillColors="[#F7F7F1, #C7E6F6]" themeColor="#D8ECF8" cornerRadius="0">
<mx:Button label="添加" click="showAddFormWindow()"/>
<mx:Button label="修改" click="showModifyFormWindow()"/>
<mx:Button label="删除" click="deleteItemConfirm(event);"/>
</mx:ApplicationControlBar>
<mx:HBox width="80%" paddingTop="5">
<mx:Spacer width="10"/>
<form:MyDateField id="startDate" yearNavigationEnabled="true" width="200" formatString="YYYY-MM-DD"/>
<form:MyDateField id="endDate" yearNavigationEnabled="true" width="200" formatString="YYYY-MM-DD"/>
<mx:Button label="确 定" click="init();"/>
</mx:HBox>
<mx:HBox width="100%" height="85%" paddingLeft="5" paddingRight="5">
<mx:DataGrid id="dataGrid" width="100%" height="100%" verticalScrollPolicy="off" doubleClickEnabled="true" itemDoubleClick="doubleClick(event);">
<mx:columns>
<mx:DataGridColumn dataField="id" visible="false"/>
<mx:DataGridColumn dataField="jtcy" visible="false"/>
<mx:DataGridColumn dataField="cyname" headerText="家庭成员"/>
<mx:DataGridColumn dataField="lb" visible="false"/>
<mx:DataGridColumn dataField="lbname" headerText="类别"/>
<mx:DataGridColumn dataField="je" headerText="金额"/>
<mx:DataGridColumn dataField="sm" headerText="说明"/>
<mx:DataGridColumn dataField="sj" headerText="支出日期"/>
<mx:DataGridColumn dataField="bcsj" headerText="保存时间"/>
</mx:columns>
</mx:DataGrid>
<mx:Spacer id="pageBarSpacer" width="-30"/>
<mx:VScrollBar id="pageBar" height="100%" visible="false"
minScrollPosition="0" maxScrollPosition="1"
lineScrollSize="1" pageScrollSize="1"
repeatDelay="1000" repeatInterval="500" scroll="pageScroll(event);"/>
<chart:ExpendBarChart id="expendBarChart" title="支出分析" width="350" height="100%"/>
</mx:HBox>
</mx:Panel>
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
title="登入" >
<mx:Script>
<![CDATA[
import mx.events.ValidationResultEvent;
import mx.rpc.remoting.mxml.RemoteObject;
import mx.controls.Alert;
import com.adobe.serialization.json.JSON;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.managers.PopUpManager;
// Event handler for the OK button.
private function submit():void {
if(username_validator.validate().type == ValidationResultEvent.INVALID){
return;
}
if(password_validator.validate().type == ValidationResultEvent.INVALID){
return;
}
var remote:RemoteObject = CustomRemoteObject.getRemogeObject("loginService");
//监听调用成功事件
remote.addEventListener(ResultEvent.RESULT,result);
var objectBean:Object = new Object();
objectBean.userId = username.text;
objectBean.password = password.text;
//调用J2EE端类中的方法
remote.login(objectBean);
}
private function result(evt:ResultEvent):void{
var object:Object = (JSON.decode(evt.result.toString()) as Object);
if(object.success){
var object2 : Object = new Object();
object2.userId = object.object.yhm;
object2.name = object.object.mc;
Session.setSession("userInfo",object2);
PopUpManager.removePopUp(this);
}else{
Alert.show(object.msg);
}
}
private function openSettingForm():void{
var form:SettingForm = SettingForm(PopUpManager.createPopUp(this, SettingForm , true));
form.url.text = Session.getSession("server_url").toString();
PopUpManager.centerPopUp(form);
}
]]>
</mx:Script>
<mx:Form width="100%" height="100%">
<mx:FormItem label="用户名:">
<mx:TextInput id="username" width="200"/>
</mx:FormItem>
<mx:FormItem label="密 码:">
<mx:TextInput id="password" displayAsPassword="true" width="200"/>
</mx:FormItem>
</mx:Form>
<mx:HBox width="100%" horizontalAlign="right" paddingRight="10" paddingBottom="10">
<mx:TextInput id="fid" visible="false" text=""/>
<mx:Button label="登入" click="submit();"/>
<!--
<mx:Button label="网络设置" click="openSettingForm();" fillAlphas="[1.0, 1.0]" fillColors="[#AAA5A5, #D4C9C9, #DFC3C3, #F7DDDD]"/>
-->
</mx:HBox>
<mx:StringValidator id="username_validator" source="{username}" property="text" minLength="4" requiredFieldError="不能放空。"/>
<mx:StringValidator id="password_validator" source="{password}" property="text" minLength="6" requiredFieldError="不能放空。"/>
</mx:TitleWindow>