Archive for the FLEX Category

AS3 API for flex, flash, AIR

Sunday, April 10th, 2011 | Permalink

开发过程中使用API可以节省时间,这里有几十个API,它们可以在Flex, Flash和AIR中使用。
(more…)

Flex监听Java服务端推送的数据应用DEMO

Friday, November 26th, 2010 | Permalink

因为需要今天研究了一下Flex接收Java端推送的数据,以前做过相应的配置,但是今天在此操作时发现忘得一干二净。好记性不如烂笔头子,所以还只记下来的说。。。。
第一步:首先,创建一个Java web工程将BlazeDS相关包加到工程中接下来配置services-config.xml文件。

在services-config.xml中添加如下代码:

然后配置messaging-config.xml文件。



true
.


配置方法是在messaging-config.xml中添加如下代码:(代码中配置说明如果有疑问还请大家Google吧。。。哈哈)


0

10

5000



第二步:编写服务端代码。

好的配置信息完毕开始写代码。我们需要创建一个实体类用来同步Flex与Java数据类型。

Tick.java

package com.eunut.vo;
import java.math.BigDecimal;

public class Tick {

private String seqno;

public String getSeqno() {
return seqno;
}

public void setSeqno(String seqno) {
this.seqno = seqno;
}
}

因为是测试DEMO所以只写了一个属性

然后编写一个Servlet

package com.eunut.servlet;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.eunut.vo.Tick;

import flex.messaging.MessageBroker;
import flex.messaging.messages.AsyncMessage;
import flex.messaging.util.UUIDUtils;

public class TickCacheServlet extends HttpServlet {

/**
*
*/
private static final long serialVersionUID = 1L;
private static FeedThread thread;

protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {

String cmd = req.getParameter("cmd");
if (cmd.equals("start")) {
start();
}
if (cmd.equals("stop")) {
stop();
}
}

protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
super.doGet(req, resp);
}

public void destroy() {
super.destroy();
}

public void init() throws ServletException {
super.init();
}

public void start() {
if (thread == null) {
thread = new FeedThread();
thread.start();
}
System.out.println("start!!");
}

public void stop() {
thread.running = false;
thread = null;
}

public static class FeedThread extends Thread {

public boolean running = true;

public void run() {
MessageBroker msgBroker = MessageBroker.getMessageBroker(null);
String clientID = UUIDUtils.createUUID();
int i = 0;
while (running) {
Tick tick = new Tick();
tick.setSeqno(String.valueOf(i));
System.out.println(i);

AsyncMessage msg = new AsyncMessage();
msg.setDestination("tick-data-feed");
msg.setHeader(AsyncMessage.SUBTOPIC_HEADER_NAME, "tick");
msg.setClientId(clientID);
msg.setMessageId(UUIDUtils.createUUID());
msg.setTimestamp(System.currentTimeMillis());
msg.setBody(tick);
msgBroker.routeMessageToService(msg, null);
i++;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
}
}
}
}

第三步:编写客户端代码。

客户端简单请见代码:
Tick.as

package com.eunut
{
[RemoteClass(alias="com.eunut.Tick")]
[Bindable]
public class Tick
{
public function Tick()
{
}
public var seqno:String;

}
}

主应用:


第四步:测试码。

首先运行客户端,点击按钮初始化消费者监听。

然后请求Servlet开启数据生产。方法是请求/TickCacheServlet?cmd=start

OK我们在客户端会看见标签上的数字会不断变大。

先写到这,回家。。。。

Flex+Java以AMF通讯方式截屏并保存到服务端的实例

Monday, November 22nd, 2010 | Permalink

今天闲着的时候研究了一下直接将flex中生成的报表转化成成图片直接通二进制流的方式传到服务端然后保存。

经过研究发现和简单。。。不罗嗦上代码。。。。
这个Demo使用了BlazeDS,有需要的朋友可以自己搭建环境,也可联系我索要工程。
Flex:

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”
layout=”vertical” backgroundGradientAlphas=”[1.0, 1.0]”
backgroundGradientColors=”[#FFFFFF, #C0C0C0]”
width=”700″ height=”650″ fontSize=”14″>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.rpc.events.ResultEvent;
import mx.core.Application;
import flash.display.BitmapData;
import mx.graphics.codec.JPEGEncoder;
import mx.graphics.codec.PNGEncoder;
import mx.collections.ArrayCollection;
import mx.core.UIComponent;
//将要保存的文件格式
public static const FORMAT_JPEG:uint = 0x00;
public static const FORMAT_PNG:uint = 0x01;
//文件扩展名
private static const EXT_JPEG:String = “.jpg”;
private static const EXT_PNG:String = “.png”;
//图标的初始化数据
[Bindable]
public var expenses:ArrayCollection = new ArrayCollection([
{Month:”Jan”, Profit:2000, Expenses:1500, Amount:450},
{Month:”Feb”, Profit:1000, Expenses:200, Amount:600},
{Month:”Mar”, Profit:1500, Expenses:500, Amount:300}
]);
//将图片按指定的格式保存
private function saveImage(comp:DisplayObject,format:uint):void{
//将可视组件转换为Bitmapdata
var bmpd:BitmapData = new BitmapData(comp.width,comp.height);
bmpd.draw(comp);
//图片最终的而二进制数组(Bytearray)
var imgByteArray:ByteArray;
//保存文件的扩展名
var ext:String;
//验证指定的保存格式,并按指定格式调用相应的编码器生成相应的二进制图片数组
switch(format){
case FORMAT_JPEG:
ext = EXT_JPEG;
var jpgenc:JPEGEncoder = new JPEGEncoder(80);
imgByteArray = jpgenc.encode(bmpd);
break;
case FORMAT_PNG:
ext = EXT_PNG;
var pngenc:PNGEncoder = new PNGEncoder();
imgByteArray = pngenc.encode(bmpd);
break;
}
server.saveIMG(imgByteArray,getNowTimestamp()+ext);
}
//获取一个时间戳作为保存图片的名字
private function getNowTimestamp():String{
var d:Date = new Date();
var tstamp:String = d.getFullYear().toString()+d.getMonth()+d.getDate()+d.getHours()+d.getMinutes()+d.getSeconds()+d.getMilliseconds();
return tstamp;
}
//点击保存按钮时的处理方法
private function onClickSave(e:MouseEvent):void{
saveImage(myChart,FORMAT_PNG);
}
private function onResultHandler(event:ResultEvent):void{
Alert.show(event.result.toString());
}
]]>
</mx:Script>
<mx:RemoteObject id=”server” destination=”saveIMG” result=”onResultHandler(event)” endpoint=”http://localhost/Demo/messagebroker/amf”/>
<mx:Label text=”Save a chart snapshot” color=”#171717″ fontSize=”20″ fontWeight=”bold”/>
<mx:Panel title=”Line Chart”>
<mx:LineChart id=”myChart”
dataProvider=”{expenses}”
showDataTips=”true”>
<mx:horizontalAxis>
<mx:CategoryAxis
dataProvider=”{expenses}”
categoryField=”Month” />
</mx:horizontalAxis>
<mx:series>
<mx:LineSeries
yField=”Profit”
displayName=”Profit” />
<mx:LineSeries
yField=”Expenses”
displayName=”Expenses” />
</mx:series>
</mx:LineChart>
<mx:Legend dataProvider=”{myChart}”/>
</mx:Panel>
<mx:Button id=”save_btn” label=”Click to save a snapshot” width=”181″ click=”onClickSave(event)”/>
</mx:Application>

<?xml version=”1.0″ encoding=”utf-8″?><mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml”  layout=”vertical” backgroundGradientAlphas=”[1.0, 1.0]”  backgroundGradientColors=”[#FFFFFF, #C0C0C0]” width=”700″ height=”650″ fontSize=”14″> <mx:Script> <![CDATA[ import mx.controls.Alert; import mx.rpc.events.ResultEvent; import mx.core.Application; import flash.display.BitmapData; import mx.graphics.codec.JPEGEncoder; import mx.graphics.codec.PNGEncoder; import mx.collections.ArrayCollection; import mx.core.UIComponent; //将要保存的文件格式 public static const FORMAT_JPEG:uint = 0x00; public static const FORMAT_PNG:uint = 0x01; //文件扩展名 private static const EXT_JPEG:String = “.jpg”; private static const EXT_PNG:String = “.png”; //图标的初始化数据 [Bindable] public var expenses:ArrayCollection = new ArrayCollection([ {Month:”Jan”, Profit:2000, Expenses:1500, Amount:450}, {Month:”Feb”, Profit:1000, Expenses:200, Amount:600}, {Month:”Mar”, Profit:1500, Expenses:500, Amount:300} ]); //将图片按指定的格式保存 private function saveImage(comp:DisplayObject,format:uint):void{ //将可视组件转换为Bitmapdata var bmpd:BitmapData = new BitmapData(comp.width,comp.height); bmpd.draw(comp); //图片最终的而二进制数组(Bytearray) var imgByteArray:ByteArray; //保存文件的扩展名 var ext:String; //验证指定的保存格式,并按指定格式调用相应的编码器生成相应的二进制图片数组 switch(format){ case FORMAT_JPEG: ext = EXT_JPEG; var jpgenc:JPEGEncoder = new JPEGEncoder(80); imgByteArray = jpgenc.encode(bmpd); break; case FORMAT_PNG: ext = EXT_PNG; var pngenc:PNGEncoder = new PNGEncoder(); imgByteArray = pngenc.encode(bmpd); break; } server.saveIMG(imgByteArray,getNowTimestamp()+ext); } //获取一个时间戳作为保存图片的名字 private function getNowTimestamp():String{ var d:Date = new Date(); var tstamp:String = d.getFullYear().toString()+d.getMonth()+d.getDate()+d.getHours()+d.getMinutes()+d.getSeconds()+d.getMilliseconds(); return tstamp; } //点击保存按钮时的处理方法 private function onClickSave(e:MouseEvent):void{ saveImage(myChart,FORMAT_PNG); } private function onResultHandler(event:ResultEvent):void{ Alert.show(event.result.toString()); } ]]> </mx:Script> <mx:RemoteObject id=”server” destination=”saveIMG” result=”onResultHandler(event)” endpoint=”http://localhost/Demo/messagebroker/amf”/> <mx:Label text=”Save a chart snapshot” color=”#171717″ fontSize=”20″ fontWeight=”bold”/> <mx:Panel title=”Line Chart”> <mx:LineChart id=”myChart”     dataProvider=”{expenses}”     showDataTips=”true”>    <mx:horizontalAxis>       <mx:CategoryAxis             dataProvider=”{expenses}”             categoryField=”Month” />    </mx:horizontalAxis>    <mx:series>       <mx:LineSeries             yField=”Profit”             displayName=”Profit” />       <mx:LineSeries             yField=”Expenses”             displayName=”Expenses” />    </mx:series> </mx:LineChart> <mx:Legend dataProvider=”{myChart}”/> </mx:Panel> <mx:Button id=”save_btn” label=”Click to save a snapshot” width=”181″ click=”onClickSave(event)”/></mx:Application>

Java:

package com.eunut.demo;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

public class IMGServer {

public String saveIMG(byte [] io,String fileName){
BASE64Encoder encode = new BASE64Encoder();
String base64 = encode.encode(io);
if(generateImage(base64, "D:\\"+fileName))
return "图片保存成功!";
else
return "图片保存失败,请重新保存!";
}
// 将图片文件转化为字节数组字符串,并对其进行Base64编码处理
public static String GetImageStr(String imgFilePath) {
byte[] data = null;
// 读取图片字节数组
try {
InputStream in = new FileInputStream(imgFilePath);
data = new byte[in.available()];
in.read(data);
in.close();
} catch (IOException e) {
e.printStackTrace();
}
// 对字节数组Base64编码
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(data);// 返回Base64编码过的字节数组字符串
}

// 对字节数组字符串进行Base64解码并生成图片
public static boolean generateImage(String imgStr, String imgFilePath) {
if (imgStr == null) // 图像数据为空
return false;
BASE64Decoder decoder = new BASE64Decoder();
try {
// Base64解码
byte[] bytes = decoder.decodeBuffer(imgStr);

for (int i = 0; i < bytes.length; ++i) {
if (bytes[i] < 0) {// 调整异常数据
bytes[i] += 256;
}
}

// 生成图片
OutputStream out = new FileOutputStream(imgFilePath);
out.write(bytes);
out.flush();
out.close();
return true;
} catch (Exception e) {
return false;
}
}
}

Mina+AMF3 解码粘包解决方法

Monday, November 22nd, 2010 | Permalink

废话少说上代码
AMF3Decoder.java

package com.eunut.server.filter;

import java.io.DataInputStream;
import java.util.zip.InflaterInputStream;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;

import com.eunut.server.vo.RequestMessage;

import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf3Input;

public class AMF3Decoder extends CumulativeProtocolDecoder
{
private final SerializationContext context = new SerializationContext();
private Amf3Input amf3in;
public AMF3Decoder()
{
}

@Override
protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception
{
long sid = session.getId();
if(in.prefixedDataAvailable(4)){
amf3in = new Amf3Input(context);
// 正常读取包头制定长度数据
int len = in.getInt();
Object message = null;
byte bytes[] = new byte[len];
in.get(bytes, 0, len);
IoBuffer tempIn = IoBuffer.wrap(bytes);
try {
amf3in.setInputStream(new InflaterInputStream(new DataInputStream(tempIn.asInputStream())));
message = amf3in.readObject();
if (message != null && (message instanceof RequestMessage)) {
out.write(message);
amf3in.close();
amf3in = null;
} else {
System.out.println(sid+":不是amf3 RequestMessage 跳出");
}
} catch (Exception e) {
System.out.println(sid+":AMF3Decoder doDecode Exception:" + e);
return false;
}finally{
tempIn.free();
tempIn = null;
bytes = null;
}
return true;
}else{
System.err.println("又粘包了!");
return false;
}
}
}

简单的拼图小游戏

Saturday, September 4th, 2010 | Permalink

由于需要,做的这么个简单的小游戏,其实有些事情并不难,就是找个合适的解决方案。
上代码:

package {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.errors.MemoryError;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.net.URLRequest;
	import flash.text.TextField;

	public class ImagePuzzle extends Sprite
	{
		private var img:Loader = new Loader();
		private var num:uint = 6;
		private var blocks:Array = new Array(num);
		private var currPosition:Object = {"indexX":num-1,"indexY":num-1};
		private var result:TextField;
		public function ImagePuzzle()
		{
			img.contentLoaderInfo.addEventListener(Event.COMPLETE,cutImg);
			img.load(new URLRequest("16.jpg"));
			this.stage.addEventListener(KeyboardEvent.KEY_DOWN,keyHandle);
			result =  new TextField();
			result.text="进行中。。。";
			result.height = 24;
			result.x = 260;
			addChild(result);
		}

		private function cutImg(event:Event):void{
			var oldImg:Bitmap = Bitmap(img.content);
			var bitImgData:BitmapData = oldImg.bitmapData;
			var blockW:Number =  bitImgData.width/num;
			var blockH:Number =  bitImgData.height/num;
			oldImg.x = bitImgData.width + 20;
			oldImg.y = result.height;
			addChild(oldImg);
			for (var i:Number = 0;i<num;i++){
				blocks[i] = new Array(num);
				for (var j:Number = 0;j<num;j++){
					var block:BitmapData = new BitmapData(blockW,blockH, false, 0x000000);
					var toX:Number = blockW*j;
					var toY:Number = blockH*i;
					var blockImg:Bitmap = new Bitmap(block);
					if(!(i == num-1 && j == num-1)){
						block.copyPixels(bitImgData,
							new Rectangle(toX,toY,blockW,blockH),
							new Point(0,0));
					}
					blockImg.x =   toX;
					blockImg.y =   toY+result.height;;
					blocks[i][j] = blockImg;
					blockImg.name = "blockImg"+i+j;
					addChild(blockImg);
				}
			}
			randomBlock();
		}



		private function swapBlock(temp:Object,currPosition:Object,isJudge:Boolean= true):void{
			var one:Bitmap = blocks[temp.indexX][temp.indexY];
			var two:Bitmap = blocks[currPosition.indexX][currPosition.indexY];
			var tempX:Number = one.x;
			var tempY:Number = one.y;
			one.x = two.x;
			one.y = two.y;
			two.x = tempX;
			two.y = tempY;
			blocks[temp.indexX][temp.indexY] = two;
			blocks[currPosition.indexX][currPosition.indexY] = one;
			if(isJudge){
				if(judgeWin())
					result.text = "YOU WIN !!!";
			}else{
				if(blocks[temp.indexX][temp.indexY].name=="blockImg55"){
					this.currPosition = {"indexX":temp.indexX,"indexY":[temp.indexY]};
				}
				if(blocks[currPosition.indexX][currPosition.indexY].name=="blockImg55"){
					this.currPosition = {"indexX":currPosition.indexX,"indexY":[currPosition.indexY]};
				}
			}
		}

		private function randomBlock():void{
			var temp:Number = Math.floor(Math.random()*num*num)+num*num/2;
			while(temp--){
				swapBlock(
					{"indexX":Math.floor(Math.random()*num),"indexY":Math.floor(Math.random()*num)},
					{"indexX":Math.floor(Math.random()*num),"indexY":Math.floor(Math.random()*num)},
					false
				);
			}
		}

		private function judgeWin():Boolean{
			for(var i:uint=0;i<blocks.length;i++)
				for(var j:uint=0;j0){
				currPosition.indexY--;
			}
			if(keyCode == 40 && currPosition.indexX>0){
				currPosition.indexX--;
			}
			if(keyCode == 37 && currPosition.indexY<(num-1)){
				currPosition.indexY++;
			}
			if(keyCode == 38 && currPosition.indexX<num-1){
				currPosition.indexX++;
			}
			swapBlock(temp,currPosition);
		}
	}
}

两个swf通过js通信的demo

Thursday, July 29th, 2010 | Permalink



	
		
	
	


Flex中自定义ToolTip

Monday, July 12th, 2010 | Permalink

Flex自带的ToolTip是一个矩形框加上一个文本框,可以通过修改style设置他的大小,背景,字体颜色等,但不能改变其形状,如果我想要一个其他形状的ToolTip就需要自定义了。自定义ToolTiP的方法与自定义其他组件一样,因为ToolTip本身就是一个组件,只是他需要实现IToolTip接口。



 
  
 
 

在程序中使用方法是在要显示ToolTip的组件里监听toolTipCreate事件,这个事件是在创建ToolTip前调用的,因此你可以在这里创建你自定义的ToolTip,如果要对这个ToolTip的位置定位,可以监听他的toolTipShow事件,这个事件是在要显示toolTip时调用的。



 
  
 
 

flex用样式文件自定义滚动条样式

Monday, July 5th, 2010 | Permalink

css样式文件

/* ScrollBar 全局*/
.scrollBar{
	trackSkin:Embed(source='images/track_skin.png', scaleGridLeft=8, scaleGridRight=9, scaleGridTop=11,scaleGridBottom=12);
	thumbUpSkin:Embed(source="images/thum_skin.png");
	thumbOverSkin:Embed(source='images/thum_skin.png', scaleGridLeft=8, scaleGridRight=9, scaleGridTop=11,scaleGridBottom=12);
	thumbDownSkin:Embed(source='images/thum_skin.png', scaleGridLeft=8, scaleGridRight=9, scaleGridTop=11,scaleGridBottom=12);
	downArrowSkin: Embed(source="images/down.png");
	upArrowSkin: Embed(source="images/up.png");
}

Mxml主文件



	
	
		
			
			
			
			
			
		
	


如果想使滚动条的thumbSkin设置成一个”点”或一个”块”,这个块是固定大小的..不像Flex自带的滚动条会随滚动区域的高度而改变,如果直接设置thumbSkin,那滑块将拉变形~非常难看。
这时候我们可以使用verticalScrollBar里的setScrollProperties方法来调整滑块高度。
例如重写

//每次刷新滚动条时调用一次setScrollProperties,设置pageSize为0
override protected function setScrollBarProperties(totalColumns:int, visibleColumns:int, totalRows:int, visibleRows:int):void
{
    super.setScrollBarProperties(totalColumns,visibleColumns,totalRows,visibleRows);
    if(verticalScrollBar)verticalScrollBar.setScrollProperties(0,verticalScrollBar.minScrollPosition,verticalScrollBar.maxScrollPosition,0);
}

ActionScript标记点位置的工具类

Monday, May 17th, 2010 | Permalink

package
{
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
 
	public class MarkPoint extends Sprite
	{
		private var _parent:DisplayObjectContainer;
 
		public function MarkPoint(parent:DisplayObjectContainer,o:Object,color:uint = 0x000000,radius:uint = 2)
		{
 
			_parent = parent;
 
			this.x = o.x;
 
			this.y = o.y;
 
			graphics.beginFill(color);
 
			graphics.drawCircle(0,0,radius);
 
			graphics.endFill();
 
			var pointXY:TextField = new TextField();
 
			pointXY.text = "("+o.x+","+o.y+")";
 
			pointXY.autoSize = TextFieldAutoSize.CENTER;
 
			pointXY.textColor = color;
 
			pointXY.x = - pointXY.width/2;
 
			pointXY.y = radius;
 
			pointXY.selectable = false;
 
			addChild(pointXY);
 
			addEventListener(Event.ENTER_FRAME,enterFrameHandler);
 
			_parent.addChild(this);
 
		}
 
		//将所有的点标记移至最上层
 
		private function enterFrameHandler(event:Event):void{
 
			_parent.setChildIndex(this,_parent.numChildren-1);
 
		}
 
	}
}