JM3: AssetManager is null [solved]

i have the following:

[java]public class Main

{

/** The one and only application object /

static Main main = null;

/
* Java Swing framework window /

static MainFrame frameMain = null;

/
* JMonkey Engine Main Canvas /

static JM3Canvas canvasJM3 = null;

/
* DMF texture manager */

static TextureManager textureManager = null;



private Main()

{

frameMain = new MainFrame();

canvasJM3 = new JM3Canvas();

textureManager = new TextureManager();

}



public static void main(String[] args)

{

main = new Main();

java.awt.EventQueue.invokeLater(new Runnable()

{

public void run()

{

canvasJM3.init(640, 480, AppSettings.LWJGL_OPENGL1);

frameMain.init(JM3Canvas.getCanvas());

canvasJM3.startCanvas(true);

textureManager.init(main);

}

});

}



public static AssetManager getAssetManager()

{

if (canvasJM3 == null)

return null;

return canvasJM3.getAssetManager();

}

}



______________________________________________________________________



public class JM3Canvas extends SimpleApplication

{

private static Canvas canvas = null;



public void init(int width, int height, String renderer)

{

AppSettings settings = new AppSettings(true);

settings.setRenderer(AppSettings.LWJGL_OPENGL1);

settings.setWidth(width);

settings.setHeight(height);

setSettings(settings);

createCanvas();

JmeCanvasContext ctx = (JmeCanvasContext) getContext();

ctx.setSystemListener(this);

canvas = ctx.getCanvas();

Dimension dim = new Dimension(width, height);

canvas.setPreferredSize(dim);

}

}



______________________________________________________________________



public class TextureManager

{

public void init(Main main)

{

AssetManager am = Main.getAssetManager();

if (am == null)

return; // <- i reach this point.

}

}[/java]



When the programm reaches Texturemanager.init(), the cavas still has not finished its setup and the assetManager is null.

Why? Shouldnt canvasJM3.startCanvas(true) prevent that?

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:swing_canvas

Yes, thats (partly) what i did, thats why im asking.

What happens when you do it exactly like that? :stuck_out_tongue:

Then my application wont look like i need it. But if startCanvas(true) would do as documented, it would workk ;-/

Why cant you use it like the way it works? Whats the problem with your application? The problem is that the real OpenGL context can only be started when its got a visible window, thats also the reason for the “SceneViewer hidden on start” bug in jMP.

The problem is that i dont want Main, JM3 and Swing in one huge application class, because that simply would become really bloated. Another point is that i dont want a JM3-Application that uses Swing but a rhavin-Application that uses swing and JM3;-)



Here the working solution if someone falls into the same pit:



In main.java

[java]public void run()

{

canvasJM3.init(640, 480, AppSettings.LWJGL_OPENGL1);

frameMain.init(JM3Canvas.getCanvas());

canvasJM3.startCanvas(true);

// we wait until the render-thread has called simpleApplicationInit()

while(!canvasJM3.isInited())

{

try

{

synchronized(canvasJM3) {canvasJM3.wait();}

}

catch (InterruptedException e)

{e.printStackTrace();}

}

textureManager.init(main);

}[/java]



in JM3Canvas.java

[java]

/** Flag showing JM3-engine has done initialization /

private boolean inited = false;

/
* Has JM3-engine done initialization? */

public boolean isInited() {return inited;}



@Override

public void simpleInitApp()

{

inited = true;

synchronized (this) {notifyAll();}

// … //

}

[/java]

1 Like

Note: I think that java.util.concurrent.CountdownLatch could be used for similar thread synching without all the synchronizing and while-looping, etc.

As i understand the java.util.concurrent.CountdownLatch, it would just trade slightly fewer code in my part for much more code imported. Not a trade im usually willing to agree to.

Wow… ok, I never really met anyone who shunned a single-class JDK import, but ok.



For those not worried about importing CountDownLatch, this is what it might look like:



In main.java

[java]public void run()

{

canvasJM3.init(640, 480, AppSettings.LWJGL_OPENGL1);

frameMain.init(JM3Canvas.getCanvas());

canvasJM3.startCanvas(true);

// we wait until the render-thread has called simpleApplicationInit()

try

{

canvasJM3.waitForInit();

}

catch (InterruptedException e)

{e.printStackTrace();}



textureManager.init(main);

}[/java]



in JM3Canvas.java

[java]

/** Flag showing JM3-engine has done initialization /

CountDownLatch inited = new CountDownLatch(1);



/
* Has JM3-engine done initialization? */

public void waitForInit() throws InterruptedException {

inited.await()

}



@Override

public void simpleInitApp()

{

inited.countDown();

// … //

}

[/java]

1 Like

I still think in Bytes when it comes to storage, but you’re allowed to call me esoteric on that :wink: But it was not about the import, it was about the actual code getting executed. In my last project i had to hunt down two (!) processor cycles because the function gets called in a database with a billion (!) entries on every field.

1 Like
rhavin said:
I still think in Bytes when it comes to storage, but you're allowed to call me esoteric on that ;) But it was not about the import, it was about the actual code getting executed.


Ok. I'm not sure how that relates to the use of a JDK class but I'll take your word for it. ;)