http://tylee82.tistory.com/96

위 블로그를 참조 바랍니다.

package wonsama.util.image

{

       import flash.display.IBitmapDrawable;

       import flash.net.URLRequest;

       import flash.net.URLVariables;

      

       import mx.graphics.ImageSnapshot;

       import mx.graphics.codec.PNGEncoder;

      

       /**

        * 화면 캡춰를 도와주는 유틸 클래스

        * */

       public final class WCapture

       {

            

             private static const _targetUrl:String = "http://localhost:8080/blazeds/web/imageProcess.jsp";

            

             /**

              * 지정한 UIComponent 화면 캡춰한다.

              * 기본적으로 설정된 서버 주소를 참조

              * @param target 스샷을 찍을 대상체(UIComponent여야 함에 유의)

              * @param targetUrl 값을 전송할 URL

              * */

             public static function takePicture(target:IBitmapDrawable,targetUrl:String=_targetUrl):void{

                   

                    var onSnapShot:ImageSnapshot = ImageSnapshot.captureImage(target);

                    ImageSnapshot.defaultEncoder = mx.graphics.codec.PNGEncoder;       //JPEGEncoder 화질이 떨어짐.75%부터 동작유의

                    var url:URLRequest = new URLRequest(targetUrl);

                                       

                    var params:URLVariables = new URLVariables();

                    params.imageData = ImageSnapshot.encodeImageAsBase64(onSnapShot);       //64Base 인코딩한 것을 파라미터로 설정한다.

                   

                    url.method = "POST";

                    url.data = params;

                    flash.net.navigateToURL(url,'_self');

             }

      

}

=====> 아래글은 참조 원문입니다. 감사합니다 쿠노기 님 ^^

[출처] 간단한 이미지 캡쳐 소스 - Flex 3.0 [JSP] (FlexComponent) |작성자 쿠노기

============================================================================

ImageCapture.mxml

============================================================================

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
  initialize="System.useCodePage=true" width="669" height="393">
 <mx:Script>
  <![CDATA[

   import mx.collections.ArrayCollection;
   import mx.graphics.ImageSnapshot;
   import mx.graphics.codec.*;


   [Bindable]
       public var expenses:ArrayCollection = new ArrayCollection([
          {Month:"Jan", Profit:2000, Expenses:1500},
          {Month:"Feb", Profit:1000, Expenses:200},
          {Month:"Mar", Profit:1500, Expenses:500}
       ]);
      
   private function doCapture():void{
    ImageSnapshot.defaultEncoder =  PNGEncoder;   //defaultEncoder 의 codec 타입을 jpeg로 했더니 화질이 좀 깨져버리네용...
    var onSnapShot:ImageSnapshot = ImageSnapshot.captureImage(myChartVBox);    //걍 챠트를 캡펴했더니 배경이 검게 나와서리 VBOX에 챠트를 넣고 VBOX를 캡쳐 했습니당..
    encodeType.text = onSnapShot.contentType;
    myTextarea.text = ImageSnapshot.encodeImageAsBase64(onSnapShot);
    //myTextarea.text = onSnapShot.contentType;

   }

   private function  sendChartImageToJsp():void{
    doCapture();
    var url:URLRequest = new URLRequest("http://{서버}/decoding.jsp");
    var params:URLVariables = new URLVariables();
    params.test = myTextarea.text;
    url.method = "POST";
    url.data = params;
    navigateToURL(url,'_self');
   }
  ]]>
 </mx:Script>
 <mx:Button x="10" y="337" label="캡쳐" click="doCapture()"/>
 <mx:TextArea x="10" y="191" id="myTextarea" width="558" height="108"/>
 <mx:TextInput x="10" y="307" width="558" id="encodeType"/>
 <mx:Button x="66" y="337" label="Send" click="sendChartImageToJsp()"/>
 <mx:VBox x="10" y="10" width="558" height="173" backgroundColor="#FFFFFF" id="myChartVBox">
  <mx:ColumnChart id="myChart" dataProvider="{expenses}" width="558" height="173" showDataTips="true">
      <mx:horizontalAxis>
         <mx:CategoryAxis  categoryField="Month"/>
      </mx:horizontalAxis>
      <mx:series>
         <mx:ColumnSeries xField="Month" yField="Profit" displayName="Profit" />
         <mx:ColumnSeries xField="Month" yField="Expenses" displayName="Expenses" />
      </mx:series>
   </mx:ColumnChart>
 </mx:VBox>
 
</mx:Application>

============================================================================

decoding.jsp    /서버단 jsp 코딩...초 간당....

============================================================================

<%@ page language="java" contentType="text/html; charset=EUC-KR" pageEncoding="EUC-KR"%>

<%@ page import="java.io.*" %>
<%@ page import="sun.misc.*" %>                  //sun.misc.BASE64Decoder 사용
<%
String str=request.getParameter("test");
OutputStream outs = null;
try{
// 쿠키 등의 정보를 지우므로 이전에 세팅을 해서는 않된다네요...^^ 
     response.reset(); 
     response.setContentType("application/smnet");
     response.setHeader("Content-Disposition","attachment; filename=capture.png");     //filename에 원하는 저장 파일의 이름을 ..확장자는 .png로 주세요
     response.setHeader("Content-Transfer-Encoding", "binary;");
     response.setHeader("Pragma", "no-cache;");
     response.setHeader("Expires", "-1;");


     BASE64Decoder decode= new BASE64Decoder(); 
     byte[] bt= decode.decodeBuffer(str);
     outs = response.getOutputStream();
     outs.write(bt);
     outs.close();
}finally{
     outs.close();
}
%>


[ JSP 코딩 참조사항 ]
outs = response.getOutputStream();  라인을
OutputStream outs = null; 아래 바로 적어주면 getOutputStream()을 또 호출했습니다. 라는 Exception이 발생하지 않게 됩니다.


buttonMode="true"
mouseChildren="false"
useHandCursor="true"

위 3개를 모두 설정하면 사용할 수 있음 !

XY 행렬형태의 배치에서 includeInLayout과 visible을 활용하여 위와 같이 화면 배치를 조절할 수 있습니다.
아래 코드를 참조하여 다양한 형태로 메뉴구성을 조절 한다면 멋질거 같네요 ^^

소스코드보기 ▼



FLEX에서 레이아웃 배치를 할 때 궁금점이 있어 테스트를 진행하여 보았습니다.

아래와 같은 테스트 코드에서

0. 버튼 누르기 전
1. includeInLayout
2. width
3. percentWidth

각각 3개를 조절하였을 때 화면상에서 어떻게 보이는지를 확인해 보았습니다.


0. 버튼 누르기 전


1. b1.includeInLayout = false;
==> 검정 화면이 레이아웃에서 제거 되면서 horizontalGap 또한 줄어 들어 실제적으로 녹색화면이 약간 크기가 증가한 모습으로 보임.

2. b1.width = 0;
==> 검정색 화면의 크기가 0으로 줄어 들었지만 컨테이너 내부에는 존재하므로 horizontalGap은 유지되어 아래와 같은 그림으로 보임.

b1.percentWidth = 0;
==> percentWidth 적용시 컨테이너 내부 항목의 크기를 최소값으로 유지하여 아래와 같은 그림으로 보임.
 

각각 약간의 차이가 보이네요 ^^ 도움이 되셨나요 ?  레이아웃 설계시 참조가 되었음 하네요 ^_^
[참조] 사항으로 rawChildren 을 공부하시면 더 도움이 될거 같네요 ~




http://www.adobe.com/cfusion/entitlement/index.cfm?e=flex%5Fskins 에 접속하여 다양한 형태의 플렉스 스킨 적용 방법을 확인 할 수 있습니다.
(위 사이트에 접속하면 Flash, FireWork 등 다양한 방법으로 스킨을 적용할 수 있습니다.)

우선적으로 AdobePhotoShop을 활용하여 스킨을 적용하는 방법을 설명하겠습니다.

[ 설치 파일 ]

1. 포토샵이 설치된 폴더에 다운로드 받은 Presets 폴더의 압축을 해제합니다.

2. 포토샵 실행 File -> Scripts -> New Flex Skin ...


3. 적절한 옵션을 선택


4. 파일을 수정(해당 레이어를 수정하면 됨)


5. 작업 완료 이후 파일 저장

(_HIDE BEFORE EXPORTING 라는 레이어는 Export 이전에 숨겨야 된다.)

6. File - Scripts -> Export Flex Skin ... 을 선택한다.

[그림 : 작업 완료 이후 생성된 파일 ]

7. 마지막으로 Flex에서 Import - Skin Artwork 메뉴에서 이전 저장한 파일을 Import 하면된다.





8. 작업 완료 이후 생성된 파일을 확인 할 수 있다.
( CSS생성, MXML에 CSS구문 추가, Image File Import 작업)




9. 작업전과 작업 이후 변경된 TabBar의 모습

작업 전
작업 이후

[이미지는 자작으로 만든것이라 ㅡ,.ㅡ;; 안 이뻐도 이해를....]

10, 기타 사항

앞에서도 언급한 것처럼 위 방법은 PhotoShop을 가지고 적용하는 방법입니다. Flash를 사용할 경우 위 사이트를 참조하여 작업을 진행하시면 될것입니다.

11. TEST CODE [ tabBarTest.mxml ]

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
 
 xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
 <mx:TabBar dataProvider="tabSource" />
 
 <mx:ViewStack id="tabSource">
  <mx:HBox label="TAB 1" />
  <mx:HBox label="TAB 2" />
  <mx:HBox label="TAB 3" /> 
 </mx:ViewStack> 
 <mx:Style source="assets.css"/> <!-- ARTWORK 사용시 자동적으로 추가 된 부분-->
</mx:Application>

요즘 실시간 모니터링 관련 DASHBOARD를 만들고 있는데.. 관련하여 차트를 만들고 있습니다.

1. RO를 통한 데이터 수신

//    2초단위 작업 시 발생 어러 ConcurrentModificationException
//
//    [참조] 실제 개수 = 개수 * 서버수(10) * 자료수(3)
//
//    시간(초)    서버        개수        결과        RO 수신시간
//    2,000    10        43200    ERROR        -
//    4,000    10        21600    OK        9.359
//    10,000    10        8640    OK        3.531
//    20,000    10        4320    OK        1.688
//    30,000    10        2880    OK        1.172
//    60,000    10        1440    OK        0.578
//
//    작업 진행은 시간 계산이 편한 10초 단위로 진행함.

위 표를 보면 알 수 있듯이 너무 많은 량의 데이터를 수신하려 한다면 flex messaging 처리 부분에서 힙 메모리 오버 플로우 애러가 발생하네요. 그래서 어쩔 수 없이 데이터를 줄여서 처리 했습니다. 맨 위 삽입한 차트가 1분(60초) 단위로 처리한 데이터를 RO를 통해 한번에 수신한 것인데 ... 그래도 차트 자체가 빡빡하네여 실제 적용할 때에는 20~30분 단위로 처리한다음 구간 SELECT 형태로 바꿔야 깔끔한 처리가 가능할 거 같습니다.

2. message-push 를 통한 데이터 수신 처리

RO를 통해 오늘-어제 데이터를 수신한 다음 실시간 데이터를 넣으면서 어제 데이터를 오늘 날짜로 업데이트 하는 형태의 차트 입니다. 위와 같이 처리를 하려 하니 차트 업데이트 과정에서 약간의 시간 지연 현상이 발생하는 거 같더군요 데이터 량이 많아 그런지 ㅡ,.ㅡ;

그리고 제가 전에 한 blazeDS 관련 포스팅 . message-push 서비스 사용시 channel-definition 에서 properties가 존재하지 않으면 ie7, ie8 에서는 정상적으로 message-push가 동작하지 않는거 잊지 말기 바랍니다. 아마도 요거 버그 같은데 ... 뭐 물어볼 분도 없구 ㅡ,.ㅡ blazeDS관련 국내 커뮤니티는 찾기 힘든거 같네요 ^^

3. 결론

ㄱ. RO 사용시 많은 량의 데이터 수신은 속도 저하를 가져옴. 적절하게 필요한 데이터만 사용하자 !
ㄴ. Messaging 서비스는 다수의 데이터 서비스 사용시 설계를 잘 해야 된다.
(자바쪽에서 스레드 내부에서 메시지 생성시 타입, 데이터 형태로 메시지를 만들어 보내는것이 무난 하기는 한거 같음)

차트 관련 주저리 플젝 완료 될때까징 주우욱... 해보렵니다.


ArrayCollection을 2개 할당한 이후
데이터 수신용, 보여주기용(Bindable) 으로 설정하여 데이터를 컨트롤 해 주도록 하면 된다. 



소스 보기

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
 creationComplete="init()"
 xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 
 <mx:Script>
  <![CDATA[
   import mx.charts.chartClasses.Series;
   import mx.controls.CheckBox;
   import mx.collections.ArrayCollection;
   import mx.utils.ObjectProxy;
   
   private const MAX_SRV:uint = 3;
   [Bindable]
   private var viewArr:ArrayCollection = new ArrayCollection; //실제 보여주는 데이터
   private var rcvArr:ArrayCollection = new ArrayCollection; //받은 데이터
   
   
   
   private var fndIdx:uint;
   
   private var timer:Timer;
   
   private function init():void{
    timer = new Timer(1000);
    timer.start();
    timer.addEventListener(TimerEvent.TIMER, timerHandler);    
   }
   
   private function cbHandler(e:Event):void{
    generateRealValues();
   }
   
   private function generateRealValues():void{
    //보여주려는 것
    var tmpArr:ArrayCollection = new ArrayCollection;
    
    
    for(var i:uint=0;i<MAX_SRV;i++){
     var tmpCB:CheckBox = this["cb"+i] as CheckBox;
     if(tmpCB.selected){
      tmpArr.addItem(rcvArr.getItemAt(Number(tmpCB.id.substr(2))));
     }
    }
    
    viewArr = tmpArr;
   }
   
   private function timerHandler(e:TimerEvent):void{
    generateDummyValues();
   }
   
   private function generateDummyValues():void{
    
    rcvArr.removeAll();
    
    for(var i:uint=0;i<MAX_SRV;i++){
     var op:ObjectProxy = new ObjectProxy();
     
     op.server = "srv"+i;   // label field
     
     op.apple = randRange(0,5);  // data field
     op.melon = randRange(0,5);
     op.banana = randRange(0,5);
          
     rcvArr.addItem(op);
    }
    
    generateRealValues();
   }
   
   
   
   private function randRange(min:Number, max:Number):Number {
    var randomNum:Number = Math.floor(Math.random() * (max - min + 1)) + min;
    return randomNum;
   }
  ]]>
 </mx:Script>

 <mx:VBox width="100%" height="100%">
  <mx:HBox>
   <mx:Label text="SELECT SERVER :" />
   <mx:CheckBox id="cb0" label="srv0" selected="true" change="cbHandler(event)"/>
   <mx:CheckBox id="cb1" label="srv1" selected="true" change="cbHandler(event)"/>
   <mx:CheckBox id="cb2" label="srv2" selected="true" change="cbHandler(event)"/>
  </mx:HBox>
  <mx:HBox width="100%" height="100%">
   <mx:BarChart id="barchart1" height="100%" width="100%" dataProvider="{viewArr}">
    <mx:series>
     <mx:BarSet type="stacked" allowNegativeForStacked="true" >
      <mx:series>
       <mx:BarSeries id="bs0" displayName="apple" yField="server" xField="apple"/>
       <mx:BarSeries id="bs1" displayName="banana" yField="server" xField="banana"/>
       <mx:BarSeries id="bs2" displayName="melon" yField="server" xField="melon"/>
      </mx:series>
     </mx:BarSet>     
    </mx:series>
    <mx:verticalAxis>
     <mx:CategoryAxis dataProvider="{viewArr}" categoryField="server"/>
    </mx:verticalAxis>
    <!-- 가로 축 정보 -->
          <mx:horizontalAxis>
             <mx:LinearAxis
         interval="1"
         maximum="15"
         maximumLabelPrecision="0"
         minimum="0"
         minorInterval="0"
       />
          </mx:horizontalAxis>
   </mx:BarChart>
   <mx:Legend dataProvider="{barchart1}"/>
   
   
  </mx:HBox>
  <mx:TextArea width="100%" height="50" />
 </mx:VBox>
</mx:Application>


작업환경 : 이클립스 J2EE  & FLEX 환경 (설치 참조 : http://wonsama.tistory.com/180 )
테스트 목적 : Remote Object를 확인하기 위해 테스트를 진행.
작업진행 : Eclipse에서 환경설정 및 클래스 생성 이후 Flex에서 해당 서비스 호출 소스 작성을 실시한다.

[Eclipse]
// WEB-INF/flex/remoting-config.xml :  리모트 오브젝트 관련 환경을 설정한다.

<?xml version="1.0" encoding="UTF-8"?>
<service id="remoting-service" class="flex.messaging.services.RemotingService">

    <adapters>
        <adapter-definition id="java-object"
            class="flex.messaging.services.remoting.adapters.JavaAdapter"
            default="true" />
    </adapters>

    <default-channels>
        <channel ref="my-amf" />
    </default-channels>

    <destination id="empRO">
        <properties>
            <source>book.EmployeeManager</source>           
        </properties>
    </destination>

</service>

RO를 사용하기 위하여 추가적으로 설정한 내용임.
1: destination id - FLEX에서 호출하는 RemoteObject의 destination 를 지정한다.
2: source - 참조하는 클래스 소스를 설정한다.

[Eclipse]
// src/book/Employee.java

package book;

import java.io.Serializable;

public class Employee implements Serializable {
    /**
     *
     */
    private static final long serialVersionUID = 1L;
    public String name;
    public String phone;
    public String email;
    public Employee(){

    }

    public Employee(String name, String phone, String email){
        this.name = name;
        this.phone = phone;
        this.email = email;
    }
}

[Eclipse]
// src/book/EmployeeManager.java

package book;

import org.apache.log4j.Logger;
import java.util.ArrayList;

public class EmployeeManager {
    /**
     * Logger for this class
     */
    private static final Logger logger = Logger.getLogger(EmployeeManager.class);
   
    public EmployeeManager(){

    }

   
    public Object[] getList(String deptId){

        if (logger.isDebugEnabled()) {
            logger.debug("getList(String) - start"); //$NON-NLS-1$
        }

        ArrayList<Employee> list = new ArrayList<Employee>();
        if(deptId.equals("ENG")){
            list.add(new Employee("Christina Coenreaets", "555-219-270","ccoenraets@fictitious.com" ));
            list.add(new Employee("Louis Freligh", "555-219-2270", "lfrelight@fictitious.com" ));
        }else if(deptId.equals("PM")){
            list.add(new Employee("Ronnie Hodgman", "555-219-2270", "ccoenraets@fictitious.com" ));
            list.add(new Employee("Joanne Wall", "555-219-2270", "lfrelight@fictitious.com" ));  
        }else if(deptId.equals("MKT")){
            list.add(new Employee("Maurice Smith", "555-219-2270", "ccoenraets@fictitious.com" ));
            list.add(new Employee("Mary Jones", "555-219-2270", "lfrelight@fictitious.com" ));  
        }
        Object[] returnObjectArray = list.toArray();

        if (logger.isDebugEnabled()) {
            logger.debug("getList(String) - end"); //$NON-NLS-1$
        }else{
            System.out.println("err");
        }

        return returnObjectArray;
    }
}

[FLEX]
// src/blaze.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
 <mx:Script>
  <![CDATA[
   import mx.controls.Alert;
   import mx.rpc.events.FaultEvent;
   import mx.rpc.events.ResultEvent;
  
   private function resultHandler(event:ResultEvent):void{
    dg.dataProvider = event.result;
   }
  
   private function faultHandler(event:FaultEvent):void{
    mx.controls.Alert.show(event.fault.message);
   }
  
  ]]>
 </mx:Script>
 
 <mx:RemoteObject id="emp" destination="empRO" showBusyCursor="true"  result="resultHandler(event)" fault="faultHandler(event)"/>


 <mx:Panel width="95%" height="95%" layout="absolute"
     title="RemoteObject UTF8" >
  <mx:DataGrid id="dg" width="100%" height="100%" />
  <mx:ControlBar horizontalAlign="center">
   <mx:HBox>
    <mx:Label text="Select a department :" />
    <mx:ComboBox id="dept" width="150">
     <mx:dataProvider>
      <mx:Array>
       <mx:Object label="Engineering" data="ENG" />
       <mx:Object label="Product Management" data="PM" />
       <mx:Object label="Marketing" data="MKT" />
      </mx:Array>
     </mx:dataProvider>
    </mx:ComboBox>
    <mx:Button label="Get Employee List" click="emp.getList(dept.selectedItem.data)" />
   </mx:HBox>
  </mx:ControlBar>
 
 </mx:Panel>
 
</mx:Application>


<mx:RemoteObject id="emp" destination="empRO" showBusyCursor="true"  result="resultHandler(event)" fault="faultHandler(event)"/>
=> RO를 설정한 부분
=> destination : Eclipse에 설정된 클래스를 호출하기 위한 Destination

<mx:Button label="Get Employee List" click="emp.getList(dept.selectedItem.data)" />
=> RO를 호출하는 부분
=> emp.getList :  getList 메소드를 호출한다. 처리 결과는 위에서 설정한 리스너를 통해 들어온다.

[처리 결과]


결론 및 요약 :

- [Eclipse] remoting-config.xml 설정 => 설정에 맞춰 클래스 생성 => [Flex] RO호출
- RO를 통해 처리를 JAVA로 위임한 이후 결과를 받아 처리 할 수 있음. 매우 유익한듯.





'기타 > Old' 카테고리의 다른 글

MS '윈도7 RC 버전' 공개됐다  (0) 2009.05.01
구글·네이버, 닮은꼴 서비스 경쟁 '후끈'  (0) 2009.04.30
설치하기  (0) 2009.04.29
이벤트 링크  (0) 2009.04.29
삼성電, 'AM-OLED 안드로이드폰' 6월 출시  (1) 2009.04.28

+ Recent posts