要求

    • 必备知识

      本文要求基本了解 Adobe Flex编程知识和JAVA基础知识。

    • 开发环境

      MyEclipse10/Flash Builder4.6/Flash Player11及以上

    • 演示地址

      演示地址

 
 

传统网络程序的开发是基于页面的、服务器端数据传递的模式,把网络程序的表现层建立于HTML页面之上,而HTML是适合于文本的,传统的基于页面的系统已经渐渐不能满足网络浏览者的更高的、全方位的体验要求了。而富互联网应用(Rich Internet Applications,缩写为RIA)的出现就是为了解决这个问题。在HTML5发布以前,RIA领域的技术解决方案一直相都是各展所长,并无争议。Adobe体系中,Flash做不了的事情,Flex可以做到;.Net系决策者在选用RIA解决方案时,Silverlight是不二之选。随着HTML 5横空出世,Flex“易主”(这里说的是Adobe将Flex捐给Apache),Silverlight被“雪藏”(这里指微软停止对Silverlight的更新),RIA领域的技术解决方案开始变得扑朔迷离。 HTML 5无疑是“明日之星”,苹果公司前CEO乔布斯对它赞赏有加,绝大多数智能手机浏览器均支持HTML 5,基于HTML 5的网站也如雨后春笋般出现。这些似乎预示着HTML 5时代来临,人们试图让决策者相信,Flash/Flex时代已经过去了,HTML 5才是RIA领域的最佳解决方案。那到底真相会是什么呢? HTML 5其实也存在许多劣势,并不完美。HTML 5的浏览器兼容性问题(由于国内传统IE浏览器占了相当大的比重);要实现html5应用,还要写CSS与JavaScript,增加了人员构成和开发成本,其编写难度也要远大于Flex。在较长一段时间内,HTML5是无法”替代”Flex技术的,也许最终HTML 5与Flex将成为是两种截然不同的技术解决方案,所以,它们是互补的,而非替代。如对Flash/Flex/Html5还不了解,我到互联网上找了一篇相关的文章和大家分享一下: 浅谈 Flash/Flex/HTML5 技术选型

一,Flex4&BlazeDS&JAVA整合:

Myeclipse10.6+Flash Builder 4.6安装配置

二,用户界面设计:

  • 播放器界面的设计:

  • 专辑制作界面的设计:

三,数据库设计:

  • album(专辑表)创建语句:
CREATE TABLE `album` (
`a_id` int(11) NOT NULL AUTO_INCREMENT,
`a_name` varchar(20) NOT NULL DEFAULT '',
`a_singer` varchar(20) NOT NULL DEFAULT '',
`a_image` varchar(120) NOT NULL DEFAULT '',
PRIMARY KEY (`a_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;
  • song(歌曲表)创建语句:
CREATE TABLE `song` (
`s_id` int(11) NOT NULL AUTO_INCREMENT,
`a_id` int(11) NOT NULL,
`s_name` varchar(120) NOT NULL DEFAULT '',
`s_source` varchar(150) NOT NULL DEFAULT '',
PRIMARY KEY (`s_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ;

四,前端代码物理实现(Flex4部分代码实现):

  • 播放器界面物理实现,通过在主程序中定义三个不同的自定义组件,”专辑””列表”“播放器控制面板”来构成整个播放器界面。

1,程序入口文件:myMusicPlayer.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="955" minHeight="600" skinClass="skinks.ApplicationSkin"
xmlns:components="components.*"
creationComplete="initApp()">
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
<s:RemoteObject id="albumListDist" destination="AlbumServerTaget"
result="albumListDist_resultHandler(event)"
fault="albumListDist_faultHandler(event)"/> <s:RemoteObject id="songListDist" destination="SongServerTaget"
result="songListDist_resultHandler(event)"
fault="songListDist_faultHandler(event)"/>
</fx:Declarations>
<fx:Metadata>
[Event(name="changeitem",type="events.MyEvent")] //通过 Event元数据 定义自定义监听事件
</fx:Metadata>
<fx:Script>
<![CDATA[
import events.MyEvent;
import events.MyEvent2;
import events.MyEvent3; import mx.collections.ArrayCollection;
import mx.collections.ArrayList;
import mx.controls.Alert;
import mx.events.FlexEvent;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent; import valueObjects.Song; [Bindable]
public var albums:ArrayCollection;
public var listData:ArrayCollection=new ArrayCollection();
private var musicSource:Object;
private var albumSinger:String; //专辑歌手 /**
* 初始化函数
*/
private function initApp():void{ albumListDist.getList(); //调用服务端方法
album.addEventListener(MyEvent3.CHANGEITEM,albumList_change_Handler3); //监听自定义事件; /* //将数据放入到值对象中
for each(var temp:Object in data[0]){
var song:Song=new Song();
song.singer=temp.singer;
song.song=temp.song;
song.musicSource=temp.musicSource;
listData.addItem(song);
}
//列表自动初始化第一个专辑数据绑定
list.data=listData;
//专辑绑定数据
album.data=Album;
player.musicItem=Object(listData[0]);
player.musicNum=listData.length;
//Alert.show(data[0].length);
*/
} /**
* 重新选择专辑后调用
*/
private function albumList_change_Handler3(event:MyEvent3):void{
albumSinger=event.albumItem.a_singer;
songListDist.getSongsById(event.albumItem.a_id); //通过专辑ID请求专辑的数据 } /**
*结果函数 albumListDist.getList() 获取专辑列表
*/
protected function albumListDist_resultHandler(event:ResultEvent):void
{ albums=event.result as ArrayCollection;
album.data=albums; //绑定专辑数据
albumSinger=albums[0].a_singer; //获取第一个专辑里歌手信息
songListDist.getSongsById(albums[0].a_id); //请求第一个专辑的数据 } protected function albumListDist_faultHandler(event:FaultEvent):void{
//Alert.show(event.message.toString());
} /**
* 结果函数 songListDist.getSongsById(albums[0].a_id); 请求第一个专辑的数据
*/
protected function songListDist_resultHandler(event:ResultEvent):void
{ list.data=event.result as ArrayCollection;
player.musicItem=event.result[0] as Object; //歌曲实例
player.musicNum=ArrayCollection(event.result).length; //专辑含歌曲数量 专辑长度
player.albumSinger=albumSinger; } protected function songListDist_faultHandler(event:FaultEvent):void{} ]]>
</fx:Script> <!--程序主题-->
<s:Group horizontalCenter="0" verticalCenter="0">
<!--背景图片-->
<s:BitmapImage width="1078" smooth="true"
source="@Embed('/assets/images/contentBg.png')"/>
<!--专辑-->
<components:Album id="album" x="220" y="70" width="100%" height="100%"/>
<!--列表-->
<components:List id="list" width="220" height="605" />
<!--播放器控制面板-->
<components:Player id="player" /> </s:Group>
</s:Application>

2,自定义“专辑”组件:Album.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="group1_creationCompleteHandler(event)"> <fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<fx:Metadata> [Event(name="changeitem3",type="events.MyEvent3")]
</fx:Metadata>
<fx:Script>
<![CDATA[
import events.MyEvent2;
import events.MyEvent3; import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.events.FlexEvent;
[Bindable]
public var data:ArrayCollection; /**
* 初始化函数
*/
protected function group1_creationCompleteHandler(event:FlexEvent):void
{
list.addEventListener(MouseEvent.DOUBLE_CLICK,albumDoubleClick); } /**
* 双击事件
*/
private function albumDoubleClick(event:MouseEvent):void{ dispatchEvent(new MyEvent3("changeitem3",list.selectedItem)); //分配事件 此事打List组件中调用
} ]]>
</fx:Script>
<s:BitmapImage left="-20" top="15" source="@Embed('/assets/images/RasterizedItems3.png')"
/>
<s:List id="list" left="0" top="43" dataProvider="{data}" itemRenderer="components.AlbumItem" skinClass="skinks.MyAlbums"
doubleClickEnabled="true"
requireSelection="true"
selectedIndex="0">
<s:layout>
<s:TileLayout paddingTop="50" paddingLeft="70" verticalGap="40" horizontalGap="40" orientation="rows"
requestedColumnCount="4"
/>
</s:layout>
</s:List>
</s:Group>

3,自定义“列表”组件:List.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:SkinnableContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="init(event)">
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<fx:Metadata> [Event(name="changeitem",type="events.MyEvent")]
</fx:Metadata>
<fx:Script>
<![CDATA[
import events.MyEvent;
import events.MyEvent2; import mx.collections.ArrayCollection;
import mx.collections.ArrayList;
import mx.controls.Alert;
import mx.events.FlexEvent; [Bindable]
public var data:ArrayCollection; protected function init(event:FlexEvent):void
{
list.addEventListener(MouseEvent.DOUBLE_CLICK,itemDoubleClick); } private function itemDoubleClick(event:MouseEvent):void{
var temp:Object=list.selectedItem;
dispatchEvent(new MyEvent("changeitem",temp)); } ]]>
</fx:Script> <s:BitmapImage height="100%"
source="@Embed('/assets/images/RasterizedItems2.png')"/>
<s:VGroup top="110" left="0" right="0" bottom="0">
<s:Label color="#FFFFFF" fontFamily="微软雅黑" fontSize="13" paddingLeft="30"
text="歌单"/>
<s:List id="list"
dataProvider="{data}"
itemRenderer="components.ListItem"
skinClass="skinks.list.SongsList"
doubleClickEnabled="true"
requireSelection="true"
selectedIndex="0" height="100%"
width="100%" >
<s:layout>
<s:VerticalLayout gap="0" paddingLeft="0" />
</s:layout>
</s:List>
</s:VGroup> </s:SkinnableContainer>

4,自定义“播放器控制面板”组件:Player.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="init()">
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<fx:Metadata> </fx:Metadata>
<fx:Script>
<![CDATA[
import events.MyEvent; import mx.controls.Alert;
import mx.events.FlexEvent; import utils.Tool4DateTime; /**
* 服务器IP地址
*/
private var serverIP:String="http://localhost:8080"; /**
* List对象
*/
public var MusicList:List; /**
* musicItem Object 音乐信息对象
*/
[Bindable]
public var musicItem:Object; /**
* 列表歌曲数量
*/
public var musicNum:int; /**
* 歌手名称
*/
[Bindable]
public var albumSinger:String; /**
* 播放器音量
*/
private var currentVolum:Number =0.5;
/**
* 正在播放的音乐的URL字符串
* 从主程序中获得 player.currentMusicUrlString=musicSource;
*/
public var currentMusicUrlString:String;
/**
* 正在播放的音乐的URLRequest
*/
private var currentMusicUrlRequest:URLRequest;
/**
* 正在播放的音乐的Sound
*/
private var currentMusicSound:Sound;
/**
* 正在播放的音乐的SoungChannel
* SoundChannel 类控制应用程序中的声音。每个声音均分配给一个声道,而且应用程序可以具有混合在一起的多个声道。SoundChannel 类包含 stop() 方法、用于监控声道幅度(音量)的属性以及用于对声道指定 SoundTransform 对象的属性。
*/
private var currentMusicChannel:SoundChannel;
/**
* 正在播放的音乐的 SoundTransform
* SoundTransform 类包含音量和平移的属性。
*/
private var currentMusicTransform:SoundTransform;
/**
* 正在播放的音乐的播放进度参数
*/
private var currentMusicPosition:int =0;
/**
* 正在播放的音乐的总时间
*/
private var currentMusicTotleTime:Number =0;
/**
* 音乐是否正在播放
*/
private var isplaying:Boolean = false; private function init():void{
playAndPause.addEventListener(MouseEvent.CLICK,musicPlay); //播放按钮
previous.addEventListener(MouseEvent.CLICK,playPrevious); //上一首
next.addEventListener(MouseEvent.CLICK,playNext); //上一首
playingProcess.addEventListener(Event.CHANGE,playingProcess_changeHandler); //进度条滚动事件
volumeSlider.addEventListener(Event.CHANGE,volumeSlider_changeHandler); //音量条滚动事件
//监听自定义事件
MusicList=parentApplication.list; //设置List对象
MusicList.addEventListener(MyEvent.CHANGEITEM,playerList_change_Handler); //监听自定义事件
} private function musicPlay(event:MouseEvent):void{
if(!isplaying){ //播放 false
//此状态为 启动播放器 然后点击播放按钮 状态(空状态)
if(currentMusicSound==null&&currentMusicChannel ==null){
currentMusicUrlString=serverIP+musicItem.s_source;
currentMusicUrlRequest =new URLRequest(currentMusicUrlString);
currentMusicSound = new Sound();
currentMusicSound.load(currentMusicUrlRequest);
currentMusicSound.addEventListener(Event.COMPLETE,load_CompleteHandler);
currentMusicChannel = currentMusicSound.play();//开始播放
timer_GetCurrentPositionHandler();//同步更新已经播放的时间的计时器
//currentMusicChannel.addEventListener(Event.SOUND_COMPLETE,autoPlayNext);//自动播放下一首
}else{//此状态为 暂停后点击播放按钮 状态
currentMusicChannel = currentMusicSound.play(currentMusicPosition);
}
isplaying=true;
}else{ //暂停
//此状态为 播放过程中点击 暂停按钮 状态
currentMusicPosition = currentMusicChannel.position;//记录暂停位置
currentMusicChannel.stop();//暂停
isplaying=false;
} currentMusicChannel.addEventListener(Event.SOUND_COMPLETE,autoPlayNext);//自动播放下一首 } /**
* 自动播放下一首
* @param event
*
*/
protected function autoPlayNext(event:Event):void{//过滤参数问题 if(parentApplication.list.list.selectedIndex>=musicNum-1 ){
parentApplication.list.list.selectedIndex = 0;
}else{
parentApplication.list.list.selectedIndex += 1;
} if(currentMusicSound!=null&&currentMusicChannel!=null){
currentMusicChannel.stop();//暂停
}
clearPar();
musicItem=parentApplication.list.list.selectedItem; currentMusicUrlString=serverIP+musicItem.s_source;
currentMusicUrlRequest =new URLRequest(currentMusicUrlString);
currentMusicSound = new Sound();
currentMusicSound.load(currentMusicUrlRequest);
currentMusicSound.addEventListener(Event.COMPLETE,load_CompleteHandler);
playAndPause.selected=true;
isplaying =true;
currentMusicChannel = currentMusicSound.play();//开始播放
timer_GetCurrentPositionHandler();//同步更新已经播放的时间的计时器
currentMusicChannel.addEventListener(Event.SOUND_COMPLETE,autoPlayNext);//自动播放下一首 } /**
* 播放上一首
*/
protected function playPrevious(event:MouseEvent):void
{
parentApplication.list.list.selectedIndex--;
if(parentApplication.list.list.selectedIndex<0 ){
parentApplication.list.list.selectedIndex = musicNum-1;
} if(currentMusicSound!=null&&currentMusicChannel!=null){
currentMusicChannel.stop();//暂停
}
clearPar();
musicItem=parentApplication.list.list.selectedItem; currentMusicUrlString=serverIP+musicItem.s_source;
currentMusicUrlRequest =new URLRequest(currentMusicUrlString);
currentMusicSound = new Sound();
currentMusicSound.load(currentMusicUrlRequest);
currentMusicSound.addEventListener(Event.COMPLETE,load_CompleteHandler);
playAndPause.selected=true;
isplaying =true;
currentMusicChannel = currentMusicSound.play();//开始播放
timer_GetCurrentPositionHandler();//同步更新已经播放的时间的计时器
currentMusicChannel.addEventListener(Event.SOUND_COMPLETE,autoPlayNext);//自动播放下一首 } /**
* 播放下一首
*/
protected function playNext(event:MouseEvent):void
{
parentApplication.list.list.selectedIndex++;
if(parentApplication.list.list.selectedIndex>musicNum-1 ){
parentApplication.list.list.selectedIndex = 0;
} if(currentMusicSound!=null&&currentMusicChannel!=null){
currentMusicChannel.stop();//暂停
}
clearPar();
musicItem=parentApplication.list.list.selectedItem; currentMusicUrlString=serverIP+musicItem.s_source;
currentMusicUrlRequest =new URLRequest(currentMusicUrlString);
currentMusicSound = new Sound();
currentMusicSound.load(currentMusicUrlRequest);
currentMusicSound.addEventListener(Event.COMPLETE,load_CompleteHandler);
playAndPause.selected=true;
isplaying =true;
currentMusicChannel = currentMusicSound.play();//开始播放
timer_GetCurrentPositionHandler();//同步更新已经播放的时间的计时器
currentMusicChannel.addEventListener(Event.SOUND_COMPLETE,autoPlayNext);//自动播放下一首 } private function playerList_change_Handler(event:MyEvent):void{ if(currentMusicSound!=null&&currentMusicChannel!=null){
currentMusicChannel.stop();//暂停
}
clearPar();
musicItem=event.musicItem;
currentMusicUrlString=serverIP+musicItem.s_source;
currentMusicUrlRequest =new URLRequest(currentMusicUrlString);
currentMusicSound = new Sound();
currentMusicSound.load(currentMusicUrlRequest);
currentMusicSound.addEventListener(Event.COMPLETE,load_CompleteHandler);
playAndPause.selected=true;
isplaying =true;
currentMusicChannel = currentMusicSound.play();//开始播放
timer_GetCurrentPositionHandler();//同步更新已经播放的时间的计时器
currentMusicChannel.addEventListener(Event.SOUND_COMPLETE,autoPlayNext);//自动播放下一首 } /**
* 清除参数
* currentMusicSound = null;
* currentMusicChannel = null;
* currentMusicPosition = 0;
*
*/
private function clearPar():void{
currentMusicSound = null;
currentMusicChannel = null;
currentMusicPosition = 0;
} /**
* 正在播放的歌曲的总时长
*/
private var len:int; /**
* 文件加载完成 能读取到音乐的总时长
* @param event
*
*/
protected function load_CompleteHandler(event:Event):void{
len = currentMusicSound.length;
totalTime.text = Tool4DateTime.millionSecond2MinuteSecond(len);
} /**
* 同步更新已经播放的时间的计时器
*
*/
protected function timer_GetCurrentPositionHandler():void{
var clock:Timer = new Timer(100,int(len/1000/60*10));//每0.1秒更新一次
clock.start();
clock.addEventListener(TimerEvent.TIMER,showTime);
} /**
* 显示已经播放的总时间
* @param event
*
*/
protected function showTime(event:Event):void{
playingProcess.maximum = int(len/1000)*10;//最大值
playingProcess.value = int(currentMusicPosition/1000*10); //当前值
currentMusicPosition = currentMusicChannel.position;
playedTime.text = Tool4DateTime.millionSecond2MinuteSecond(currentMusicPosition);
} /**
* 播放进度条 可以拖动
* @param event
*
*/
protected function playingProcess_changeHandler(event:Event):void{
if(currentMusicChannel!=null){
currentMusicPosition = playingProcess.value*1000/10;//当前音乐播放进度
currentMusicChannel.stop();
currentMusicChannel = currentMusicSound.play(currentMusicPosition);
isplaying=true; playAndPause.selected=true;
currentMusicChannel.addEventListener(Event.SOUND_COMPLETE,autoPlayNext);//自动播放下一首 }else{
playingProcess.value=0;
}
} /**
* 音量调节
* @param event
*
*/
protected function volumeSlider_changeHandler(event:Event):void{
if(currentMusicChannel != null){//正在播放时调节音量
currentMusicTransform = currentMusicChannel.soundTransform;
currentMusicTransform.volume = volumeSlider.value/10;
currentMusicChannel.soundTransform = currentMusicTransform;
currentVolum = currentMusicTransform.volume;
}
currentVolum = volumeSlider.value/10;
} ]]>
</fx:Script>
<s:states>
<s:State name="normal" />
<s:State name="disabled" />
</s:states>
<!--背景图片-->
<s:BitmapImage smooth="true"
source="@Embed('/assets/images/headBg.png')"/>
<s:Group id="contentGroup" left="0" right="0" top="0" bottom="0" >
<!--播放按钮-->
<s:HGroup left="35" bottom="15" verticalAlign="middle" >
<s:Button skinClass="skinks.playercontrol.PreviousButton" id="previous" />
<s:ToggleButton id="playAndPause" skinClass="skinks.playercontrol.PlayAndPause" />
<s:Button skinClass="skinks.playercontrol.NextButton" id="next"/>
</s:HGroup>
<!--音量条-->
<s:HGroup left="200" bottom="15" height="50" gap="10" verticalAlign="middle">
<s:BitmapImage source="@Embed('/assets/images/MuteButton.png')"/>
<s:HSlider id="volumeSlider" skinClass="skinks.playercontrol.volume.HSliderSkin" maximum="10" stepSize="1" value="5" />
<s:BitmapImage smooth="true"
source="@Embed('/assets/images/RasterizedItems10.png')"/>
</s:HGroup>
<s:BitmapImage smooth="true" source="@Embed('/assets/images/Shape 14.png')"
x="365" y="2"/>
<!--进度条和歌曲信息-->
<s:VGroup left="372" bottom="25" horizontalAlign="center" >
<s:Label text="{musicItem.s_name}"
color.normal="#D6D3D3" fontFamily.normal="微软雅黑" fontSize.normal="13"
fontWeight.normal="bold"/>
<s:Label text="{albumSinger}"
color.normal="#D6D3D3" fontFamily.normal="微软雅黑" fontSize.normal="11"/>
<s:HGroup>
<s:Label id="playedTime" text="00:00"
color.normal="#D6D3D3" fontFamily.normal="微软雅黑"/>
<s:ScrubBar id="playingProcess" skinClass="skinks.playercontrol.scrubbar.ScrubBar"/>
<s:Label id="totalTime" text="00:00"
color.normal="#D6D3D3" fontFamily.normal="微软雅黑"/>
</s:HGroup>
</s:VGroup>
</s:Group>
</s:Group>

关于flex操作音频文件,可以参考我之前做的一个简单音乐播放器实例:

博客中 Flex4/Flash mp3音乐播放器实例 含演示地址

  • 专辑制作插件物理实现、

MyUpload3.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="955" minHeight="600"
skinClass="skinks.ApplicationSkink"
creationComplete="init()">
<fx:Style source="assets/styles/main.css"/>
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 --> </fx:Declarations> <fx:Script>
<![CDATA[
import components.Album;
import components.GridHeaderRenderer;
import components.MultiFileUpload; import events.MyEvent; import mx.collections.ArrayCollection;
import mx.collections.ArrayList;
import mx.controls.Alert;
import mx.utils.StringUtil; import spark.components.gridClasses.GridColumn;
[Bindable]
private var data=new ArrayCollection([
{id:"1",song:"心愿",sf:".mp3"},
{id:"2",song:"心愿",sf:".mp3"},
{id:"3",song:"心愿",sf:".mp3"},
{id:"4",song:"心愿",sf:".mp3"},
{id:"4",song:"心愿",sf:".mp3"}
]); public var album:Album; //专辑信息上传对象
public var multiFileUpload:MultiFileUpload; //音乐文件上传对象 public var imageTypes:FileFilter = new FileFilter("Images (*.jpg; *.jpeg; *.gif; *.png)" ,"*.jpg; *.jpeg; *.gif; *.png");
public var imagefilesToFilter:Array = new Array(imageTypes); //图片过滤数组
public var ImageUploadDestination:String = "http://localhost:8080/MyUpload4/AlbumAdd"; //专辑信息上传地址 public var musicTypes:FileFilter = new FileFilter("Music Files (*.mp3)","*.mp3");
public var filesToFilter:Array = new Array(musicTypes); //音乐过滤数组
public var uploadDestination:String = "http://localhost:8080/MyUpload4/FileUploadServlet"; //专辑信息上传地址 private function init():void{ album=new Album(albumName,singer,ImageUploadDestination,imagefilesToFilter,img,create);
album.addEventListener(MyEvent.COMPLETE,albumUpload); //初始化数据列表头
var _nameColumn = new GridColumn;
var _typeColumn = new GridColumn;
var _sizeColumn = new GridColumn; _nameColumn.headerText= "File";
_nameColumn.headerRenderer=new ClassFactory(GridHeaderRenderer); _typeColumn.headerText = "File Type";
_typeColumn.width = 80;
_typeColumn.headerRenderer=new ClassFactory(GridHeaderRenderer); _sizeColumn.headerText = "File Size";
_sizeColumn.width = 150;
_sizeColumn.headerRenderer=new ClassFactory(GridHeaderRenderer); var _columns = new ArrayList([_nameColumn,_typeColumn,_sizeColumn]);
filesDG.columns=_columns;
} private function albumUpload(e:MyEvent):void{ var postVariables:URLVariables = new URLVariables;
postVariables.id = e.data; multiFileUpload = new MultiFileUpload(
filesDG,
browseBTN,
clearButton,
delButton,
upload_btn,
progressbar,
uploadDestination,
postVariables,
10240000,
filesToFilter
); // var test=filesDG.columns.getItemAt(0); } ]]>
</fx:Script>
<s:Group width="460" verticalCenter="0" horizontalCenter="0">
<s:layout>
<s:VerticalLayout verticalAlign="middle" horizontalAlign="center"/>
</s:layout> <!--专辑信息-->
<s:Group width="100%">
<s:Button id="create"
right="0" width="60" height="150" label="创建专辑"
enabled="true"
skinClass="skinks.ButtonSkin1"/>
<s:SkinnableContainer width="400" height="150" skinClass="skinks.SkinnableContainer">
<s:Image id="img" left="10" top="10" width="130" height="130" scaleMode="zoom" smooth="true"
source="assets/images/album.png"/>
<s:VGroup width="100%" height="100%" top="10" left="140" bottom="10" right="10" gap="0">
<s:HGroup width="100%" height="100%" verticalAlign="middle" paddingLeft="10">
<s:Label width="50" color="#FFFFFF" fontFamily="微软雅黑" fontSize="14"
text="专辑名" textAlign="right"/>
<s:TextInput id="albumName" width="180" height="30" borderVisible="false" fontFamily="微软雅黑"
fontSize="14"/>
</s:HGroup>
<s:HGroup width="100%" height="100%" verticalAlign="middle" paddingLeft="10">
<s:Label width="50" color="#FFFFFF" fontFamily="微软雅黑" fontSize="14" text="歌手"
textAlign="right"/>
<s:TextInput id="singer" width="180" height="35" borderVisible="false" fontFamily="微软雅黑"
fontSize="14"/>
</s:HGroup>
</s:VGroup> </s:SkinnableContainer>
</s:Group> <!--数据列表-->
<s:DataGrid id="filesDG" width="460" color="#FFFFFF" fontFamily="微软雅黑" fontSize="13"
requestedRowCount="4" rowHeight="70" skinClass="skinks.DG">
<!--<s:columns>
<s:ArrayList>
<s:GridColumn dataField="id" headerText="#" headerRenderer="components.GridHeaderRenderer" itemRenderer="components.GridItemRenderer"></s:GridColumn>
<s:GridColumn dataField="song" headerText="歌曲" headerRenderer="components.GridHeaderRenderer" itemRenderer="components.GridItemRenderer"></s:GridColumn>
<s:GridColumn dataField="sf" headerText="后缀" headerRenderer="components.GridHeaderRenderer" itemRenderer="components.GridItemRenderer"></s:GridColumn>
</s:ArrayList>
</s:columns>-->
</s:DataGrid> <mx:ProgressBar
id="progressbar"
width="100%"
height="15"
labelPlacement="center"
barSkin="skinks.ProgressBar.CustomProgressSkin"
trackSkin="skinks.ProgressBar.CustomProgressBarTrackSkin" color="0xFFFFFF"
minimum="0"
visible="true"
maximum="100"
label="CurrentProgress 0%"
direction="right"
mode="manual"
/> <s:HGroup gap="0">
<s:Button id="browseBTN" label="浏览" fontFamily="微软雅黑"/>
<s:Button id="upload_btn" label="上传" fontFamily="微软雅黑"/>
<s:Button id="delButton" label="移除" fontFamily="微软雅黑"/>
<s:Button id="clearButton" label="移除全部" fontFamily="微软雅黑"/>
</s:HGroup> </s:Group> </s:Application>

关于文件上传部分,是根据MultiFile Upload插件,通过自定义UI组件皮肤完成,可以参考我之前的一个修改实例:

Flex4/Flash多文件上传(带进度条)实例分享

五,后端代码物理实现(JAVA部分代码物理实现):

AlbumDao.java

package com.dao;

import java.awt.List;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList; import com.bean.Album; import com.resource.JDBCUtilSingle; public class AlbumDao { /**
* 插入专辑信息 返回ID号
* @param a_name
* @param a_singer
* @param a_image
* @return
*/
public int addAlbum(String a_name,String a_singer,String a_image){
Connection connection=null;
PreparedStatement statement=null;
ResultSet rs=null;
connection=JDBCUtilSingle.getInitJDBCUtil().getConnection();
int id=0; try {
//专辑信息插入
String sql="insert into album(a_name,a_singer,a_image) values(?,?,?)";
statement=connection.prepareStatement(sql);
statement.setString(1,a_name);
statement.setString(2,a_singer);
statement.setString(3,a_image);
//System.out.println(sql);
statement.executeUpdate();
//获取插入ID
rs = statement.getGeneratedKeys();
rs.next();
id = rs.getInt(1);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JDBCUtilSingle.getInitJDBCUtil().closeConnection(rs, statement, connection);
return id;
} /**
* 获取所有专辑信息
* @return 返回专辑列表
*/
public ArrayList selectAlbum(){
Connection connection=null;
PreparedStatement statement=null;
ResultSet rs=null;
connection=JDBCUtilSingle.getInitJDBCUtil().getConnection();
ArrayList albums=new ArrayList();
try {
//专辑信息插入
String sql="select * from album";
statement=connection.prepareStatement(sql);
rs=statement.executeQuery();
while(rs.next()){
albums.add(new Album(rs.getInt("a_id"), rs.getString("a_name"), rs.getString("a_singer"), rs.getString("a_image")));
} } catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
JDBCUtilSingle.getInitJDBCUtil().closeConnection(rs, statement, connection);
}
return albums;
}
}

SongDao.java

package com.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList; import com.bean.Album;
import com.bean.Song;
import com.resource.JDBCUtilSingle; public class SongDao { public int addSongs(int a_id,String s_name,String s_source){
Connection connection=null;
PreparedStatement statement=null;
ResultSet rs=null;
connection=JDBCUtilSingle.getInitJDBCUtil().getConnection();
int tag=0;
try {
String sql="insert into song(a_id,s_name,s_source) values(?,?,?)";
statement=connection.prepareStatement(sql);
statement.setInt(1,a_id);
statement.setString(2,s_name);
statement.setString(3,s_source);
tag=statement.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} JDBCUtilSingle.getInitJDBCUtil().closeConnection(rs, statement, connection);
return tag;
} public ArrayList getSongs(int a_id){
ArrayList songs=new ArrayList();
Connection connection=null;
PreparedStatement statement=null;
ResultSet rs=null;
connection=JDBCUtilSingle.getInitJDBCUtil().getConnection();
try {
String sql="select * from song where a_id="+a_id;
statement=connection.prepareStatement(sql);
rs=statement.executeQuery();
while(rs.next()){
songs.add(new Song(rs.getInt("s_id"), rs.getInt("a_id"), rs.getString("s_name"), rs.getString("s_source")));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{ JDBCUtilSingle.getInitJDBCUtil().closeConnection(rs, statement, connection);
} return songs; }
}

好吧,就写到这里了,因为代码是较早之前写的了,由于学校放假,闲来没事,就那之前的代码翻看了一遍,由于时间久远,也没写什么注释,在代码的语法和程序逻辑上,自己也硬是看了半天才回过神来。现在在代码中加了一些注释,添加了一些歌曲内容,已上传到测试空间中,欢迎大家来测试。由于本人水平有限,如文章在表述或代码方面有何不妥之处,欢迎批评指正。

你可能还对以下关于Flex的文章内容还感兴趣:

如以上文章或链接对你有帮助的话,别忘了在文章结尾处轻轻点击一下 “还不错”按钮或到页面右下角点击 “赞一个” 按钮哦。你也可以点击页面右边“分享”悬浮按钮哦,让更多的人阅读这篇文章。

作者:Li-Cheng
由于本人水平有限,文章在表述和代码方面如有不妥之处,欢迎批评指正。留下你的脚印,欢迎评论哦。你也可以关注我,一起学习哦!

Flex4/Flash开发在线音乐播放器 , 含演示地址的更多相关文章

  1. python 开发在线音乐播放器-简易版

    在线音乐播放器,使用python的Tkinter库做了一个界面,感觉这个库使用起来还是挺方便的,音乐的数据来自网易云音乐的一个接口,通过urllib.urlopen模块打开网址,使用Json模块进行数 ...

  2. Andriod小项目——在线音乐播放器

    转载自: http://blog.csdn.net/sunkes/article/details/51189189 Andriod小项目——在线音乐播放器 Android在线音乐播放器 从大一开始就已 ...

  3. 推荐美丽的flash网页MP3音乐播放器

    文章来源:PHP开发学习门户 地址:http://www.phpthinking.com/archives/491 在网页制作中.假设想在网页中插入mp3音乐来增添网页的互动感,提升用户体验度,这个时 ...

  4. 在线音乐播放器-----酷狗音乐api接口抓取

    首先身为一个在线音乐播放器,需要前端和数据库的搭配使用. 在数据库方面,我们没有办法制作,首先是版权问题,再加上数据量.所以我们需要借用其他网络播放器的数据库. 但是这些在线播放器,如百度,酷狗,酷我 ...

  5. Android开发之音乐播放器的实现

    Android音乐播放器 使用到Android的Actiivity和Service组件 播放音频的代码应该运行在服务中,定义一个播放服务MusicService,服务里定义play.stop.paus ...

  6. Android开发之音乐播放器

    做了一天的音乐播放器小项目,已经上传到github,将链接发到这里供大家参阅提议 https://github.com/wangpeng0531/MusicPlayer.git

  7. Android应用开发--MP3音乐播放器代码实现(一)

    需求1:将内存卡中的MP3音乐读取出来并显示到列表当中 1.   从数据库中查询所有音乐数据,保存到List集合当中,List当中存放的是Mp3Info对象 2.   迭代List集合,把每一个Mp3 ...

  8. H5音乐播放器源码地址

    源码获取 https://pan.baidu.com/s/1pR_bhIFFQWU6TK9ZvrRWIA      安卓安装包下载地址 https://pan.baidu.com/s/1Z8HF5LY ...

  9. 简单风格 在线音乐播放器(支持wav,MP3等)

    找了两天终于找到了,支持wav,MP3,其他格式没有测试. 1.修复了jQuery判断ie的bug, 2.修复播放循环 下载地址: http://pan.baidu.com/s/1o6upwHs

随机推荐

  1. bootstrap的datetimepicker只选择月份

    本文转载自:http://blog.csdn.net/feng1603/article/details/41869523 直接上代码: //选择年月日的 startView: 2, minView: ...

  2. 【转】c# winform DataGridView导出数据到Excel中,可以导出当前页和全部数据

    准备工作就是可以分页的DataGridView,和两个按钮,一个用来导出当前页数据到Excel,一个用来导出全部数据到Excel 没有使用SaveFileDialog,但却可以弹出保存对话框来 先做导 ...

  3. 黄聪:WordPress 多站点建站教程(六):使用WP_Query、switch_to_blog函数实现获取子站点分类中的文章

    首先在你使用主题的funtions.php里面添加下代码: //根据时间显示最新的分类文章内容,每个站点显示一篇内容 //$blog_id 子站点ID //$catid 分类ID wp_reset_q ...

  4. J2EE学习中一些值得研究的开源项(转)

    这篇文章写在我研究J2SE.J2EE近三年后.前3年我研究了J2SE的Swing.Applet.Net.RMI.Collections. IO.JNI……研究了J2EE的JDBC.Sevlet.JSP ...

  5. PLSQL_基础系列04_时间间隔INTERVAL(案例)

    2014-12-08 Created By BaoXinjian

  6. PLSQL_性能优化系列06_Oracle Soft Parse / Hard Parse软硬解析

    2014-08-11 Createed By BaoXinjian

  7. centos6配置远程桌面,使用xmanager访问

    现在linux的图形界面越来越丰富,使用图形界面操作也逐渐成为使用者的一种习惯.在我们安装文件的过程中,经常会应用得到. 比如远程安装oracle,或者有多台主机.避免在不同主机间切换显示器. 1.检 ...

  8. tcpdump学习

    #直接启动tcpdump将监视第一个网络接口上所有流过的数据包 -n不解析地址到nametcpdump -n #监视指定网络接口的数据包,不指定则为 eth0tcpdump -i eth1 #监视指定 ...

  9. queue 与 vector

    优先队列是队列的一种,不过它可以按照自定义的一种方式(数据的优先级)来对队列中的数据进行动态的排序 每次的push和pop操作,队列都会动态的调整,以达到我们预期的方式来存储. 例如:我们常用的操作就 ...

  10. C#导出带有格式的Excel(列宽,合并单元格,显示边框线,加背景颜色等)

    源地址:http://blog.sina.com.cn/s/blog_74f702e60101au55.html 导出excel相关设置:http://blog.csdn.net/wanmingtom ...