Март 25th, 2008 от graann

Константин Ковалев предложил более простой и изящный вариант решения проблемы затронутой мною в предыдущем посте.

Суть решения заключается в использовании метатега RemoteClass в классе сохраняемого объекта. Т.е registerClassAlias не требуется. Код ниже:

XML:

<mx:Application
  creationComplete="onCreationComplete()"
  xmlns:mx="http://www.adobe.com/2006/mxml"
  layout="vertical">
  <mx:Script>
    <![CDATA[
      import com.riapriority.tests.DataObject;
      
      private var so:SharedObject;
      private var dataObject:DataObject;
  
  
      private function onCreationComplete(): void
      {
        dataObject = new DataObject();
        so = SharedObject.getLocal ("test");
      }
  
  
      private function dataObjectGeneration (): void
      {
        dataObject.generate();
        ta.text += 'GENERATING: ' + dataObject.toString() + '\n';
      }
  
      private function saveLocalData(): void
      {
        so.data.DataObject = dataObject;
        so.flush();
        ta.text += 'SAVE: ' + dataObject.toString() + '\n';
      }
  
      private function loadLocalData(): void
      {
        so = SharedObject.getLocal('test');
        if(so.data.DataObject != null)
        {
          dataObject = so.data.DataObject as DataObject;
          ta.text += 'LOAD: ' + dataObject.toString() + '\n';
        }
        else
        {
          ta.text += 'LOAD: null\n';
        }
      }
    ]]>
  </mx:Script>
  
  <mx:Button
    label="Generate"
    click="{dataObjectGeneration()}"/>
  <mx:Button
    label="Save"
    click="{saveLocalData()}"/>
  <mx:Button
    label="Load"
    click="{loadLocalData()}"/>
  <mx:TextArea
    width="50%"
    height="50%"
    id="ta"/>
</mx:Application>

и код класса

  1. package com.riapriority.tests
  2. {
  3.         import mx.formatters.DateFormatter;
  4.        
  5.         [Bindable]
  6.         [RemoteClass(alias="com.riapriority.tests.DataObject")]
  7.         public class DataObject
  8.         {
  9.                 public var date: Date;
  10.                 public var random: String;
  11.  
  12.                 public function generate(): void
  13.                 {
  14.                         date = new Date();
  15.                         random = "" + Math.random() * 10000;
  16.                 }
  17.  
  18.                 public function toString():String
  19.                 {
  20.                         var df:DateFormatter = new DateFormatter ();
  21.                         df.formatString = "JJ:NN:SS DD/MM/YYYY";
  22.                         return "\n  date: " + df.format(date) + "\n  random: " + random;
  23.                 }
  24.         }
  25. }

[Bindable] здесь не обязателен, но как тонко выразился Константин,
класс без [Bindable], что штопор без бутылки :)

Upd: Работает только с публичными свойствами (касается так же вложенных объектов). Вложенные объекты так же должны быть снабжены метатегом RemoteClass.

Март 24th, 2008 от graann

Продолжу тему затронутую Александром Гаховым в статье Клонирование объектов утилитой ObjectUtil.copy.

Здесь я приведу пример использования registerClassAlias для восстановления объектов определенного класса из SharedObject. Суть проблемы заключалась в том, что помещенные в SharedObject экземпляры определенного класса при перезапуске возвращались, как экземпляры класса Object. Когда я столкнулась с этой проблемой, доступного для понимания примера мне нагуглить не удалось. Перед размещением же поста, я нашла вопрос по этой теме в ruFlex, однако приведенный там пример показался мне не вполне наглядным. Предлагаю вашему вниманию свой пример решения этой проблемы:

XML:

<mx:Application creationComplete="onCreationComplete()" xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
  import src.DataObject;
  import flash.net.*;
  
  private var so: SharedObject;
  private var dataObject: DataObject;
 
  
  private function onCreationComplete(): void
  {
    dataObject=new DataObject();
    registerClassAlias('src.DataObject', DataObject);    
    so = SharedObject.getLocal("test");
  }
  
  
  private function dataObjectGeneration(): void
  {
    dataObject.generate();
    ta.htmlText+='GENERATION: '+dataObject.toString()+'\n';
  }
  
  private function saveLocalData(): void
  {
    so.data.DataObject=dataObject;
    so.flush();
    ta.htmlText+='SAVE: '+dataObject.toString()+'\n';
  }
  
  
  
  private function loadLocalData(): void
  {
    so = SharedObject.getLocal('test');
    if(so.data.DataObject!=null)
    {
      dataObject=so.data.DataObject as DataObject;
      ta.htmlText+='LOAD: '+dataObject.toString()+'\n';
    } else {
      ta.htmlText+='LOAD: null\n';
    }
  }
  
]]>
</mx:Script>
<mx:Button x="193" y="27" label="save" id="save_" click="{saveLocalData()}"/>
<mx:Button x="107" y="27" label="generate" id="generate" click="{dataObjectGeneration()}"/>
<mx:Button x="49" y="27" label="load" id="load_" click="{loadLocalData()}"/>
<mx:TextArea x="49" y="57" height="141" width="618" id="ta"/>
</mx:Application>

Собственно сам класс нашего объекта.

  1. ackage src
  2. {
  3.         import mx.formatters.DateFormatter;
  4.        
  5.         public class DataObject
  6.         {
  7.                 public var date: Date;
  8.                 public var random: String;
  9.                
  10.                 public function DataObject()
  11.                 {
  12.                        
  13.                 }
  14.                
  15.                 public function generate(): void
  16.                 {
  17.                         date=new Date();
  18.                         random=""+Math.random()*10000;
  19.                 }
  20.                
  21.                 public function toString():String
  22.                 {
  23.                         var df: DateFormatter=new DateFormatter();
  24.                         df.formatString="JJ:NN:SS DD/MM/YYYY";
  25.                         return "\n  date: "+df.format(date)+"\n  random: "+random;
  26.                 }
  27.         }
  28. }

Прошу прощения за подобное отображение mxml-ины. Если пример вас заинтересует скопируйте его. :)

Январь 31st, 2008 от graann

Путь скинизации посредством css тернист и многотруден. Особенно если каждый стиль требуют собственных скинов для виджетов (иконок, кнопок и т.д). Предположим нам надо подгрузить картинку. Для примера создадим класс наследованный от UIComponent и требующий подгрузки картинки описанной в css. Назовем класс Example.as.

Стили для него описаны в одноименном блоке стиля. (вы разумеется знаете, что стили цепляются к одноименной компоненте автоматом и не требуют каких-то дополнительных директив?)

Казалось бы чего проще?…

XML:

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" xmlns:ns1="src.*">
    <!−− так конечно делать не надо, но для примера покатит :) с css будет так же!−−>
    <mx:Style>
        Example{image: Embed("graphics/image.png");}
    </mx:Style>
    <ns1:Example x="42" y="24"/>
</ns1:Example></mx:Application>
  1. package src
  2. {
  3.        import mx.core.UIComponent;
  4.        import mx.controls.Image;
  5.  
  6.        public class Example extends UIComponent
  7.        {
  8.                private var image: Image;
  9.                
  10.                public function Example()
  11.                {
  12.  
  13.                }
  14.                
  15.                override protected function createChildren(): void
  16.                {
  17.                        super.createChildren();
  18.                        image=new Image();
  19.                        image.source=getStyle("image");
  20.                        addChild(image);
  21.                }
  22.                
  23.        }
  24. }

И после компиляции картинку благополучно не видим. Почему? Потому, что по умолчанию ее размеры составляют 0 x 0. Для того чтобы она отобразилась корректно требуется задать ей реальные размеры, каковые нам любезно предоставляют свойства measuredWidth и measuredHeight. Однако актуальные значения ширины и высоты будут доступны только после вызова метода protected function measure(): void UIComponent, о котором доступна подробная информация в хелпе.

Ну и собственно результат:

  1. package src
  2. {
  3. import mx.core.UIComponent;
  4. import mx.controls.Image;
  5.  
  6. public class Example extends UIComponent
  7. {
  8.         private var image: Image;
  9.        
  10.         public function Example()
  11.         {
  12.         }
  13.                
  14.         override protected function createChildren(): void
  15.         {
  16.                 super.createChildren();
  17.                 image=new Image();
  18.                 image.source=getStyle("image");
  19.                 addChild(image);
  20.         }
  21.  
  22.         override protected function measure():void
  23.         {
  24.                 super.measure();
  25.                 image.setActualSize(image.measuredWidth, image.measuredHeight);
  26.         }
  27.        
  28. }

Следует отметить, что подобных проблем с размерами не возникает в mxml-e.

Сентябрь 6th, 2007 от graann

Сегодня у Константина Палыча день рождения!

Поздравляю!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Счастье у тебя уже есть, поэтому дальнейших творческих узбеков тебе, Костик, и чтобы твое здоровье тебе ни в чем не отказывало! :)

Август 16th, 2007 от graann

Счастья, здоровья, хорошего аппетита, трудовых свершений, а главное, крепких нервов в совместной работе с твоей горячо любимой мной :)

Июнь 5th, 2007 от graann

При большом количестве меток (да и вообще компонент) и частой их отрисовке вы непременно столкнетесь с тормозами. В случае с метками есть альтернатива в лице mx.core.UITextField, которой и посвящен этот пост. Что нас привлекает в mx.controls.Label? Возможность отобразить некий текст и применить к нему стили. UITextField нам эти возможности предоставляет так же. Однако есть одна тонкость. Как работать со стилями если:

public function setStyle(styleProp:String, value:*):void - Does nothing. A UITextField cannot have inline styles.

Не очень понятно зачем вообще нужен этот метод если он ничего не делает. Была мысль, что он описан в каком-то из имплементящихся интерфейсов, но подтверждения этому в коде найти не удалось. Впрочем я отвлеклась. Ну так как же работать со стилями? Да в общем точно так же, только через свойство styleName.

styleName:Object [read-write] - The class style used by this component. This can be a String, CSSStyleDeclaration or an IStyleClient.
Т.е uiTextField.styleName.setStyle("color", 0xff0000); сработает, но только если к UITextField уже был применен какой-то стиль. Не поленилась написать небольшой пример:

XML:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.core.UITextField;
import mx.styles.*;
 
private var uiTextField: UITextField;
 
override protected function createChildren(): void
{
  super.createChildren();
  uiTextField=new UITextField();
  addChild(uiTextField);
  uiTextField.text="mx.core.UITextField";
  trace("uiTextField.styleName: "+uiTextField.styleName);
// uiTextField.styleName: null
  var styleCss:CSSStyleDeclaration = new CSSStyleDeclaration();
  styleCss.setStyle('fontSize', 15);
  styleCss.setStyle('color', picker.selectedColor);
  uiTextField.styleName=styleCss;
}
 
public function changeColor(): void
{
  uiTextField.styleName.setStyle("color", picker.selectedColor);
}
 
]]>
</mx:Script>
<mx:ColorPicker id="picker" change="changeColor()" />
</mx:Application>
Февраль 12th, 2007 от graann Февраль 7th, 2007 от graann

При работе с чартингом, одной из осей которого является DateTimeAxis, часто возникает потребность в изменении формата отображения меток. Как я поняла в ходе общения с кодом DateTimeAxis, сам флекс не меняет формат даты в зависимости от локали. По умолчания дата отображается в формате m/d/yy. Для российского глаза такое отображение несколько непривычно. Хелп предоставляет два пути решения этой проблемы.
1. labelFunction:Function [read-write]
Called to format axis values for display as labels. A labelFunction has the following signature:

  1. function labelFunction(labelValue:Object, previousValue:Object, axis:IAxis):String


If you know the types of the data your function will be formatting, you can specify an explicit type for the labelValue and previousValue parameters.

Казалось бы вот оно счастье, однако поспешность в выборе может послужить для вас причиной дополнительного геморроя. Качественная замена функции дело довольно муторное. Ведь интервал между метками может составлять как секунды так и годы. Куча кода. Рекомендую с негодованием отвергнуть эту веселую перспективу и обратить свой взор к пункту 2.

2. В хелпе есть такое понятие как Protected Methods. Для человека пришедшего из AS2 и не озаботившегося ознакомлением с матчастью AS3 такое буквосочетание может показаться слабо информативным, однако белые люди сжевавшие в процессе общения с флексом уже не одну pdf-ную страницу в курсе что Protected Methods - методы класса которые можно переопределять в наследниках. Часто большинство этих методов скрыто в недрах хелпа в аккордеоне с надписью “Show Inherited Protected Methods", однако это не наш случай. Интересующие нас сейчас методы DateTimeAxis на виду:

  1. formatDays(d:Date, previousValue:Date, axis:DateTimeAxis):String
  2. formatMilliseconds(d:Date, previousValue:Date, axis:DateTimeAxis):String
  3. formatMinutes(d:Date, previousValue:Date, axis:DateTimeAxis):String
  4. formatMonths(d:Date, previousValue:Date, axis:DateTimeAxis):String
  5. formatSeconds(d:Date, previousValue:Date, axis:DateTimeAxis):String
  6. formatYears(d:Date, previousValue:Date, axis:DateTimeAxis):String

Разумеется прежде чем переопределять их в соответствии с вашими пожеланиями следует ознакомиться с исходным кодом DateTimeAxis. Там за вас уже все придумали и написали:

  1. protected function formatYears(d:Date, previousValue:Date, axis:DateTimeAxis):String
  2. {
  3.         var fy:Number = d[fullYearP];
  4.         return fy.toString();
  5. }
  6. protected function formatMonths(d:Date, previousValue:Date, axis:DateTimeAxis):String
  7. {
  8.         var fy:Number = d[fullYearP];
  9.         return (d[monthP] + 1) + "/" + ((fy % 100) < 10 ? "0" + fy % 100 : fy % 100);
  10. }
  11. protected function formatDays(d:Date, previousValue:Date, axis:DateTimeAxis):String
  12. {
  13.         var fy:Number = d[fullYearP];
  14.         return (d[monthP] + 1) + "/" + d[dateP] + "/" + ((fy % 100) < 10 ? "0" + fy % 100 : fy % 100);
  15. }
  16. protected function formatMinutes(d:Date, previousValue:Date, axis:DateTimeAxis):String
  17. {
  18.         return d[hoursP] + ":" + (d[minutesP] < 10 ? "0" + d[minutesP] : d[minutesP]);
  19. }
  20. protected function formatSeconds(d:Date, previousValue:Date, axis:DateTimeAxis):String
  21. {
  22.         return d[hoursP]+ ":" + (d[minutesP] < 10 ? "0" + d[minutesP] : d[minutesP]) + ":" + (d[secondsP] < 10 ? "0" + d[secondsP] : d[secondsP]);
  23. }

Потребуется только слегка откорректировать эти методы в соответствии с вашими пожеланиями. Или, если приложение требует некоторой гибкости, добавить к уже имеющемуся формату еще несколько форматов отображения. (в зависимости от локали)

Кстати. Если вдруг получившиеся в ходе переопределения методов метки будут натыкаться друг на друга и делать подписи абсолютно нечитаемыми следует воспользоваться методом reduceLabels(intervalStart:AxisLabel, intervalEnd:AxisLabel):AxisLabelSet, а никак не свойством interval : Number, как это может захотеться с первого взгляда. Но это уже совсем другая история…

Декабрь 20th, 2006 от graann

Если по какой-то нелепой случайности кто-то из вас еще не ознакомился с этим волшебным сборником советов, настоятельно рекомендую исправить это досадное недоразумение.

ЗЫ: Уже на русском. За что огромная благодарность команде переводчиков!

Graann`s blog
flash, flex и все, что придет в голову

Сентябрь 2010
Пн Вт Ср Чт Пт Сб Вс
 << <   > >>
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30      

О блоге

С назначением блога можно ознакомиться здесь

Идейным вдохновителем и по совместительству куратором блога является Сonstantiner, за что ему огромный респект и уважуха! Впрочем не только за это :)

Поиск

powered by b2evolution free blog software


Design downloaded from Zeroweb.org
Website templates, layouts, and website tools for FREE!
Free short URL services from urlSNIP.