B4J Question How to cast Java HashMap to B4J Map

rwblinn

Well-Known Member
Licensed User
Longtime User
Hi,

the javacode below (defined in a library using "hashmap to map convert example" from another related thread) causes in B4J a java.lang.ClassCastException when assigning a list map entry to a B4J map.
Checking content via createmap, the result is the same content as in the list map entries created via the library.

Any hints on the cause for this exception?

//B4J Code
B4X:
Dim l As List = cl.ColorMap
  Log(l.Get(0))
  'OUTPUT = (MyMap) {Name=TRANSPARENT, Value=0x00000000}
  For i = 0 To 1
    Log(l.Get(i))
    Dim m As Map = l.Get(i)
    ' EXCEPTION:
    ' java.lang.ClassCastException: anywheresoftware.b4a.objects.collections.Map cannot be cast to anywheresoftware.b4a.objects.collections.Map$MyMap
  Next

// JAVA CODE
B4X:
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import javafx.scene.paint.Color;
import anywheresoftware.b4a.BA;
import anywheresoftware.b4a.objects.collections.Map;

..
.. additional code
..

//List of Color Names and Values as a Map
public static  List<Map> getColorMap() throws IllegalArgumentException, IllegalAccessException, ClassNotFoundException
{
    List<Map> colors = new ArrayList<Map>();
    Class<?> clcolor = Class.forName("javafx.scene.paint.Color");
    if (clcolor != null) {
    Field[] field = clcolor.getFields();
    for (int i = 0; i < field.length; i++) {
      Field f = field[i]; 
      // Get Name
      Object objn = f.get(null);
      if(objn instanceof Color){
        Color c = (Color) objn;
        Map m = new Map();
        m.Initialize();
        m.Put("Name", f.getName());
        m.Put("Value", c.toString());
        colors.add(m);
      } 
     }
    }
    return colors;
}
 

Daestrum

Expert
Licensed User
Longtime User
I may be missing the point of the question, but why would the Java routine return a list of maps??
Surely it could just return a map<colorName,colorValue>, which you could just read in B4J directly.
 
Upvote 0

rwblinn

Well-Known Member
Licensed User
Longtime User
Hi Erel,

thanks for the hint - Tried, but getting an error "method not found" when using m.Object.

Pls advice if there is anything else that needs to change.
 
Upvote 0

rwblinn

Well-Known Member
Licensed User
Longtime User
@Erel,
thanks again. This is how I got it working:
B4X:
public static  List<Map.MyMap> getColorMapAsList() throws IllegalArgumentException, IllegalAccessException, ClassNotFoundException
    {
        List<Map.MyMap> colors = new ArrayList<Map.MyMap>();
        Class<?> clcolor = Class.forName("javafx.scene.paint.Color");
        if (clcolor != null) {
            Field[] field = clcolor.getFields();
            for (int i = 0; i < field.length; i++) {
                Field f = field[i];              
                Object objn = f.get(null);
                if(objn instanceof Color){
                    Color c = (Color) objn;
                    Map m = new Map();
                    m.Initialize();
                    m.Put("Name", f.getName());
                    m.Put("Value", c.toString());
                    colors.add(m.getObject());
                }          
            }
        }
        return colors;
    }

@Daestrum
The reason for building this piece of Java code, was to a) test Class.forName to dynamically create objects and access their fields accordingly and b) learn how to create a list of maps to be used in B4A/J code. Both topics are required in a current B4J project.
Thanks for your reply = based upon your hint, have build following Java Method.
May be of use to others:
B4X:
    public static  Map.MyMap getColorMap() throws IllegalArgumentException, IllegalAccessException, ClassNotFoundException
    {
        Class<?> clcolor = Class.forName("javafx.scene.paint.Color");
        Map.MyMap colormap = new Map.MyMap();
        if (clcolor != null) {
            Field[] field = clcolor.getFields();
            for (int i = 0; i < field.length; i++) {
                Field f = field[i];               
                Object objn = f.get(null);
                if(objn instanceof Color){
                    Color c = (Color) objn;
                    Map m = new Map();
                    m.Initialize();
                    m.Put(f.getName(), c.toString());
                    colormap.putAll(m.getObject());
                }           
            }
        }
        return colormap;
    }

Of course any code optimization ideas welcome.
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
Slightly optimized to return the map (not sure what Map.MyMap is so using Hashmap)
B4X:
        ....
        Map<String,String> m  = new HashMap<>();
        Class<?> p = Class.forName("javafx.scene.paint.Color");
        for (Field g : p.getFields()){
            m.put(g.getName(), g.get(null).toString());
        }
        return m;
 
Upvote 0
Top