Translate

Mostrando entradas con la etiqueta flex 4. Mostrar todas las entradas
Mostrando entradas con la etiqueta flex 4. Mostrar todas las entradas

lunes, 22 de abril de 2013

Flex: TextInput prompt no aparece en Popup

El problema con el que he encontrado esta semana es que si tengo un Popup, ya sea utilizando el componente de Flex 4 PopUpAnchor o el propio del Framework Parsley ParleyPopup,  si dentro de él ponemos un textInput el prompt no aparece.




--




<fx:Declarations>

<!-- Place non-visual elements (e.g., services, value objects) here -->

<parsley:Configure/>

 <parsley1:ParsleyPopup open="{model.popupVisible}" modal="true" reuse="false">

  <popups:PopUpBase width="{stage.width}" height="{stage.height}" showEffect="Fade"    hideEffect="Fade" removedEffect="Fade"/>

 </parsley1:ParsleyPopup>

</fx:Declarations>



--

Para solucionarlo tenemos que crear un group que englobe a todo lo que está dentro del pop que implemente la interfaz IFocusManagerContainer, ya que es el Focus Manager lo que está provocando este mal comportamiento.


--
public class PopUpGroup extends Group implements IFocusManagerContainer
  
 {
  
  public function PopUpGroup()
   
  {
   
   super();
   
  }
  
  
  
  public function get defaultButton():IFlexDisplayObject
   
  {
   
   return null;
   
  }
  
  
  
  public function set defaultButton(value:IFlexDisplayObject):void
   
  {
   
  }
  
 }



--


<parsley1:ParsleyPopup open="{model.popupVisible}" modal="true" reuse="false">
 <group:PopUpGroup>       
  <popups:PopUpBase width="{stage.width}" height="{stage.height}" showEffect="Fade" hideEffect="Fade" removedEffect="Fade"/>
 </group:PopUpGroup>
</parsley1:ParsleyPopup>


--



Referencia:

TextInput in a pop up doesn't display its promptDisplay ? Bug or a FocusManager issue ?

lunes, 11 de marzo de 2013

mxmlc Use Flash Text Engine in MX components

En ciertos casos es posible que tengamos ciertos componentes en Flex que no son Sparks y sea necesario skinearlos.

Por ejemplo los tooltips no son skineables, pero se les puede dar estilo gracias al uso de CSS al ser un componente MX.

tooltip

Para que ese estilo de tu CSS funcione con los componentes MX hay que habilitar la siguiente opción del Flex Compiler: Use Flash Text Engine in MX components



El problema es que para hacer la compilación a través del compilador MXMLC esa opción aunque aparece en las opciones de compilación de flex 4  (opción defaults-css-files) parece que al compilar no funciona.

La alternativa para conseguir el mismo efecto en nuestra aplicación es utilizar coger la hoja de estilo que tiene por defecto el flash builder (MXFTEText.css) situada en

[FLEX_4.6_SDK_PATH]\frameworks\projects\spark

Se importa en el mxml principal de nuestro proyecto en combinación con nuestra CSS ya creada y el efecto es el mismo que habilitar la opción.

MainApp.mxml

<fx:Style source="assets/css/MXFTEText.css"/>

<fx:Style source="assets/css/common.css"/>



Common.css
@namespace s "library://ns.adobe.com/flex/spark";

@namespace mx "library://ns.adobe.com/flex/mx";



mx|ToolTip

{

 backgroundColor: #3085B7;

 color: white;

 fontAntiAliasType: advanced;

 fontFamily: "DINPRegular";

 fontSize: 12;

 cornerRadius: 0; 

}


Referencia:

How to use the -fteInMXComponents compiler option with flexmojos











viernes, 8 de marzo de 2013

mxmlc error: Unable to resolve resource package

En español:  [mxmlc] Error: No se puede resolver el paquete de recursos "X".

Este error se produce cuando estamos realizando la compilación de un proyecto a través del comando mxmlc ya se por línea de comandos o a través de ANT, y el compilador no puede compilar uno de nuestros archivos de properties de i18n (intenacionalización).

Para solucionarlo tenemos que añadir la siguiente línea tantas veces sea necesario como idiomas estemos utilizando.


<mxmlc ....
.....
<compiler.source-path path-element='${APP_ROOT}/locale/es_ES'/>

<mxmlc/>

donde ${APP_ROOT} es la ruta donde está nuestro proyecto.


miércoles, 6 de marzo de 2013

Compilación Flex mxmlc con RSL: El orden de compilación de las RSL importa mucho

Cuando compilas tu aplicación Flex y lo haces con RSL externas para que el SWF generado pese lo menos posible (Opciones de compilación MXMLC static-rsls="false") y el orden de las RSL no es el correcto se produce el siguiente error:







VerifyError: Error #1014: flashx.textLayout.container::TextContainerManager is not found

Este error se produce al acceder con tu navegador a la aplicación, el SWF se descarga pero el error que hemos visto.

Esto se produce porque el orden que estableces en las librerías RSL en la compilación de tu SWF es el orden en que estas se descargarán del servidor.

Por lo tantos si ponemos el orden incorrecto de  las librerías al compilar, al descargar y ejecutarse el swf  de la aplicación se descargarán las librerías .swz en el orden incorrecto y el error de que una librería no se encuentra aparecerá.

El orden correcto lo podemos encontrar en nuestra FLEX SDK (en mi caso 4.6) en el archivo flex-config.xml que está en la ruta:

[FLEX_SDK_4.6_PATH]/frameworks/flex-config.xml

A continuación os pongo el comando de apache ANT que utilizo para compilar para que veáis el orden en que hay que poner las librerías .swz para que luego se descarguen correctamente. Se ve en el apartado de las

<runtime-shared-library....

Variables de ANT:

${APP_ROOT} Es la ruta física de la aplicación.
${DirectorioXmlReport} Directorio donde se crea el XML con la dependencias del proyecto.
${FLEX_HOME} Es la ruta donde está instalado el framework de flex ([FLEX_SDK_4.6_PATH])



--
<mxmlc  file="${APP_ROOT}/MyApp.mxml" keep-generated-actionscript="false" 
     output="${APP_ROOT}/${SwfDestination}/${modulo}.swf"
  actionscript-file-encoding="UTF-8"     
  services="${APP_ROOT}/WEB-INF/flex/services-config.xml"
  context-root="MyApp"    
  link-report="${DirectorioXmlReport}/report.xml"
  static-rsls="false"
        incremental="false" warnings="false" fork="true" maxmemory="512m">
  
 <!-- Compilación para la versión de Flash Player -->
 
 <target-player>11.1.0</target-player>
 
 <!-- Get default compiler options. -->
 <load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>

 <!-- List of path elements that form the roots of ActionScript
        class hierarchies. -->
        <source-path path-element="${FLEX_HOME}/frameworks"/>
     
 <!-- List of SWC files or directories that contain SWC files. -->
        <compiler.library-path dir="${APP_ROOT}" append="true">
            <include name="libs" />
      </compiler.library-path>  

<!-- Parámetro para modificar el color de fondo al cargar el preloader de la aplicación-->
 <default-background-color>0x252e39</default-background-color>
 
<!-- Parametro adicional al flex compiler para incluir los .properties-->            
 <include-resource-bundles>resources</include-resource-bundles> 

<!-- Asociación de los RSLs para optimización para separar el Framework de flex de nuestros módulos.-->
     
      
<runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/framework.swc">
   <url rsl-url="framework_4.6.0.23201.swz"/>
   <url policy-file-url=""/>
   <url rsl-url="framework_4.6.0.23201.swf"/>
   <url policy-file-url=""/>
  </runtime-shared-library-path>

<runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/textLayout.swc">
   <url rsl-url="textLayout_2.0.0.232.swz"/>
   <url policy-file-url=""/>
   <url rsl-url="textLayout_2.0.0.232.swf"/>
   <url policy-file-url=""/>
  </runtime-shared-library-path>   
 
<runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/spark.swc">
   <url rsl-url="spark_4.6.0.23201.swz"/>
   <url policy-file-url=""/>
   <url rsl-url="spark_4.6.0.23201.swf"/>
   <url policy-file-url=""/>
  </runtime-shared-library-path>    
 
<runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/sparkskins.swc">
   <url rsl-url="sparkskins_4.6.0.23201.swz"/>
   <url policy-file-url=""/>
   <url rsl-url="sparkskins_4.6.0.23201.swf"/>
   <url policy-file-url=""/>
  </runtime-shared-library-path>    
 
<runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/rpc.swc">
   <url rsl-url="rpc_4.6.0.23201.swz"/>
   <url policy-file-url=""/>
   <url rsl-url="rpc_4.6.0.23201.swf"/>
   <url policy-file-url=""/>
  </runtime-shared-library-path>    

<runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/charts.swc">
   <url rsl-url="charts_4.6.0.23201.swz"/>
   <url policy-file-url=""/>
   <url rsl-url="charts_4.6.0.23201.swf"/>
   <url policy-file-url=""/>
  </runtime-shared-library-path>   

<runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/spark_dmv.swc">
   <url rsl-url="spark_dmv_4.6.0.23201.swz"/>
   <url policy-file-url=""/>
   <url rsl-url="spark_dmv_4.6.0.23201.swf"/>
   <url policy-file-url=""/>
  </runtime-shared-library-path>    
 
<runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/mx/mx.swc">
   <url rsl-url="mx_4.6.0.23201.swz"/>
   <url policy-file-url=""/>
   <url rsl-url="charts_4.6.0.23201.swf"/>
   <url policy-file-url=""/>
  </runtime-shared-library-path>
  
 
<runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/advancedgrids.swc">
   <url rsl-url="advancedgrids_4.6.0.23201.swz"/>
   <url policy-file-url=""/>
   <url rsl-url="advancedgrids_4.6.0.23201.swf"/>
   <url policy-file-url=""/>
  </runtime-shared-library-path>

 
  
  <!--Metadatos adicionales a incluir en el proyecto-->
   
 
   <!-- Metadatos dependientes de Parsley-->
   <keep-as3-metadata name="Metadata" />
   <keep-as3-metadata name="DefaultProperty" />
   <keep-as3-metadata name="Required" />
   <keep-as3-metadata name="Event" />
   <keep-as3-metadata name="AssignableTo" />
   <keep-as3-metadata name="Inject" />
   <keep-as3-metadata name="InjectConstructor" />
   <keep-as3-metadata name="Publish" />
   <keep-as3-metadata name="Subscribe" />
   <keep-as3-metadata name="PublishSubscribe" />
   <keep-as3-metadata name="Factory" />
   <keep-as3-metadata name="Init" />
   <keep-as3-metadata name="Destroy" />
   <keep-as3-metadata name="Observe" />
   <keep-as3-metadata name="AsyncInit" />
   <keep-as3-metadata name="ManagedEvents" />
   <keep-as3-metadata name="MessageDispatcher" />
   <keep-as3-metadata name="MessageHandler" />
   <keep-as3-metadata name="MessageBinding" />
   <keep-as3-metadata name="MessageInterceptor" />
   <keep-as3-metadata name="MessageError" />
   <keep-as3-metadata name="Command" />
   <keep-as3-metadata name="CommandComplete" />
   <keep-as3-metadata name="CommandResult" />
   <keep-as3-metadata name="CommandError" />
   <keep-as3-metadata name="CommandStatus" />
   <keep-as3-metadata name="ResourceBinding" />
   <keep-as3-metadata name="Selector" />
   <keep-as3-metadata name="Target" />
   <keep-as3-metadata name="Autoremove" />
   <keep-as3-metadata name="Internal" />
   <keep-as3-metadata name="ObjectDefinition" />
   <keep-as3-metadata name="DynamicObject" />

  
  <!--Localización -->
 
   <locale>es_ES</locale>
   <!--Necesario para las RSLs del framework flex-->
   <locale>en_US</locale>


  <!-- Necesario para el source path del Flex Build Paht-->
  <compiler.source-path path-element='${APP_ROOT}'/>
  <compiler.source-path path-element='${APP_ROOT}/locale/es_ES'/>
 
  <!-- Optimización-->
  <use-network>true</use-network>
     <debug>false</debug>
     <optimize>true</optimize>
  
</mxmlc>  


--





viernes, 2 de noviembre de 2012

Subida de archivos con Flash en MacOS : TypeError: Error #1009

TypeError: Error #1009: Cannot access a property or method of a null object reference Uploading file.

Este error se produce cuando intentamos subir un archivo con el sistema operativo Mac a través del Flash Player (actualmente la versión 11.4).

El problema consiste en que en el objeto FileReference que se encarga de identificar el archivo que subimos, si accedemos a la propiedad "type" esta llega con valor null y si la utilizamos nos dará el error antes tipificado. TypeError: Error #1009

var fileReference:FileReference

fileReference.type //NULL



Para solucionarlo lo mejor es recuperar la extensión del archivo del nombre del fichero del FileReference, con las propiedad "name".


var fileReference:FileReference

fileReference.name //file.txt



viernes, 19 de octubre de 2012

Flex Spark: z-index en flex

El problema en que me visto esta semana es que teniendo una pantalla que ya estaba creada he tenido que poder una capa encima de otra ya existente bajo determinadas condiciones.

En la pantalla aparece una lista con distintos objetos cargadas y al pulsar un botón debía de aparecer otra lista encima de la ya existente.

Si la pantalla no estuviera ya hecha lo mejor sería utilizar un estado pero creo que para este caso lo mejor es crear la segunda lista y ponerla por encima de la ya existente, haciéndola visible o invisible según me convenga.

Para esto puedo usar la propiedad depth que tiene todo Spark container, la profundida por defecto es 0 y si queremos que algún container de nuestro mxml este por encima de otro debemos de pone está propiedad depth con valores mayores a 0.

--
<s:group depth="1" height="570" top="{50" width="100%">
....
....
</s:group>

--

referencias:

documentación de adobe

viernes, 24 de agosto de 2012

Flex: Recuperar el índice de un itemrenderer

Title: get de item index in a flex itemrenderer

Recuperar el índice de la posición que ocupa el itemrenderer que se está mostrando en pantalla es un cosa que no te preguntas hasta que realmente no te hace falta utlizarlo, aunque es de lo más básico

En internet hay varias opciones para hacerlo pero si ya estamos utlizando de Flex4 con la implementación Spak del itemrenderer es tan fácil como utilizar la propiedad  itemIndex

--
<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer............

<s:Group x="74" y="12">
  <s:Rect x="0.5" y="0.5" width="20" height="20">
   <s:stroke>
    <s:SolidColorStroke caps="none" color="#3085B7" joints="miter" miterLimit="10"/>
   </s:stroke>
  </s:Rect>
 <s:RichText id="numQuestion" x="8" y="6" color="#3085B7" columnCount="1"
 fontFamily="Myriad-Bold" fontSize="12.1205" kerning="on" lineHeight="76.1519"
 tabStops="S36" text="{itemIndex+1}" whiteSpaceCollapse="preserve"/>
</s:Group>


<s:RichText d:id="4" x="110"
y="17" ai:aa="2" color="#414042" columnCount="1" fontFamily="DINPro-Regular"
fontSize="14.1406" kerning="on" lineHeight="76.1519" tabStops="S199.772155761719"
text="{data.question}" 
whiteSpaceCollapse="preserve"/>

..............
</s:ItemRenderer>
--



Acordaros de poner el +1 para que la cuenta no empiece en 0.

Referencias:

http://www.jeffryhouser.com/index.cfm/2008/11/4/How-do-you-find-an-items-dataProvider-index-from-inside-an-itemRenderer

http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/spark/components/supportClasses/ItemRenderer.html#itemIndex

martes, 24 de julio de 2012

StringTokenizer en Flex

Buscando buscando encontré un código firmado por Alex Ciobanu y que lo tiene en una librería con otras funcionalidades para obtener la misma funcionalidad de Stringtokenizer de Java.

Toda esta funcionalidad está en la librería fxmaker

Como sólo me interesaba la parte del manejo de la cadena miré el código fuente y lo utilicé.

Por si os es útil os dejo la referencia a la librería y al código fuente del StringTokenizer.

Y también os pego el código aquí por si acaso en algún momento desaparece, ya que me parece bastante útil.

--

/**
         *
         * @author Alexutz
         *
         */    
        public class StringTokenizer
        {
                private var tokens : Array;
               
                private var currentToken : int = -1;
                /**
                 *
                 *
                 */            
                public function StringTokenizer(delimiter : String = null, value: String = null){
                        tokenize(value, delimiter);
                }
                /**
                 *
                 * @return
                 *
                 */            
                public function hasMoreTokens() : Boolean{
                        return tokens && currentToken < tokens.length - 1;
                }
                /**
                 *
                 * @return
                 *
                 */            
                public function getToken() : String{
                        if(currentToken >= tokens.length - 1){
                                throw new Error("");
                        }
                        currentToken++;
                        var token : String = tokens[currentToken] as String;
                        return token;
                }
                /**
                 *
                 * @param value
                 * @param delimiter
                 *
                 */            
                public function tokenize(value : String, delimiter : String) : void{
                        if(value == null || delimiter == null){
                                return;
                        }
                        tokens = value.split(delimiter);
                        currentToken = -1;
                }
        }

miércoles, 27 de junio de 2012

Flex - itemCreationPolicy: La política de creación de un objeto es útil

Pre-requisitos: Conocimientos básicos de Flex.

Esta particularidad de Flex es bastante útil desde mi punto de vista por dos puntos principalmente.

  • Para ahorrar memoria.
  • Para mejorar el comportamiento al a vista del usuario.
Todo objecto que se añade en flex tiene una  itemCreationPolicy que puede ser de dos tipos

  • Deferred: Que hace que el objeto se cree cuando es instaciado. Valor por defecto
  • Inmediate: Que hace que el objeto se cree al inciar la aplicación.

El  comportamiento deferred es el que está puesto por defecto ya que si fuera al contrario y todos los componentes cargaran en nuestra aplicación esta podría consumir mucha memoria y perder rendimiento.

Los que tienen el valor deferred se crean cuando el objeto es instanciado es decir cuando aparece en pantalla y el objeto tes visible.

Pero en ciertos casos necesitamos que este objeto aunque no se vea en pantalla necesitamos que se cree para que por ejemplo se carguen en él unos datos recuperados de base de datos o que al cargase se ejecute algún evento que necesitemos que ocurra.

En estos casos lo mejor es poner el campo  itemCreationPolicy="immediate" para que aunque no sea visible se comporte como si lo fuera y se cree al cargase la pantalla.

Todos los componentes de flex tienen esta propiedad itemCreationPolicy y puede aplicase cuando se crea necesario:


 <s:Button id="newButtonImmediate" 
            includeIn="Immediate" 
            itemCreationPolicy="immediate"/>



Referencias:

http://help.adobe.com/en_US/flex/using/WS2db454920e96a9e51e63e3d11c0bf63611-7ffa.html

jueves, 17 de mayo de 2012

Flex 4: Acceder al contenedor padre de un Itemrenderer

Calling parent container from ItemRendere.

Pre-requisitos: Conocimientos básicos de Flex 4 (funcionamiento de un Itemrenderer) y Action Script 3.

Una de las mejores características de flex es que te permite crear listas de objetos, con la particularidad de que podemos crear diseños e interfaces muy visuales de estos objetos gracias a los Itemrederers. Por ejemplo, una lista botones donde cada botón tiene un diseño similar con funcionalidad similar.

Pero puede que tengamos la necesidad de acceder, no sólo a la lista que contiene al itemrenderer sino también a la vista que contiene a esta lista para acceder a alguno de sus objetos declarados o funciones.

La parte negativa de esto es que el Itemrenderer que lo utilice quedará totalmente acoplado a la vista padre a la que hacemos referencia y no podrá ser un elemento independiente y reutilizable por otras listas.

El propio itemrenderer ya nos trae distintas propiedades rellenas con la información de los datos con lo que hemos rellenado la lista.


data: Contiene la información del elemento de la lista al que representa el itemrenderer.
parentDocument: hace referencia a algún objetos padre que contiene al itemrederer.

También se puede sobre-escribir funciones  como set data() que se ejecutará para de asignar el valor de uno de los elementos de la lista al itemrenderer.

Para acceder a la vista padre lo que debemos utilizar es parentDocument.parentDocument que nos devolverá un objeto del tipo de contiene a lista.


El ejemplo que os pongo a continuación es una mxml principal(MainApp.mxml) con una lista y el itemrender utilizado (ServiceIR.mxml). Se supone que ambos están en el mismo paquete de la aplicación.


MainApp.mxml

<s:Application
................

<s:Group width="100%">
                              <s:HGroup left="40" top="40">

                                        <s:List width="100%" dataProvider="{items}"
                                                            itemRenderer="ServicesIR"
                                                            contentBackgroundColor="#E6E7E8" borderVisible="false">

                                                  <s:layout>
                                                            <s:HorizontalLayout columnWidth="50" gap="5"/>
                                                  </s:layout>
                                        </s:List>

.....

</Application>


El objeto items del data provider podría ser un arrayCollections de Strings por ejemplo.

ServicesIR.mxml


<?xml version="1.0" encoding="utf-8"?>
<s:ItemRenderer xmlns:fx="http://ns.adobe.com/mxml/2009"
                                        xmlns:s="library://ns.adobe.com/flex/spark"
                                        xmlns:mx="library://ns.adobe.com/flex/mx"
                                        autoDrawBackground="true">
...

<fx:Script>
                    <![CDATA[

              override public function set data(value:Object):void
              {
              var parent:MainApp =  parentDocument.parentDocument; //Instance of MainApp.mxml
                    ............................
              }

]]>
</fx:Script>


     ..............
  }

<s:ToggleButton id="tab"  label="{data}" horizontalCenter="0" verticalCenter="0"/>


</s:ItemRenderer>


Utilizo la función set data para asignar para recuperar al objeto padre y acceder a lo que necesite para modificar los datos como sea necesario.