3

In flex builder 4.5 i'm working on a project like cacoo. I want to save diagrams(display object,ui components,text) before close the application into somewhere than I would be able to access after the application open again.

more clear:-If user edit some uml diagram on this project and save it for edit later and close application.after some days he/she want to edit previously saved diagram. now how i'm save this diagram for future edit.

Devendra
  • 1,864
  • 6
  • 29
  • 49
  • What you are using Flex or adobe AIR. – Raja Jaganathan Jan 03 '13 at 09:08
  • thanks for ur assist,i'm using Flex 4.5 web application not AIR – Devendra Jan 03 '13 at 09:33
  • Please use a meaningfull title for your question; something other than the name of the IDE you use. Other than that, what exactly do you mean by "save diagrams"? Save a picture? Save the state of your application? Or just a part of it? ... Please be more precise. – RIAstar Jan 03 '13 at 09:56

3 Answers3

1

You can store your diagram state through SharedObject for better you create one class which hold all of your state of Diagram so that later you can use

SharedObject using http://livedocs.adobe.com/flex/3/html/help.html?content=lsos_5.html

you can use registerClassAlias for custom class stored in sharedobject.

myClassInstance = new MyClass();
myClassInstance.x = 100;
myClassInstance.y = 100;
myClassInstance.text = "diagrams";

registerClassAlias("com.path.to.MyClass", MyClass);
myStuff = SharedObject.getLocal("myAppStuff");
myStuff.data.whatINamedIt = myClassInstance;
myStuff.flush();

now when get it back out... you can say:

myStuff = SharedObject.getLocal("myAppStuff");
var mySavedClass:MyClass = myStuff.data.whatINamedIt as MyClass;

Read mySavedClass instance value then inject to your diagram model when open again.

To implement application close event

http://www.flexer.info/2007/10/25/fabridge-warn-on-flex-application-exit/

Raja Jaganathan
  • 33,099
  • 4
  • 30
  • 33
  • thanks mr.raja, but if user open his/her previously edit diagram in another system then will he/she able to edit the same previous diagram?? – Devendra Jan 03 '13 at 10:49
  • For that you need to send to state of Diagram value to server some period of times(like 2 min) then when ever your that user log in again get those information from server then set to your model. – Raja Jaganathan Jan 03 '13 at 11:12
  • how to store this value on server?can user able to edit previously edited diagram on different system(computer)? – Devendra Jan 03 '13 at 11:27
  • Ofcourse it is possible in (any)another system your app running in server right then why worrying about it. Store value via table then get back those value when user loggedin. – Raja Jaganathan Jan 03 '13 at 11:47
  • i'm store all diagram's instances in arrayList, if i would be able to store this list in shareObject then my problem will be solved.. – Devendra Jan 03 '13 at 12:00
  • i'm not able to get back SharedObject to my class object. – Devendra Jan 05 '13 at 08:01
  • its working but i'm able to get group component in Object class only... do u have any idea about it? – Devendra Jan 05 '13 at 08:13
1

If save/open dialog will work for you, you can yse FileReference API. Before doing this, you have to implement serialization/deserialization of your state into/from String/ByteArray/XML object.

private var fileReference:FileReference;

// due to security restrictions, this method must be called from an
// event handler that responds to a user event (mouse click or key
// press), otherwise it will fail.

private function saveState(serializedState:*, fileName:String):void {
    fileReference = new FileReference();

    fileReference.addEventListener(Event.COMPLETE, onSaved);
    fileReference.addEventListener(IOErrorEvent.IO_ERROR, onSavingError);

    try {
        fileReference.save(serializedState, fileName); // will open save dialog
    } catch (e:Error) {
        trace("error saving data: " + e.toString());
        freeListeners();
    }
}

private function onSaved(e:Event):void {
    trace("saved!");
    freeListeners();
}

private function onSavingError(e:ErrorEvent):void {
    trace("error saving data: " + e.toString());
    freeListeners();
}

private function freeListeners():void {
    fileReference.removeEventListener(Event.COMPLETE, onSaved);
    fileReference.removeEventListener(IOErrorEvent.IO_ERROR, onSavingError);
}

Similarly with restoring the state (use FileReference.browse(), then FileReference.load()).

If you need to save/restore app state without any dialogs, then you should probably use AIR (or SharedObject, as Raja Jaganathan suggested). But it seems to be not the case, as you want the user to be able to re-open the diagram in another system. To achieve this, you should allow the user to save his work to the appropriate place, so later he can move it to another machine/system and re-open it with your application.

Another alternative is to store everything on the server and provide the user with a list of saved files (like Cacoo does). If you go this way, you'll have to implement the corresponding server-side API. It may be REST API or smth like RTMP server. In the case of REST API, use FileReference.upload() to upload the data to your server, and URLLoader.load() to obtain it back.

skozin
  • 3,789
  • 2
  • 21
  • 24
  • i'm using flex 4.6 web application. so AIR will not be used. – Devendra Feb 12 '13 at 11:08
  • @raja was correct but in case UIComponent decedents i'm not able to copy these type of objects. – Devendra Feb 12 '13 at 11:10
  • Sure. But you can copy the *state*, not actual objects that represent this state. For example, you can save positions/labels of your diagram components, and then re-create corresponding Flex objects. – skozin Feb 12 '13 at 11:13
  • Moreover, this is the only correct way of saving UML diargam when you want to edit it later. Save *the state*, not it's representation. – skozin Feb 12 '13 at 11:16
  • how we create corresponding objects.i'm get objects in base class Object form. – Devendra Feb 12 '13 at 11:16
  • If you use SharedObject, you should call [registerClassAlias](http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/net/package.html#registerClassAlias()): registerClassAlias("anyName", YourCustomClass) *before* saving/restoring anything (for example, when your app starts). This tells AMF to (de-)serialize instances of YourCustomClass properly. – skozin Feb 12 '13 at 11:19
  • i've used this but no solution for UIComponents it working for text objects. – Devendra Feb 12 '13 at 11:21
  • As I said, saving UIComponent is a bad idea. Save positions/labels/anything about your diagram, and then re-create UIComponents using this data. – skozin Feb 12 '13 at 11:23
  • so no need to registerclassAlias: in this case? – Devendra Feb 12 '13 at 11:25
  • It's better to use it. For example, if you store positions in Rectangle objects, then you should call registerClassAlias("com.my.pcg.Rectangle", Rectangle) to be able to get them back in form of Rectangle objects. Otherwise, you'll get them in form of plain objects. – skozin Feb 12 '13 at 11:28
  • last u said no need to save particular object so i think no need to registerclass aliasing.. – Devendra Feb 12 '13 at 11:30
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/24373/discussion-between-dev-and-sam-kozin) – Devendra Feb 12 '13 at 11:31
1

Sprite or MovieClip other DisplayObject objects can not be direct serialized. So you should stored objects information (origin x,y, width, height, color, child info...). using a ByteArray or Array or Dictionary ... and that save to ShareObjects. later roll back from ShareObject and re-create Original Object. MovieClip or Sprite appropriate purpose is container.

Here is my test code.

1. create a Movieclip. purpose is container.

enter image description here

2. draw a rectangle using a graphics. And set the coordinates.

var drawWidth:Number = 500;
var drawHeight:Number = 300;

var rect:MovieClip = new MyRect();
rect.graphics.beginFill(0xffffff*Math.random(),1);
rect.graphics.drawRect(0,0,drawWidth,drawHeight);
rect.graphics.endFill();
rect.x= 300;
rect.y= 100;

3. Stores the information in the array.

var myRectInformation:Array = new Array();
myRectInformation.push(rect.x);
myRectInformation.push(rect.y);
myRectInformation.push(drawWidth);
myRectInformation.push(drawHeight);
var bmd:BitmapData = new BitmapData(rect.width, rect.height,true,0);
bmd.draw(rect);
//is byteArray.
myRectInformation.push(bmd.getPixels(new Rectangle(0,0,bmd.width,bmd.height)));

4. save to SharedObjects, array.

var mySaveData:SharedObject = SharedObject.getLocal("myStorage")
mySaveData.data.myRectInformation = myRectInformation;
mySaveData.flush();

5. this is load from SharedObject data stored. and recreate Objects.

var rect:MovieClip = new MyRect();
var loadBmd:BitmapData = new BitmapData(mySaveData.data.myRectInformation[2], mySaveData.data.myRectInformation[3], true, 1);
loadBmd.setPixels(new Rectangle(0,0,loadBmd.width,loadBmd.height), mySaveData.data.myRectInformation[4]);
var bmp:Bitmap = new Bitmap(loadBmd);
rect.addChild(bmp);
rect.x = mySaveData.data.myRectInformation[0];
rect.y = mySaveData.data.myRectInformation[1];
addChild(rect);
bitmapdata.com
  • 9,572
  • 5
  • 35
  • 43