Константин Ковалев предложил более простой и изящный вариант решения проблемы затронутой мною в предыдущем посте.
Суть решения заключается в использовании метатега 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> |
и код класса
- package com.riapriority.tests
- {
- import mx.formatters.DateFormatter;
- [Bindable]
- [RemoteClass(alias="com.riapriority.tests.DataObject")]
- public class DataObject
- {
- public var date: Date;
- public var random: String;
- public function generate(): void
- {
- date = new Date();
- random = "" + Math.random() * 10000;
- }
- public function toString():String
- {
- var df:DateFormatter = new DateFormatter ();
- df.formatString = "JJ:NN:SS DD/MM/YYYY";
- return "\n date: " + df.format(date) + "\n random: " + random;
- }
- }
- }
[Bindable] здесь не обязателен, но как тонко выразился Константин,
класс без [Bindable], что штопор без бутылки ![]()
Upd: Работает только с публичными свойствами (касается так же вложенных объектов). Вложенные объекты так же должны быть снабжены метатегом RemoteClass.
Продолжу тему затронутую Александром Гаховым в статье Клонирование объектов утилитой 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> |
Собственно сам класс нашего объекта.
- ackage src
- {
- import mx.formatters.DateFormatter;
- public class DataObject
- {
- public var date: Date;
- public var random: String;
- public function DataObject()
- {
- }
- public function generate(): void
- {
- date=new Date();
- random=""+Math.random()*10000;
- }
- public function toString():String
- {
- var df: DateFormatter=new DateFormatter();
- df.formatString="JJ:NN:SS DD/MM/YYYY";
- return "\n date: "+df.format(date)+"\n random: "+random;
- }
- }
- }
Прошу прощения за подобное отображение mxml-ины. Если пример вас заинтересует скопируйте его. ![]()
Путь скинизации посредством 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> |
- package src
- {
- import mx.core.UIComponent;
- import mx.controls.Image;
- public class Example extends UIComponent
- {
- private var image: Image;
- public function Example()
- {
- }
- override protected function createChildren(): void
- {
- super.createChildren();
- image=new Image();
- image.source=getStyle("image");
- addChild(image);
- }
- }
- }
И после компиляции картинку благополучно не видим. Почему? Потому, что по умолчанию ее размеры составляют 0 x 0. Для того чтобы она отобразилась корректно требуется задать ей реальные размеры, каковые нам любезно предоставляют свойства measuredWidth и measuredHeight. Однако актуальные значения ширины и высоты будут доступны только после вызова метода protected function measure(): void UIComponent, о котором доступна подробная информация в хелпе.
Ну и собственно результат:
- package src
- {
- import mx.core.UIComponent;
- import mx.controls.Image;
- public class Example extends UIComponent
- {
- private var image: Image;
- public function Example()
- {
- }
- override protected function createChildren(): void
- {
- super.createChildren();
- image=new Image();
- image.source=getStyle("image");
- addChild(image);
- }
- override protected function measure():void
- {
- super.measure();
- image.setActualSize(image.measuredWidth, image.measuredHeight);
- }
- }
Следует отметить, что подобных проблем с размерами не возникает в mxml-e.
Сегодня у Константина Палыча день рождения!
Счастье у тебя уже есть, поэтому дальнейших творческих узбеков тебе, Костик, и чтобы твое здоровье тебе ни в чем не отказывало! ![]()
По ряду причин была вынуждена установить на свою рабочую машину Vista. Расскажу о тех проблемах, с которыми столкнулась в ходе установки flex builder2 под Vista. Сразу оговорюсь переходить на 3-й builder мы не стали т.к он бета и показался нам не стабильным.
Проблема раз. Попытка установить второй билдер под eclipse 3.3:

Проблема два. Вернее легкое неудобство. В процессе установки инсталятор отказался демонстрировать контролы. Просто не отображал. Устанавливать пришлось на автопилоте руководствуясь подсознанием. Установила. Честно признаюсь не с первого раза.
Update установила.
Проблема три. SVN отказался дружить с подцепленым проектом. Проблема довольно специфическая, врядли у кого-то повторится, поэтому подробно останавливаться на ней не буду. Починила.
Установила subclips.
Последняя капля. Эклипс периодически вылетал с предупреждением следующего вида

В debugg-режиме с прерываниями он вылетал постоянно. Переставляла builder и java. Не помогло.

Счастья, здоровья, хорошего аппетита, трудовых свершений, а главное, крепких нервов в совместной работе с твоей горячо любимой мной ![]()
На протяжении довольно долгого времени я пользовалась OmeaReader-ом. Была я вполне счастлива и довольна, пока в один прекрасный день omea не задергался в конвульсиях и не умер прихватив с собой всю мою базу. Довольно неприятное обстоятельство, особенно учестывая, что легко восстановить мне ее не удалось. В начале не помогла перезагрузка, а потом и переустановка. Спас почищенный реестр, но рисковать так более я готова не была. Возникла потребность в поиске другого RSS-reader-а, результатом чего и стал этот пост. Обзоров было уже довольно много. И зачастую они весьма противоречивы. Я же только поделюсь с вами своим абсолютно субъективным мнением.
Mozilla Thunderbird. 2.0.0.6
Клиент бесплатный. Mozilla Firefox был и остается моим самым любимым браузером. Разумеется на Thunderbird я обратила свое пристальное внимание и… И мои надежды не оправдались. Как rss-клиент мне он показался глючным, неудобным и, что самое неприятное, он теряет каналы. Потерянные каналы не отображаются в списке подписок, но Thunderbird свято верит, что они где-то есть и при попытке повторной подписи выкидывает эксепшен. Потерянных каналов было только 2, но мне как-то хватило. Кроме того, порадовала приятная необходимость всякий раз при запуске подтверждать пароли на все каналы требующие аутентификации. Подтверждать нажатием кнопочки enter. Однако, если таковых каналов у вас не один, мягко говоря, это начинает нервировать. Отключить этот бонус мне не удалось.
И тем не менее пока Thunderbird остался моим основным почтовым клиентом.
ЗЫ: В ходе изысканий был найден, приятный, на мой взгляд, плагин сворачивающий Firefox и Thunderbird в трей
Microsoft Office Outlook 2007
Буду краткой. Не халява. Запутанный и перегруженный интерфейс. Слишком умный для меня. Мой моск, в плане продвинутости, не готов с ним конкурировать. Не нравится.
Abilon 2.5.3 b 196
Бесплатный. Легкий и быстрый. Вполне удобный. Все бы с ним хорошо, если бы не одна небольшая фигня. Отказался правильно парсить жж-шные посты. ![]()
FeedDemon 2.3.0.10
Не халява. Но выбрала я именно его. Боюсь даже, что он затмил в моих глазах OmeaReader в его неглючные времена. Он нравится мне всем, кроме стоимости.
Не буду вдаваться в пространное описание тем более что таковых в сети и без моего предостаточно. Заинтересованные могут почитать о нем например тут и не только о нем тут
При большом количестве меток (да и вообще компонент) и частой их отрисовке вы непременно столкнетесь с тормозами. В случае с метками есть альтернатива в лице 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> |
:: Следующие >>
