flex: редактируемый компонент метки - PullRequest
1 голос
/ 21 сентября 2011

Я пытаюсь создать редактируемую метку в flex4.

Для этого я расширяю класс текстового поля, поэтому он содержит элемент управления меткой.Но я не могу сделать метку видимой, когда текстовое поле становится невидимым.

Код выглядит следующим образом:

package unimap.components
{
import spark.components.Label;
import spark.components.TextInput;

public class SmartTextInput extends TextInput
{
    private var _label:Label;
    public function SmartTextInput()
    {
        super();
    }

    public override function set editable(value:Boolean):void
    {
        super.editable = value;

        if (value == false)
        {
            _label = new Label();
            _label.x = this.x;
            _label.y = this.y;
            _label.width = this.width;
            _label.height = this.height;
            _label.text = "Home";

            addChild( _label ); // This lines fail the code with error
                                                // Error: addChild() is not available in this class. Instead, use addElement() or modify //the skin, if you have one.

        }

        super.visible = false;
        trace("Editable")
    }
}

}

Но если бы я изменилaddChild to addElement Я вижу следующую ошибку: 1180: вызов возможно неопределенного метода addElement.

Может кто-нибудь посоветовать, что я делаю неправильно?

Ответы [ 3 ]

5 голосов
/ 21 сентября 2011

Вот решение, которое я использую в производственных системах:

package com.npacemo.component
{
    import flash.events.Event;
    import flash.events.FocusEvent;
    import flash.events.KeyboardEvent;
    import flash.events.MouseEvent;
    import flash.ui.Keyboard;

    import mx.core.UIComponent;

    import spark.components.Label;
    import spark.components.PopUpAnchor;
    import spark.components.TextInput;
    import spark.components.supportClasses.SkinnableComponent;

    [Event(name="change", type="flash.events.Event")]
    public class EditableLabel extends SkinnableComponent
    {
        [SkinState("normal")]
        [SkinState("selected")]
        [SkinPart(required="true")]
        public var labelComponent:Label;
        [SkinPart(required="true")]
        public var inputAnchor:PopUpAnchor;
        [SkinPart(required="true")]
        public var inputComponent:UIComponent;

        [Bindable]
        public var text:String; 

        public function EditableLabel()
        {
            addEventListener(MouseEvent.CLICK, handleDisplayLabelClick);
        }

        override protected function partAdded(partName:String, instance:Object):void
        {
            if (instance == labelComponent)
            {
                labelComponent.addEventListener(MouseEvent.CLICK, handleDisplayLabelClick);
            }
            else if (instance == inputComponent)
            {
                inputComponent.addEventListener(Event.CHANGE, handleInputComponentChange);
                inputComponent.addEventListener(KeyboardEvent.KEY_DOWN, handleTextInputKeyDown);
                inputComponent.addEventListener(FocusEvent.FOCUS_OUT, handleInputComponentFocusOut);
            }
        }

        private function handleInputComponentChange(e:Event):void
        {
            text = (inputComponent as TextInput).text;
            dispatchEvent(e.clone());
        }

        private function handleDisplayLabelClick(event:MouseEvent):void
        {
            skin.currentState = "selected";
            stage.addEventListener(MouseEvent.CLICK, handleStageClick);
        }

        private function handleStageClick(e:MouseEvent):void
        {
            if (!inputComponent.hitTestPoint(stage.mouseX, stage.mouseY))
            {
                stage.removeEventListener(MouseEvent.CLICK, handleStageClick);
                skin.currentState = "normal";
            }
        }

        private function handleTextInputKeyDown(event:KeyboardEvent):void
        {
            if (event.charCode == Keyboard.ENTER)
            {
                stage.removeEventListener(MouseEvent.CLICK, handleStageClick);
                skin.currentState = "normal";   
            }
        }

        private function handleInputComponentFocusOut(event:FocusEvent):void
        {
            stage.removeEventListener(MouseEvent.CLICK, handleStageClick);
            skin.currentState = "normal";
        }
    }
}

И это примерный скин:

<?xml version="1.0" encoding="utf-8"?>
<s:Skin xmlns:fx="http://ns.adobe.com/mxml/2009" 
        xmlns:s="library://ns.adobe.com/flex/spark" 
        xmlns:mx="library://ns.adobe.com/flex/mx">
    <!-- host component -->
    <fx:Metadata>
        [HostComponent("com.npacemo.component.EditableLabel")]
    </fx:Metadata>

    <!-- SkinParts
    name=inputComponent, type=mx.core.UIComponent, required=true
    name=labelComponent, type=spark.components.Label, required=true
    -->
    <s:states>
        <s:State name="normal"/>
        <s:State name="selected" enterState="inputComponent.setFocus(); inputComponent.selectRange(inputComponent.text.length, inputComponent.text.length);"/> 
    </s:states>

    <s:transitions>
        <s:Transition fromState="*" toState="*" autoReverse="true">
            <s:Fade targets="{[labelComponent, inputComponent]}" duration="100"/>
        </s:Transition>
    </s:transitions>

    <s:PopUpAnchor id="inputAnchor" x="-1" y="-7" displayPopUp.normal="false" displayPopUp.selected="true">
        <s:TextInput id="inputComponent" text="{hostComponent.text}" 
                     alpha.normal="0" alpha.selected="1" 
                     enabled.normal="false" enabled.selected="true"
                     width="{labelComponent.width + 20}" focusSkin="{null}" 
                     contentBackgroundColor="0xFBFCA4" borderVisible="false"
                     fontFamily="Futura" fontSize="12" textAlign="left">
            <s:filters>
                <s:DropShadowFilter angle="135" alpha="0.5" blurX="10" blurY="10"/>
            </s:filters>
        </s:TextInput>
    </s:PopUpAnchor>

    <s:Label id="labelComponent" text="{hostComponent.text}"
             alpha.normal="1" alpha.selected="0" 
             visible.normal="true" visible.selected="false"
             verticalCenter="0" width="{this.width+20}" maxDisplayedLines="1"
             textDecoration="underline" buttonMode="true"/>
</s:Skin>
0 голосов
/ 23 сентября 2011

По сути, TextInput не является контейнером, это компонент управления текстом, поэтому вы не можете добавить к нему ни дочерние элементы, ни элементы (с помощью методов addElement или addChild).

Вы можете создать обложку для вашего TextInput, которая делаетваш TextInput "ведет себя" как метка.

Скажите нам, что вы хотите сделать со своей "редактируемой меткой", чтобы мы могли дать вам лучший ответ.

0 голосов
/ 21 сентября 2011

Здесь есть несколько вопросов.Во-первых, если я несколько раз позвоню enable = false, у меня будет несколько дочерних меток.Не то, что вы собираетесь.Вы можете создать составной элемент управления на основе группового элемента управления и создать собственный скин, но это может быть излишним.Я бы порекомендовал просто создать скин TextInput и изменить внешний вид, чтобы он выглядел как метка, когда он не включен (например, visible.disabled = false на фонах и границах и alpha.disabled = 1.0 на основном элементе скина). Преимущество этого состоит в том, чтоВы можете применить его через CSS и использовать элемент управления по умолчанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...