SWINGing on a star

hey guys,



I'm moving my NWN resource browser off Java3D and onto my new JME loader for its model and area viewers.



Looking at the Swing test in jmetest/utils i managed to get a basic frame u pwitha  JME canvas in it, but its pretty ugly stuff.



Im thinking of trying to make something that wraps it and makes it much more like a Swing component so you can just drop it in  a layout and go.  Before I do it, is this already there somewhere that i missed?



Thanks



JK

Unless I'm confused (which is usually the case) I think JMEDesktop does what you're looking for?

Hmm I think jeffpk is trying to do the opposite: a jME canvas within a Swing app, instead of having Swing widgets rendered by jME.



JK : there's work in progress for precisely the same thing with SWT (works great but with only one canvas for the moment), I guess it should be easier with Swing (since jME works with AWT)

Oh…right…no wonder it didn't make a lot of sense to me what he was asking. :wink:

Yeah Librarian is right, thats what Im up to.



For a game, I want one big JME screen, but for tools its useful to be able to embed the JME in Swing.



Its doable now, just a bit ugly so I guess Ill go ahead and make my component…  a JMEJPanel or some such thing.



JK

If you're talking about tools, why not go ahead and use JMEDesktop?  If you set it to ortho you could get the same effect in the OpenGL window, right?

jeffpk said:

Yeah Librarian is right, thats what Im up to.

For a game, I want one big JME screen, but for tools its useful to be able to embed the JME in Swing.

Its doable now, just a bit ugly so I guess Ill go ahead and make my component..  a JMEJPanel or some such thing.

JK


i've written a simple class that build swing apps with an embedded jme canvas specifically from the point of view of tools.....


public class SwingJMEFrame extends JFrame implements Runnable, ActionListener
{
   protected    Canvas                   mcl_jmeCanvas;
   protected   SimpleCanvasImpl         mcl_canvasImplementor;
   private      JButton                  mcl_randClrs;
   
   public   int                  mi_width;
   public   int                  mi_height;
   
   public   int                  mi_jmeCanvasWidth;
   public   int                  mi_jmeCanvasHeight;
   
   public
   SwingJMEFrame(int i_w, int i_h, int i_jmeW, int i_jmeH)
   {
      mi_width = i_w;
      mi_height = i_h;
      mi_jmeCanvasWidth = i_jmeW;
      mi_jmeCanvasHeight = i_jmeH;
      
      initFrame();
      setVisible(true);
      
      // wait for it to come alive
      while (mcl_jmeCanvas == null) ;
           
      Thread         lcl_runner = new Thread(this);
      lcl_runner.setDaemon(true);
      lcl_runner.start();
      
      System.out.println("running!!!");
      
   }
   
   /* (non-Javadoc)
    * @see java.lang.Runnable#run()
    */
   public void
   run()
   {
      try
      {
            while (true)
            {
                if (isVisible())
                {
                   mcl_jmeCanvas.repaint();
                }
               
                Thread.sleep(2);
            }
        }
      catch (InterruptedException e)
      {
            e.printStackTrace();
        }
      
   }

   public   void
   initFrame()
   {
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setLayout(null);
      setSize(mi_width, mi_height);
      setLocationRelativeTo(null);
      
      getJmeCanvas();
      
      this.getContentPane().add(mcl_jmeCanvas);
      
      initialiseUserComponents();
   }
   
   public   void
   initialiseUserComponents()
   {
      mcl_randClrs = new JButton("rand");
      mcl_randClrs.setBounds(mi_jmeCanvasWidth + 20, 25, 120, 30);
      this.getContentPane().add(mcl_randClrs);
      mcl_randClrs.addActionListener(this);
   }
   
   public   Canvas
   getJmeCanvas()
   {
      if(mcl_jmeCanvas == null)
      {
         buildJMECanvas();
      }
      
      return mcl_jmeCanvas;
   }
   
   public   void
   buildJMECanvas()
   {
      mcl_jmeCanvas = DisplaySystem.getDisplaySystem().createCanvas(mi_jmeCanvasWidth, mi_jmeCanvasHeight);
      mcl_jmeCanvas.setSize(new Dimension(mi_jmeCanvasWidth, mi_jmeCanvasHeight));
      
      initialiseImplementor();
      
      ((JMECanvas)mcl_jmeCanvas).setImplementor(mcl_canvasImplementor);
   }
   
   public   void
   initialiseImplementor()
   {
      mcl_canvasImplementor = new SwingJMEImplementor(mi_jmeCanvasWidth, mi_jmeCanvasHeight);
   }
   
   public   SimpleCanvasImpl
   getImpl()
   {
      return mcl_canvasImplementor;
   }
   
   /* (non-Javadoc)
    * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
    */
   public void
   actionPerformed(ActionEvent cl_e)
   {
      if(cl_e.getSource() == mcl_randClrs)
      {
         ((SwingJMEImplementor)mcl_canvasImplementor).lcl_box.setRandomColors();
      }
   }

   /**
    * @param args
    */
   public static void
   main(String[] args)
   {
      // TODO Auto-generated method stub
      SwingJMEFrame         lcl_main = new SwingJMEFrame(1024, 768, 640, 480);

   }

}





if you want to build a tool using jme and swing just

1. subclass SwingJMEFrame
2. subclass SimpleCanvasImpl


public class SwingJMEImplementor extends SimpleCanvasImpl
{
   public   Box         lcl_box;

   /* (non-Javadoc)
    * @see com.jmex.awt.SimpleCanvasImpl#simpleSetup()
    */
   @Override
   public void
   simpleSetup()
   {
      lcl_box = new Box("box1", new Vector3f(0, 0, 0), 5f, 5f, 5f);
      lcl_box.setRandomColors();
      this.rootNode.attachChild(lcl_box);
      
   }

   public
   SwingJMEImplementor(int i_w, int i_h)
   {
      super(i_w, i_h);
      
   }
   
   public void
   simpleRender()
   {
      
    }
   

}



3. in the initialiseImplementor() method of the class you created in step 1 instantiate the class that you wrote in step 2...
e.g.


mcl_canvasImplementor = new SwingJMEImplementor(mi_jmeCanvasWidth, mi_jmeCanvasHeight);



4. implement the initialiseUserComponents with whatever components you want

it take all of 1 minute to get a swing app with a jme canvas up and running....
hope that helps....
oh i ripped most of this out of RenParticleEditor....credit where credit is due  :)

Handy, thanks.



I gave up on my attempt.  I played with it a bit and came to the conclusion that I really don't understand AWT internals well enough to do it right… and the last thing we need is another half-assed way to do it lying around :wink:



One of my best friends at Sun knew the AWT stuff in and out, but hes been gone for awhile :frowning:



JK

Jeff, have you considered just using JMEDesktop inline like I suggested?  You would no longer have any need for embedding it anymore then, right?  Also, it would offer some other nice features should you choose to use them in the future (such as floating tools inside the OpenGL view).

This app has an awful lot of Swing code arranged in a  JFrame already.  its my NWN Resource browser and I dont think I want to have to re-engineer.  its just not worth it.



I Do have a JME window working in a JFrame, its just not pretty code.



Maybe next utility i build ill try the other way.  what are the gotchas/limits of trying

to do Swing within the JME environment?


Btw thanks NComp.



Im generalizing your code just a bit more and then I can use it as the root for any future utilities 8)

The biggest problem with Swing inside jME is it has some issues in JRE 1.6.  There are a few places where you end up having to make some changes to existing code, but most of the time you can just drop in existing code to the JMEDesktop and it just works.