3 Replies Latest reply on Sep 9, 2008 10:40 AM by dimival

    Issue when converting java.util.HashMap into an ActionScript Object

    dimival Level 1
      I have this weird issue and i can't figure it out, let me explain:

      I have a java object A which has a HashMap variable myMap, this map will hold objects of class B. Inside B there is an instance of C class. In ActionScript i have the corresponding class A which has a variable myMap but since there is no HashMap in ActionScript its type is Object and i also have the corresponding classes B and C.

      [RemoteClass(alias="com.test.A")]
      public class A {
      public var myMap:Object; // this is the HashMap in Java
      }

      [RemoteClass(alias="com.test.B")]
      public class B {
      public var id:Number;
      public var name:String;
      public var myC:C
      }

      [RemoteClass(alias="com.test.C")]
      public class C {
      public var myId:Number;
      public var myName:String;
      }

      I need to put the C objects of each B object of the map inside a DataGrid so i am obtaining the object of class A using a RemoteObject and then i iterate over the myMap property using a for each in loop, like this:

      for each(var i:* in objectA.myMap) {
      someArrayCollection.add(i.myC);
      }

      The first issue appears here, suppose the java HashMap contains 3 elements, in the ActionScript loop i get 4 elements, the fourth one being a reference to the A object. In order to avoid this i use the "is" operator like this:

      for each(var i:* in objectA.myMap) {
      if (i is B) {
      someArrayCollection.add(i.myC);
      }
      }

      Now here is the real issue, when i do this the C objects contained in the B objects of the myMap property are reset to their initial values (myId is NaN and myName is empty string according to the C class). I changed the if condition to this and worked:

      for each(var i:* in objectA.myMap) {
      if (!(i is A)) {
      someArrayCollection.add(i.myC);
      }
      }
      When i did this the DataGrid shows the values of the C objects (myId and myName) perfectly fine. I did a little more testing and i "figured" out the issue, if i use an instance of class B anywhere in my application, the values of the C object are reset, for example:

      for each(var i:* in objectA.myMap) {
      if (i is B) {
      someArrayCollection.add(i.myC);
      }
      }
      var test:B = new B();

      This resets the C object (myId and myName) of each B object contained in the map of the A object which makes no absolute sense.

      So the thing is whenever i use the B class, which is the class of the objects inside myMap, the C objects are reset!!!! Does anyone know how to fix this?????

      I am using Flex 2.01 hotfix 3, i wonder if this is some kind of bug that was solved in a later release.

      Any help would be appreciated.
        • 1. Re: Issue when converting java.util.HashMap into an ActionScript Object
          Ventis85 Level 1
          Your example is a little complicated so forgive me if I have the wrong idea. Also, although I work with Java programmers on Flex projects, I know next to nothing about Java, so Hashmap is a blurry concept for me.

          The way I understand it is that you get one object A from the Java side, which has one hashmap wich contains one or more objects B which each contain one object C.

          In that case I would change your myMap variable to an ArrayCollection instead of an Object. In fact, if it's possible, I wouldn't use the A object at all, since all it contains is the Hashmap. Simply casting the result you get from java into an arraycollection should suffice, there's no need to loop over the result. An arraycollection will also be much handier when working with Datagrids.

          Again to put the C object of each B object into a Datagrid, you don't need to loop over the arrayCollection. Simply put the arraycollection as dataprovider to your datagrid and in the column use myC as datafield. I often notice that Java developers tend to use Actionscript far to often when there are components that do the difficult work for you.

          Your second problem I don't fully understand. If you create a new instance of B then of course that instance will have default values, but it shouldn't affect any other instances.

          • 2. Re: Issue when converting java.util.HashMap into an ActionScript Object
            dimival Level 1
            You got the general idea but you missed some important points. I can't use ArrayCollection because java.util.HashMap can't be converted into one, it converts to Object. Think of HashMap as a Dictionary, a key with a value, so it maps to Object.

            I did a simple example for this, actually A, B and C have more properties, i just simplified it for this example.

            You are right about not having sense, i am not creating a new B object, i tried to use it like this " if (is B) ", by doing that you are using an instance of B, that's when the properties of object C are being reset. The properties of B (id and name) aren't being reset, but the myC property, which is a C object, is the one being reset.
            I realized that whenever i use a B instance, that is inside an if condition, or if i create a new B, then the C objects of the map are being reset, as if when using a B instance the Flash Player tried to cast the C objects automatically but instead it is reseting them.

            I am trying to put up a quick functional example of this behavior hoping someone can help me out
            • 3. Re: Issue when converting java.util.HashMap into an ActionScript Object
              dimival Level 1
              Ok i fixed it, like i said my app was a more complicated scenario so here's what happened:

              The C object is the superclass of D and E, and the Java service puts objects D or E inside the myC property of the B object, since myC is of type C and C is the super class of D and E then this works.

              The problem is that in Flex the C object inside B is actually a D or an E object, i just had to use an instance of D and E somewhere in the code so the Flash Player included those classes.

              Anyways, i know this is all complicated but the good news is that it works now