반응형

기본적인 개념으로.. 데이터 그리드등에 ItemRenderer를 사용하여 checkBox 나 기타 등등의 컴포넌트를 넣었을때

데이터그리드를 스크롤하게 되면 체크박스의 데이터가 뒤죽박죽이 되는 문제가 발생한다.

이는.. 보이는영역에서 사라진 컴포넌트들이 재사용(!!) 되면서 일어나는 현상으로 다음과 같은 방법으로 해결한다.

<Adobe Flex4 Help에서 발췌>

Creating a recyclable item renderer


With virtual layout disabled, the DataGroup and SkinnableDataContainer containers create one instance of the item renderer for each child. With virtual layout enabled, the container only creates enough item renderers to display its currently visible children. Virtual layout greatly reduces the overhead required to use the DataGroup and SkinnableDataContainer containers.
With virtual layout enabled, when a child is moved off the visible area of the container, its item renderer is recycled. First, the item renderer’s data property is set to null. When the item renderer is reused, its data property is set to the data item representing the new child. Therefore, if a recycled item renderer performs any actions based on the value of the data property, it must first check that the property is not null. When the item renderer is reassigned, Flex also calls the updateRenderer() method of the item renderer owner. This method must set the owner and label properties on the item renderer. Subclasses of SkinnableDataContainer, can use the updateRenderer() method to set additional properties on the item renderer. Because a container can reuse an item renderer, ensure that you fully define its state. For example, you use a CheckBox control in an item renderer to display a true (checked) or
false (unchecked) value based on the current value of the data property. A common mistake is to assume that the CheckBox control is always in its default state of unchecked and only inspect the data property for a value of true.
However, remember that the CheckBox can be recycled and had previously been checked. Therefore, inspect the data property for a value of false , and explicitly uncheck the control if it is checked, as the following example shows:

<ItemRenderer의 dataChange 이벤트를 이용하는 방법>
Prerelease - 5 October 2009
USING FLEX 4 442
Building the user interface
<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\myComponents\MySimpleItemRendererCB.mxml -->
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:mx="library://ns.adobe.com/flex/halo"xmlns:s="library://ns.adobe.com/flex/spark" dataChange="setMgr();">
<fx:Script>
<![CDATA[
private function setMgr():void {
// Check to see if the data property is null.
if (data == null) return;
// If the data property is not null,
// set the CheckBox control appropriately..
if (data.manager == "yes") {
mgr.selected = true;
}
else {
mgr.selected = false;
}
}
]]>
</fx:Script>
<s:states>
<s:State name="normal"/>
<s:State name="hovered"/>
<s:State name="selected"/>
</s:states>
<s:HGroup verticalCenter="0" left="2" right="2" top="2" bottom="2">
<s:Label text="{data.lastName}, {data.firstName}"/>
<s:Label text="{data.companyID}"/>
<s:CheckBox id="mgr"/>
</s:HGroup>
</s:ItemRenderer>


Use the dataChange event of the ItemRenderer class to detect the change to its data property. This event is dispatched whenever the data property changes. Alternatively, you can override the data property. Alternatively, you can override the ItemRenderer.data
property itself, as the following example shows:

<data 속성을 오버라이드하는 방법>
Prerelease - 5 October 2009
USING FLEX 4 443
Building the user interface
<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\myComponents\MySimpleItemRendererCBData.mxml -->
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/halo"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Script>
<![CDATA[
override public function set data(value:Object):void {
super.data = value;
// Check to see if the data property is null.
if (value== null) return;
// If the data property is not null,
// set the CheckBox control appropriately..
if (value.manager == "yes") {
mgr.selected = true;
}
else {
mgr.selected = false;
}
}
]]>
</fx:Script>
<s:states>
<s:State name="normal"/>
<s:State name="hovered"/>
<s:State name="selected"/>
</s:states>
<s:HGroup verticalCenter="0" left="2" right="2" top="2" bottom="2">
<s:Label text="{data.lastName}, {data.firstName}"/>
<s:Label text="{data.companyID}"/>
<s:CheckBox id="mgr"/>
</s:HGroup>
</s:ItemRenderer>

상단의 두가지 방법을 이용하여 새로운 ItemRenderer를 생성한 후 다음과 같은 방법으로 사용한다.

<?xml version="1.0" encoding="utf-8"?>
<!-- containers\spark\SparkDataGroupContainerTypicalItem.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/halo"
xmlns:s="library://ns.adobe.com/flex/spark">
<s:layout>
<s:VerticalLayout/>
</s:layout>
<fx:Script>
<![CDATA[
[Bindable]
public var typicalObj:Object = {
firstName:"Long first name",
lastName:"Even longer last name",
companyID:"123456",
manager:"yes"
};
]]>
</fx:Script>
<s:Scroller>
<s:DataGroup itemRenderer="myComponents.MySimpleItemRendererCB"
height="100"
typicalItem="{typicalObj}" >
<s:layout>
<s:VerticalLayout useVirtualLayout="true"/>
</s:layout>
<mx:ArrayList>
<fx:Object firstName="Bill" lastName="Smith" companyID="11233" manager="yes"/>
<fx:Object firstName="Dave" lastName="Jones" companyID="13455" manager="no"/>
<fx:Object firstName="Mary" lastName="Davis" companyID="11543" manager="yes"/>
<fx:Object firstName="Debbie" lastName="Cooper" companyID="14266" manager="no"/>
<fx:Object firstName="Bob" lastName="Martins" companyID="11233" manager="yes"/>
<fx:Object firstName="Jack" lastName="Jones" companyID="13455" manager="no"/>
<fx:Object firstName="Sam" lastName="Johnson" companyID="11543" manager="yes"/>
<fx:Object firstName="Tom" lastName="Fitz" companyID="14266" manager="no"/>
<fx:Object firstName="Dave" lastName="Mead" companyID="11233" manager="yes"/>
<fx:Object firstName="Dave" lastName="Jones" companyID="13455" manager="no"/>
<fx:Object firstName="Mary" lastName="Davis" companyID="11543" manager="yes"/>
<fx:Object firstName="Debbie" lastName="Cooper" companyID="14266" manager="no"/>
</mx:ArrayList>
</s:DataGroup>
</s:Scroller>
</s:Application>


Posted by 1010
반응형

출처 : http://igna84.blogspot.kr/2010/03/flex-datagrid-itemrenderer-2-%EC%A0%84%EB%A9%B4%EC%A0%84.html


Flex DataGrid ItemRenderer #2 - 전면전

경력사원임에도 불구하고 나이가 어려서 그런지 신입사원 연수를 다녀오라는 지시에 지난 목요일 금요일 다녀오는 바람에 ItemRenderer 이야기가 늦어졌습니다. 기다리신 분 계신가요?? 죄송합니다. 본의아니게;;

아무튼 DataGrid ItemRenderer 라는 뜨거운 감자를 삼키기위해 어떤 모양의 ItemRenderer를 만들지 한번 생각해보도록 할까요.

 

처음이니 간단하게 CheckBox 아이템 렌더러를 만들도록 해봅시다.

 

일단 메인 어플리케이션을 만들어 놓습니다.

 

[code xml]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
    <![CDATA[
    import mx.collections.ArrayCollection;

    [Bindable]
    private var ac:ArrayCollection = new ArrayCollection([
                                     {index:1, description:"test1", toggle:"Y"},
                                     {index:2, description:"test2", toggle:"N"},
                                     {index:3, description:"test3", toggle:"N"},
                                     {index:4, description:"test4", toggle:"Y"},
                                     {index:5, description:"test5", toggle:"N"},
                                     {index:6, description:"test6", toggle:"N"},
                                     {index:7, description:"test7", toggle:"Y"},
                                     {index:8, description:"test8", toggle:"N"},
                                     {index:9, description:"test9", toggle:"N"},
                                     {index:10, description:"test10", toggle:"N"},
                                     {index:11, description:"test11", toggle:"N"},
                                     {index:12, description:"test12", toggle:"N"}
                                     ]);
    ]]>
</mx:Script>
<mx:DataGrid dataProvider="{ac}">
    <mx:columns>
        <mx:DataGridColumn headerText="index" dataField="index" />
        <mx:DataGridColumn headerText="description" dataField="description" />
        <mx:DataGridColumn headerText="check" dataField="toggle" />
    </mx:columns>
</mx:DataGrid>
</mx:Application>
[/code]

 

위와같이 코딩하고 컴파일하게되면 아래와 같이 산출물이 나오게 됩니다.

 

 

그럼 우리는 ratio라고 적혀있는 곳에 ItemRenderer를 적용할겁니다.

 

CheckBox를 상속받아 작업할겁니다. 왜 "UIComponent 안쓰고!"라고 말씀하신다면

그 이유는 UIComponent를 상속받은 클래스이기도 하고 지난시간 말했던 IDataRenderer, IDropInListitemRenderer, IListItemRenderer 이렇게 세 인터페이스가 이미 구현되어있으며 우리가 원하는 아이템 렌더러는 CheckBox아이템 렌더러이기 때문이지요.

 

[code as3]
package classes.controls.renderers
{
//-----------------------------------------------------------------------------
//
//  Import
//
//-----------------------------------------------------------------------------
import mx.core.IDataRenderer;
import mx.controls.CheckBox;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IDropInListItemRenderer;
import mx.controls.listClasses.IListItemRenderer;
import mx.events.FlexEvent;
public class CheckBoxRenderer extends CheckBox
{
    //-----------------------------------------------------------------------------
    //
    //  Constructor
    //
    //-----------------------------------------------------------------------------
    /**
     *  Constructor.
     */
    public function CheckBoxRenderer()
    {
        super();
    }

    //-----------------------------------------------------------------------------
    //
    //  Variables
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     *  데이터 변경 확인 플래그
     */
    private var dataChanged:Boolean = false;

    //-----------------------------------------------------------------------------
    //
    //  Override Methods
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     */
    override protected function createChildren():void
    {
        super.createChildren();
    }

    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();
    }

    /**
     *  @private
     */
    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);
    }
}
}
[/code]

초벌로 createChildren, commitProperties, updateDisplayList도 확장해 두고 아이템 랜더러로 사용하기 위한 준비를 마쳤습니다.

그리고 메인 어플리케이션은 아래와 같이 수정하고 컴파일 합니다.

[code xml]
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
    <![CDATA[
    import mx.collections.ArrayCollection;

    [Bindable]
    private var ac:ArrayCollection = new ArrayCollection([
                                        {index:1, description:"test1", toggle:"Y"},
                                        {index:2, description:"test2", toggle:"N"},
                                        {index:3, description:"test3", toggle:"N"},
                                        {index:4, description:"test4", toggle:"Y"},
                                        {index:5, description:"test5", toggle:"N"},
                                        {index:6, description:"test6", toggle:"N"},
                                        {index:7, description:"test7", toggle:"Y"},
                                        {index:8, description:"test8", toggle:"N"},
                                        {index:9, description:"test9", toggle:"N"},
                                        {index:10, description:"test10", toggle:"N"},
                                        {index:11, description:"test11", toggle:"N"},
                                        {index:12, description:"test12", toggle:"N"}
                                        ]);
    ]]>
</mx:Script>
<mx:DataGrid dataProvider="{ac}">
    <mx:columns>
        <mx:DataGridColumn headerText="index" dataField="index" />
        <mx:DataGridColumn headerText="description" dataField="description" />
        <mx:DataGridColumn headerText="radio" dataField="toggle" itemRenderer="classes.controls.renderers.CheckBoxRenderer" />
    </mx:columns>
</mx:DataGrid>
</mx:Application>
[/code]

일단 아래와 같은 결과가 나오면 성공입니다.

 

CheckBox 가 "Y"냐 "N"이냐에 따라 selected가 처리되는 로직이 필요합니다. 그러기 위해서는 그 코드를 어디에 넣는것이 좋을지 고민해봐야하는데 아까도 말했듯 모든 속성처리는 commitProperties에서 하게 됩니다. commitProperties를 호출하기 위해서는 저번에 이야기 했었던 대로 invalidateProperties() 메서드를 호출하면 됩니다. 그렇다면 코드를 아래와 같이 수정합니다.

 

[code as3]
package classes.controls.renderers
{
//-----------------------------------------------------------------------------
//
//  Import
//
//-----------------------------------------------------------------------------
import mx.core.IDataRenderer;
import mx.controls.CheckBox;
import mx.controls.dataGridClasses.DataGridListData;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IDropInListItemRenderer;
import mx.controls.listClasses.IListItemRenderer;
import mx.events.FlexEvent;
public class CheckBoxRenderer extends CheckBox
{
    //-----------------------------------------------------------------------------
    //
    //  Constructor
    //
    //-----------------------------------------------------------------------------
    /**
     *  Constructor.
     */
    public function CheckBoxRenderer()
    {
        super();
    }

    //-----------------------------------------------------------------------------
    //
    //  Variables
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     *  데이터 변경 확인 플래그
     */
    private var dataChanged:Boolean = false;
    //-----------------------------------------------------------------------------
    //
    //  Override Properties
    //
    //-----------------------------------------------------------------------------
    override public function set data(value:Object):void
    {
        super.data = value;

        dataChanged = true;

        invalidateProperties();
    }

    //-----------------------------------------------------------------------------
    //
    //  Override Methods
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     */
    override protected function createChildren():void
    {
        super.createChildren();
    }

    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();
        if(dataChanged)
        {
            dataChanged = false;
            updateProperties();
        }
    }

    /**
     *  @private
     */
    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);
    }

    //-----------------------------------------------------------------------------
    //
    //  Methods
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     *  CheckBox의 속성을 변경
     */
    private function updateProperties():void
    {
        if(listData.label == "Y")
        {
            selected = true;
        }
        else
        {
            selected = false;
        }

        invalidateDisplayList();
    }
}
}
[/code]

위와 같이 코딩하게 되면 아래와 같은 산출물이 나오게 됩니다.

 

 

썩 잘나오는거 같습니다. 몇가지 마음에 안 드는 것이 있는데 일단 CheckBox가 셀의 중앙에 갔으면 좋겠고 CheckBox를 클릭하고 휠을 돌려보면 Check가 풀려버리는 버그가 있다는 것이지요.

 

CheckBox를 중앙에 놓으려면 CheckBox의 너비를 알아야하는데 그것은 CheckBox는 기본적으로 14픽셀의 넓이를 갖습니다. 그것을 어떻게 아냐구요?

measuredWidth를 trace 해보면 간단하게 알 수 있습니다. 아, measuredWidth는 컨포넌트 객체의 기본 너비를 이야기 합니다.

 

위의 두가지 문제점을 해결하기 위해 아래와 같이 코드를 수정합니다.

 

[code as3]
package classes.controls.renderers
{
//-----------------------------------------------------------------------------
//
//  Import
//
//-----------------------------------------------------------------------------
import flash.events.MouseEvent;

import mx.core.IDataRenderer;
import mx.controls.CheckBox;
import mx.controls.dataGridClasses.DataGridListData;
import mx.controls.listClasses.BaseListData;
import mx.controls.listClasses.IDropInListItemRenderer;
import mx.controls.listClasses.IListItemRenderer;
import mx.core.mx_internal;
import mx.events.FlexEvent;

use namespace mx_internal;

public class CheckBoxRenderer extends CheckBox
{
    //-----------------------------------------------------------------------------
    //
    //  Constructor
    //
    //-----------------------------------------------------------------------------
    /**
     *  Constructor.
     */
    public function CheckBoxRenderer()
    {
        super();
    }

    //-----------------------------------------------------------------------------
    //
    //  Variables
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     *  데이터 변경 확인 플래그
     */
    private var dataChanged:Boolean = false;

    //-----------------------------------------------------------------------------
    //
    //  Override Properties
    //
    //-----------------------------------------------------------------------------
    override public function set data(value:Object):void
    {
        super.data = value;

        dataChanged = true;

        invalidateProperties();
    }

    //-----------------------------------------------------------------------------
    //
    //  Override Methods
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     */
    override protected function createChildren():void
    {
        super.createChildren();
    }

    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();
        if(dataChanged)
        {
            dataChanged = false;

            updateProperties();
        }
    }

    /**
     *  @private
     */
    override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
        super.updateDisplayList(unscaledWidth, unscaledHeight);

        currentIcon.x = (unscaledWidth - currentIcon.width) / 2;
    }

    //-----------------------------------------------------------------------------
    //
    //  Methods
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     *  CheckBox의 속성을 변경
     */
    private function updateProperties():void
    {
        if(listData.label == "Y")
        {
            selected = true;
        }
        else
        {
            selected = false;
        }

        invalidateDisplayList();
    }

    //-----------------------------------------------------------------------------
    //
    //  Override EventHandler
    //
    //-----------------------------------------------------------------------------
    /**
     *  @private
     */
    override protected function clickHandler(event:MouseEvent):void
    {
        super.clickHandler(event);

        //data[DataGridListData(listData).dataField] = selected ? "Y" : "N";

        if(selected)
        {
            data[DataGridListData(listData).dataField] = "Y";
        }
        else
        {
            data[DataGridListData(listData).dataField] = "N";
        }
    }
}
}
[/code]

 

currentIcon이라는 생소한 속성을 위에서 보실 수 있습니다. 그것은 체크박스에서 체크되는 아이콘을 지칭합니다. 그 currentIcon이란 녀석은 mx_internal이라는 접근자를 이용하고 있고 LanguageReference에는 표시되지 않고 있어서 그 존재를 모르는 사람이 많습니다.

예전에 저도 그것을 몰라서 HBox에다가 넣고 horizontalAlign="center"를 주는 바보같은 짓을 일삼았는데 이 사실을 알고 난뒤에 Container를 사용하지 않고 좀더 가볍게 itemRenderer를 만들어 낼 수 있었지요.


그래서 updateDisplayList() 메서드에서 좌표를 잡아서 셀의 중앙에 놓고 clickHandler라는 메서드를 확장하여 변경된 값을 data에 반영하게 합니다. 그렇게 되면 아래와 같은 결과물이 나오게 되지요.

 

 

오. 그럴싸하게 작동하는 것 같습니다만 몇가지 아쉬운점이 있습니다.

 

1. "Y", "N" 값으로만 작동하게 되어있다.

2. CheckBox를 클릭하면 뭔가 다른 행동을 하고 싶을땐 어떻게 하나.

 

이렇게 두가지 사항인데요.

이 부분에 대해서는 다음시간에 알아보도록 해요~


Posted by 1010
카테고리 없음2014. 6. 10. 15:02
반응형

<mx:TextArea id="ta"

      valueCommit="ta.verticalScrollPosition = ta.maxVerticalScrollPosition" />

 

이면 되네요.

단, change 이벤트가 아닌 valueCommit 를 사용하는 이유는,

change 이벤트는 사용자의 입력에 따른 text 변경에 대해서 발생되는 이벤트라서,

프로그램에서 ta.text += "~~~~ Log 내용"; 과 같은 방식으로 내용을 수정하게 되면 발생하지 않습니다.

valueCommit 은 API 를 한번 확인해보시면 아시겠지만, 값 자체의 변경에 대한 모든 경우에 발생을 하는군요.

 

그럼 다들 즐플렉스~하세요. ^^

출처 : http://blog.naver.com/PostView.nhn?blogId=ezmo01&logNo=110084670815

Posted by 1010
반응형

각 컨트롤 속성에서

 

Mouse.cursor = MouseCursor.ARROW; 이렇게 주면된다.

 

AUTO : 자동

ARROW : 화살표

BUTTON : 버튼 누를때 나오는 한손꾸락

HAND : 잡아당길때 나오는 손바닥

IBEAM : 텍스트 창에서 나오는 I모양

 

예) mouseOver="Mouse.cursor = MouseCursor.BUTTON;" 이렇게 하면 된다.

출처 : http://blog.naver.com/PostView.nhn?blogId=sehwanq&logNo=50091363895

Posted by 1010
반응형


위 처럼 컨트롤 포인트를 이용하여 사이즈를 조절하는 컴포넌트를 만들려면...

1. 우선 각각의 포인트가 되는 사각형을 만듭니다.

ControlPoint.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" 
   width="9" height="9">
 
 <s:Rect width="9" height="9">
  <s:fill>
   <s:SolidColor />
  </s:fill>
 </s:Rect>
</s:Group>


2. 그 다음 위 검정색 사각형을 위치시켜 놓을 컨트롤 박스(Group)를 만들고 위 사각형을 제 위치에 놓습니다.

<?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"
   xmlns:control="org.jhl.control.*"
   width="100" height="100">
 
 <fx:Script>
  <![CDATA[
   private var _currentPointID:String;
   private var _startPointX:Number = 0;
   private var _startPointY:Number = 0;
   private var _x:Number;
   private var _y:Number;
   private var _width:Number;
   private var _height:Number;
   
   protected function mouseDownListener( event:MouseEvent ):void
   {
    _startPointX = this.parent.mouseX;
    _startPointY = this.parent.mouseY;
    _currentPointID = ControlPoint(event.target).id;
    _x = this.x;
    _y = this.y;
    _width = this.width;
    _height = this.height;
    
    this.systemManager.addEventListener(MouseEvent.MOUSE_MOVE, moveListener);
    this.systemManager.addEventListener(MouseEvent.MOUSE_UP, upListener);
   }
  
   
   protected function moveListener( event:MouseEvent ):void
   {
    var pointer:ControlPoint = event.target as ControlPoint;
    
    var dx:Number = this.parent.mouseX - _startPointX;
    var dy:Number = this.parent.mouseY - _startPointY;
    
    if( _currentPointID == "topLeft" )
    {
     this.x = _x + dx;
     this.width = _width - dx;
     this.y = _y + dy;
     this.height = _height - dy;
    }
    else if( _currentPointID == "topCenter" )
    {
     this.y = _y + dy;
     this.height = _height - dy;
    }
    else if( _currentPointID == "topRight" )
    {
     this.width = _width + dx;
     this.y = _y + dy;
     this.height = _height - dy;
    }
    else if( _currentPointID == "middleLeft" )
    {
     this.x = _x + dx;
     this.width = _width - dx;
    }
    else if( _currentPointID == "middleRight" )
    {
     this.width = _width + dx;
    }
    else if( _currentPointID == "bottomLeft" )
    {
     this.x = _x + dx;
     this.width = _width - dx;
     this.height = _height + dy;
    }
    else if( _currentPointID == "bottomCenter" )
    {
     this.height = _height + dy;
    }
    else if( _currentPointID == "bottomRight" )
    {
     this.width = _width + dx;
     this.height = _height + dy;
    }
    
    event.updateAfterEvent();
   }
   
   
   protected function upListener( event:MouseEvent ):void
   {
    this.systemManager.removeEventListener(MouseEvent.MOUSE_MOVE, moveListener);
    this.systemManager.removeEventListener(MouseEvent.MOUSE_UP, upListener);
   }


    override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
   {
    super.updateDisplayList(unscaledWidth, unscaledHeight);
    
    var g:Graphics = this.graphics;
    
    g.clear();
    g.lineStyle(1, 0x000000);
    g.drawRect(0, 0, unscaledWidth, unscaledHeight);
   }
  ]]>
 </fx:Script>
  
 <control:ControlPoint id="topLeft" left="-4" top="-4" 
        mouseDown="mouseDownListener(event)" />
 <control:ControlPoint id="topCenter" top="-4" horizontalCenter="0"
        mouseDown="mouseDownListener(event)" />
 <control:ControlPoint id="topRight" right="-4" top="-4"
        mouseDown="mouseDownListener(event)" />
 
 <control:ControlPoint id="middleLeft" left="-4" verticalCenter="0"
        mouseDown="mouseDownListener(event)" />
 <control:ControlPoint id="middleRight" right="-4" verticalCenter="0"
        mouseDown="mouseDownListener(event)"/>
 
 <control:ControlPoint id="bottomLeft" left="-4" bottom="-5"
        mouseDown="mouseDownListener(event)" />
 <control:ControlPoint id="bottomCenter" bottom="-5" horizontalCenter="0"
        mouseDown="mouseDownListener(event)" />
 <control:ControlPoint id="bottomRight" right="-4" bottom="-5"
        mouseDown="mouseDownListener(event)" />
 
</s:Group>



이 컴포넌트를 이용하여 다음과 같은 결과물을 얻을 수 있습니다.


p.s. 하양감자님의 지적부분을 수정하여 업데이트 하였습니다.

Flex 4 배포버전 : 4.0.0.14159 [2010/03/21]
Flex 4 현재버전 : 4.1.0.16076 [2010/06/10]



어제 만든 컴포넌트를 활용하여 원을 컨트롤하는 컴포넌트를 만들어 볼려고 합니다.


위 그림 처럼 외부는 컨트롤하는 외곽선과 컨트롤 점들로 그리고 내부는 원, 여기서 원이 사각형 또는 다각형의 모양일 수도 있구요

이렇게 구성하기 위해 먼저 원을 그리면..

Circle.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"
   width="100" height="100">
 
 <fx:Script>
  <![CDATA[
   override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
   {
    super.updateDisplayList(unscaledWidth, unscaledHeight);
    
    var g:Graphics = this.graphics;
    
    g.clear();
    g.lineStyle(1, 0x000000);
    g.beginFill(0xEEEEEE);
    g.drawEllipse(0, 0, unscaledWidth, unscaledHeight);
    g.endFill();
   }
  ]]>
 </fx:Script>
  
</s:Group>

그리고 어제 만든 컴포넌트를 원 컴포넌트에 추가하면...
(원 컴포넌트를 컨트롤 하기 위해 컨트롤 컴포넌트에 target 이라는 속성을 둬서 원 컴포넌트를 컨트롤 하게 합니다.)

Circle.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"
   xmlns:control="org.jhl.control.*"
   width="100" height="100">
 
 <fx:Script>
  <![CDATA[
   override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
   {
    super.updateDisplayList(unscaledWidth, unscaledHeight);
    
    var g:Graphics = this.graphics;
    
    g.clear();
    g.lineStyle(1, 0x000000);
    g.beginFill(0xEEEEEE);
    g.drawEllipse(0, 0, unscaledWidth, unscaledHeight);
    g.endFill();
   }
  ]]>
 </fx:Script>

 <control:ControlBox target="{this}" width="{this.width}" height="{this.height}"/>

</s:Group>

그리고 아래는 수정된 컨트롤 컴포넌트...

ControlBox.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"
   xmlns:control="org.jhl.control.*"
   width="100" height="100" >
 
 <fx:Script>
  <![CDATA[
   import mx.core.UIComponent;
   private var _currentPointID:String;
   private var _startPointX:Number = 0;
   private var _startPointY:Number = 0;
   private var _x:Number;
   private var _y:Number;
   private var _width:Number;
   private var _height:Number;
   private var _target:UIComponent = null;
   
   
   public function set target( value:UIComponent ):void
   {
    _target = value;
   }


   protected function mouseDownListener( event:MouseEvent ):void
   {
    _startPointX = _target.parent.mouseX;
    _startPointY = _target.parent.mouseY;
    _currentPointID = ControlPoint(event.target).id;
    _x = _target.x;
    _y = _target.y;
    _width = _target.width;
    _height = _target.height;
    
    this.systemManager.addEventListener(MouseEvent.MOUSE_MOVE, moveListener);
    this.systemManager.addEventListener(MouseEvent.MOUSE_UP, upListener);
   }
  
   
   protected function moveListener( event:MouseEvent ):void
   {
    var dx:Number = _target.parent.mouseX - _startPointX;
    var dy:Number = _target.parent.mouseY - _startPointY;
    
    if( _currentPointID == "topLeft" )
    {
     _target.x = _x + dx;
     _target.width = _width - dx;
     _target.y = _y + dy;
     _target.height = _height - dy;
    }
    else if( _currentPointID == "topCenter" )
    {
     _target.y = _y + dy;
     _target.height = _height - dy;
    }
    else if( _currentPointID == "topRight" )
    {
     _target.width = _width + dx;
     _target.y = _y + dy;
     _target.height = _height - dy;
    }
    else if( _currentPointID == "middleLeft" )
    {
     _target.x = _x + dx;
     _target.width = _width - dx;
    }
    else if( _currentPointID == "middleRight" )
    {
     _target.width = _width + dx;
    }
    else if( _currentPointID == "bottomLeft" )
    {
     _target.x = _x + dx;
     _target.width = _width - dx;
     _target.height = _height + dy;
    }
    else if( _currentPointID == "bottomCenter" )
    {
     _target.height = _height + dy;
    }
    else if( _currentPointID == "bottomRight" )
    {
     _target.width = _width + dx;
     _target.height = _height + dy;
    }
    
    event.updateAfterEvent();
   }
   
   
   protected function upListener( event:MouseEvent ):void
   {
    this.systemManager.removeEventListener(MouseEvent.MOUSE_MOVE, moveListener);
    this.systemManager.removeEventListener(MouseEvent.MOUSE_UP, upListener);
   }
   
   
   override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
   {
    super.updateDisplayList(unscaledWidth, unscaledHeight);
    
    var g:Graphics = this.graphics;
    
    g.clear();
    g.lineStyle(1, 0x000000);
    g.drawRect(0, 0, unscaledWidth, unscaledHeight);
   }
  ]]>
 </fx:Script>
  
 <control:ControlPoint id="topLeft" left="-4" top="-4" 
        mouseDown="mouseDownListener(event)" />
 <control:ControlPoint id="topCenter" top="-4" horizontalCenter="0"
        mouseDown="mouseDownListener(event)" />
 <control:ControlPoint id="topRight" right="-4" top="-4"
        mouseDown="mouseDownListener(event)" />
 
 <control:ControlPoint id="middleLeft" left="-4" verticalCenter="0"
        mouseDown="mouseDownListener(event)" />
 <control:ControlPoint id="middleRight" right="-4" verticalCenter="0"
        mouseDown="mouseDownListener(event)"/>
 
 <control:ControlPoint id="bottomLeft" left="-4" bottom="-5"
        mouseDown="mouseDownListener(event)" />
 <control:ControlPoint id="bottomCenter" bottom="-5" horizontalCenter="0"
        mouseDown="mouseDownListener(event)" />
 <control:ControlPoint id="bottomRight" right="-4" bottom="-5"
        mouseDown="mouseDownListener(event)" />
 
</s:Group>

아래는 위 코드의 결과물입니다.


Flex 4 배포버전 : 4.0.0.14159 [2010/03/21]
Flex 4 현재버전 : 4.1.0.16076 [2010/06/10]


컨트롤 포인트를 이용해서 그림을 컨트롤 할 수 있는 소스입니다.

Image.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"
   xmlns:control="org.jhl.control.*"
   width="64" height="64">
 
 <fx:Script>
  <![CDATA[
   override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void
   {
    super.updateDisplayList(unscaledWidth, unscaledHeight);
    
    img.width = unscaledWidth;
    img.height = unscaledHeight;
   }
  ]]>
 </fx:Script>
 
 <s:BitmapImage id="img" source="@Embed('assets/rss.png')" />
 
 <control:ControlBox target="{this}" width="{this.width}" height="{this.height}"/>
 
</s:Group>

 




ControlBox 는 전에 올린 내용을 참고하시면 됩니다.



Posted by 1010
56. Eclipse Etc.../Eclipse2014. 5. 30. 11:05
반응형

출처 : http://jungkun86.egloos.com/4139049


컴퓨터를 포맷하는 바람에, 이클립스를 새로 설치하면서 관련된 플러그인을 설치했다.

subversive 플러그인을 설치한 후 이클립스를 재기동하니, SVN connector를 선택하라는 팝업이 하나 뜬다.

무심하게 취소를 눌렀더니, SVN connector가 설치가 안되었다 --;

이클립스를 재기동하고, subversive 플러그인을 삭제후 재설치해도 SVN connector가 설치되지 않는다.


그렇다면 

http://community.polarion.com/projects/subversive/download/eclipse/3.0/juno-site/ 

에서 직접 설치할 수 있다.

Posted by 1010
98..Etc/jQuery2014. 5. 21. 15:46
반응형

출처 : http://jhoonslife.tistory.com/524


jqGrid postData 처리시 주의 사항 !


jqGrid 에서 postData 처리를 위해서는 javascript 객체 형식을 써야 합니다.


좋은예와 안좋은예를 보여드리겠습니다.


안좋은예


$("#grid").jqGrid({

  url:'url.do'

, datatype: 'json'

  , mtype: 'POST'

  , page : 1

  , rowNum : 10

postData : "param1="+$("#param1").val() + "&param2="+$("#param2").val()

...



좋은예

$("#grid").jqGrid({

  url:'url.do'

, datatype: 'json'

  , mtype: 'POST'

  , page : 1

  , rowNum : 10

        , postData : { 

jobReqId:$("#jobReqId").val(), 

srcWkptId:$("#selSrcWkptId").val() 

}...



두가지의 차이점은 
postData 를 full text 로 입력 했느냐, 자바스크립트 객체로 입력 했느냐 입니다.

어떻게 보면 두가지 모두 비슷한 결과를 나타내는것 같지만
전달되는 요청관계를 자세히 살펴보면 전혀 다른 결과가 나타납니다.

안좋은예의 요청 파라미터
param1=param1&param2=param2

좋은예의 요청 파라미터

param1=param1&param2=param2&_search=false&nd=1353343119211&rows=10&page=1



두가지의 차이를 아시겠나요?
안좋은예는 정말 postData 안에 있는 항목만 파라미터로 담겨서 넘어갑니다. jqGrid 의 다른 속성 컬럼들이 파라미터에 담기질 않습니다.
(이유는 잘 모르겠습니다. 아는사람 설명 좀 부탁해요.)
그래서 당연히 페이징이랑 검색이 자연스럽게 넘어가지 않았던 거죠~!

그렇지만 자바스크립트 객체로 입력해 놓은 좋은예는 postData 뿐만아니라 jqGrid 의 다른 여러가지 프로퍼티들도 함께 넘어갑니다 ( 페이징처리 시에 필요한 rows 와 page 까지 함께..)

그렇기 때문에 첫번째 페이지가 나오는건 같은데 페이징 처리가 먹히지 않는 것은 postData 처리를 잘못 하였기 때문입니다.

postData 는 반드시 full TEXT 가 아닌 자바스크립트 객체 형식으로 넘기셔야 하고, 검색이나 페이징 시에도 마찬가지 입니다.

reload 의 나쁜예

$("#"+gridId).setGridParam({

page : pageNum,

rowNum : rowNum,

postData : "param1="+$("#param1").val()+"&param2="+$("#param2").val()

}).trigger("reloadGrid");



reload 의 좋은예

$("#"+gridId).setGridParam({

page : pageNum,

rowNum : rowNum,

postData : {

param1:$("#param1").val(),

param2:$("#param2").val()

}

}).trigger("reloadGrid");


-끝


Posted by 1010
반응형

http://braincast.nl/samples/jsoneditor/

Posted by 1010
카테고리 없음2014. 4. 25. 14:46
반응형
출처 : http://infobot.tistory.com/58

  • DokuWiki는 다양한 문서를 저장하고 체계적으로 관리할 수 있는 위키이다. 


  • 자체 히스토리 기능으로 이전 버전으로 복원이 가능하며, 플러그인을 추가해서
    도쿠위키의 기능을 확장, 강화할 수 있다. 


  • 도쿠위키를 복잡한 설치과정 없이 바로 사용할 수 있는 것이 DokuWiki Stick이다.




 다운로드




  • 다운로드받은 dokuwikistick-2009-12-25c 의 압축을 푼다. 


  • DokuWikiStick 폴더의 mapache.exe 를 실행한다. 


  • 인터넷 브라우저를 열고 주소창에 http://localhost:8800 를 입력한다. 


  • 도쿠위키 페이지가 보이고 관리자 계정으로 로그인 후 관리 작업 - 환경 설정 관리에서 설정을 수정할 수 있다.
    [관리자 계정]
    - 사용자: admin
    - 패스워드: admin



  • 도쿠위키 스틱 문서 저장 경로:
    DokuWikiStick\dokuwiki\data\pages




 다운로드 링크


Posted by 1010
56. Eclipse Etc.../Eclipse2014. 4. 23. 18:36
반응형

org.springframework.beans.factory.BeanCreationException: Error creating bean with name'exceptionTransfer'

 

조치방법 : pom.xml 의내용을전부컨트롤 + x 후저장. 이클립스빌드가끝나면다시컨트롤 + v 저장빌드가끝나면실행.

 

출처 : http://enspring.tistory.com/51

Posted by 1010