JMonkey in Swing Question

Hi All,



All questions I am going to pose in this thread line relate to the following article in the wiki…

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



This looks as though it is exactly what I want, however I am not 100% sure how this all works, and I guess more than anything right now before I begin I am looking for some clarification on a few points.



All I have to do is to initialize the canvas in the run method, and add the canvas as a panel to my already existing JFrame?

–seems too easy… ::disbeleiving look::



How do I add the JMonkey prequisites to my NetBeans project so that I can do this?



how does one have the canvas be started as a seperate thread?



Thanks,

~David



P.S. Sorry about some of the n00b questions, gotta learn somehow I guess…btw, you guys have been a great support for me in my project!

scratch the jmonkey prequisites quesiton, got it.

The canvas is already started as a separate thread. You can add it as any other component to your Swing/AWT GUI.

However you’re right that there’s a catch, the canvas is in fact a heavy-weight component, and heavy-weight components work differently and in some ways don’t cooperate well with the rest of the GUI.

You can find more info about heavy-weight components here:

http://java.sun.com/products/jfc/tsc/articles/mixing/

Ah, that was a very helpful article to point me to, and will save some headache, since I definately forsee some of those bridges needing to be crossed.



I have run into one other issue…I wish to use the netbeans GUI editor to layout the gui…though from my earlier attempt, I need to have my main class with the run method extend from javax.swing.JFrame to use the design mode.



How do I set it up so that I can do this?



I cannot simply extend both classes (JFrame and SimpleApplication), due to Java’s inability to support multiple inheritance…Ie making a new class of the type JFrame Form, and then adding the SimpleApplication extension.



Thanks,

~David

Don’t extend both of them, in fact, don’t even think about doing that :slight_smile: Trying to interact with jME from the GUI, or vice versa, is bound to cause many issues unless you properly take care of threading.

Ok, So I’m not entirely sure where I went wrong with my code. I feel as though it should be right, however when I hit run, it just doesnt pull up anything. Can anybody take a look and let me know which n00b mistake I’m making? Im trying to encode the canvas into Panel 3.



[java]

/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.

    */



    package doggyui_swingv2;



    import com.jme3.system.AppSettings;

    import com.jme3.system.JmeCanvasContext;

    import java.awt.Dimension;

    import javax.swing.JFrame;



    /**

    *
  • @author David

    */

    public class Main extends com.jme3.app.SimpleApplication

    {



    public Main()

    {



    }



    static JmeCanvasContext ctx;

    /**
  • @param args the command line arguments

    /

    public static void main(String[] args)

    {

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

    {

    public void run()

    {

    AppSettings settings = new AppSettings(true);

    settings.setWidth(640);

    settings.setHeight(480);



    Main canvasApplication = new Main();

    canvasApplication.setSettings(settings);

    canvasApplication.createCanvas(); // create canvas!

    ctx = (JmeCanvasContext) canvasApplication.getContext();

    ctx.setSystemListener(canvasApplication);

    Dimension dim = new Dimension(640, 480);

    ctx.getCanvas().setPreferredSize(dim);

    canvasApplication.initComponents();

    }

    });







    }



    /
    * This method is called from within the constructor to
  • initialize the form.

    */



    private void initComponents() {



    jTabbedPane1 = new javax.swing.JTabbedPane();

    jPanel1 = new javax.swing.JPanel();

    jLabel1 = new javax.swing.JLabel();

    jLabel2 = new javax.swing.JLabel();

    jLabel3 = new javax.swing.JLabel();

    jLabel4 = new javax.swing.JLabel();

    jPanel2 = new javax.swing.JPanel();

    jButton1 = new javax.swing.JButton();

    jButton2 = new javax.swing.JButton();

    jPanel3 = new javax.swing.JPanel();

    jButton3 = new javax.swing.JButton();

    window = new javax.swing.JFrame();



    jPanel3.add(ctx.getCanvas());



    // <editor-fold defaultstate=“collapsed” desc=“Generated Code”>



    window.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);



    jLabel1.setText(“Welcome to Doggy UI v1.0 Alpha”);



    jLabel2.setText(“Created by”);



    jLabel3.setText(“Dr. David Roberts”);



    jLabel4.setText(“David Crook”);



    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);

    jPanel1.setLayout(jPanel1Layout);

    jPanel1Layout.setHorizontalGroup(

    jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGroup(jPanel1Layout.createSequentialGroup()

    .addContainerGap()

    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addComponent(jLabel1)

    .addComponent(jLabel4)

    .addComponent(jLabel3)

    .addComponent(jLabel2))

    .addContainerGap(206, Short.MAX_VALUE))

    );

    jPanel1Layout.setVerticalGroup(

    jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGroup(jPanel1Layout.createSequentialGroup()

    .addContainerGap()

    .addComponent(jLabel1)

    .addGap(18, 18, 18)

    .addComponent(jLabel2)

    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

    .addComponent(jLabel3)

    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

    .addComponent(jLabel4)

    .addContainerGap(154, Short.MAX_VALUE))

    );



    jTabbedPane1.addTab(“Doggy UI”, jPanel1);



    jButton1.setText(“Start Server”);



    jButton2.setText(“Stop Server”);



    javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);

    jPanel3.setLayout(jPanel3Layout);

    jPanel3Layout.setHorizontalGroup(

    jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGap(0, 258, Short.MAX_VALUE)

    );

    jPanel3Layout.setVerticalGroup(

    jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGap(0, 200, Short.MAX_VALUE)

    );



    jButton3.setText(“Sit”);



    javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);

    jPanel2.setLayout(jPanel2Layout);

    jPanel2Layout.setHorizontalGroup(

    jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGroup(jPanel2Layout.createSequentialGroup()

    .addContainerGap()

    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addComponent(jButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 78, javax.swing.GroupLayout.PREFERRED_SIZE)

    .addGroup(jPanel2Layout.createSequentialGroup()

    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addComponent(jButton1)

    .addComponent(jButton2))

    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

    .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))

    .addContainerGap())

    );

    jPanel2Layout.setVerticalGroup(

    jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGroup(jPanel2Layout.createSequentialGroup()

    .addContainerGap()

    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

    .addGroup(jPanel2Layout.createSequentialGroup()

    .addComponent(jButton1)

    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

    .addComponent(jButton2)))

    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)

    .addComponent(jButton3)

    .addContainerGap())

    );



    jTabbedPane1.addTab(“Data Collection”, jPanel2);



    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(window.getContentPane());

    window.getContentPane().setLayout(layout);

    layout.setHorizontalGroup(

    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGroup(layout.createSequentialGroup()

    .addContainerGap()

    .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)

    .addContainerGap())

    );

    layout.setVerticalGroup(

    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGroup(layout.createSequentialGroup()

    .addContainerGap()

    .addComponent(jTabbedPane1)

    .addContainerGap())

    );



    window.pack();

    }// </editor-fold>



    public void simpleInitApp()

    {

    //ensure input doesn’t get mapped to canvas.

    flyCam.setDragToRotate(true);



    }





    private javax.swing.JButton jButton1;

    private javax.swing.JButton jButton2;

    private javax.swing.JButton jButton3;

    private javax.swing.JLabel jLabel1;

    private javax.swing.JLabel jLabel2;

    private javax.swing.JLabel jLabel3;

    private javax.swing.JLabel jLabel4;

    private javax.swing.JPanel jPanel1;

    private javax.swing.JPanel jPanel2;

    private javax.swing.JPanel jPanel3;

    private javax.swing.JTabbedPane jTabbedPane1;

    private javax.swing.JFrame window;



    }







    [/java]

gah, forgot to include the line of code:



window.setVisible(true);

So the GUI is showing up now, however Panel3 under the Data Collection Tab is not displaying the canvas.



The code looks exactly as before except the line I mentioned is added to the end of the initComponents method.



Thanks for tips,

~David

NetBeans uses GroupLayout for its GUI editor, this layout is not compatible with the add() method, you have to create groups through GroupLayout.create***Group() methods and add components to them.

See this page:

http://download.oracle.com/javase/tutorial/uiswing/layout/group.html



However you don’t need to do that, because NetBeans GUI editor allows you to specify custom initialization code.

Go to the properties tab → Code → Custom Creation Code, and type ctx.getCanvas() in there.

Im not entirely sure I am fully understanding what you are saying.

I tried adding ctx.getCanvas() to the initialization code specified (within the jPanel3 properties window), however it is giving me an incompatible type error, it seems all it did was change the jPanel3 initialization code to:

jPanel3 = ctx.getCanvas();

instead of me manually making it:

jPanel3 = new jPanel();

jPanel3.add(ctx.getCanvas());

ctx.getCanvas() returns a type canvas. Is canvas a type of component, where I can do:

[java]

jPanel3 = new jPanel()



//This section of code is cut out, but you can reference above for where this snippit belongs…within jPanel2, I am proposing

//to change the generated code to add the component



jPanel3.setLayout(jPanel3Layout);

jPanel3Layout.setHorizontalGroup(

jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGap(0, 258, Short.MAX_VALUE)

.addComponent(ctx.getCanvas()) //THIS NEW LINE!!!

);

jPanel3Layout.setVerticalGroup(

jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

.addGap(0, 200, Short.MAX_VALUE)

);

[/java]

If not, can you further explain what jPanel is needing, or what sort of layout I need to use? My project is due friday for school :confused: pass or fail.

Thanks for any help, it is VERY MUCH appreciated!

~David

Just read the part where I explain how to do it with the NetBeans GUI editor



Make sure you select an AWT canvas from the toolbox because the jME canvas is not a JPanel

thats exactly what I did, and this is the result, where line 72 is an error:



This is a link to a picture of a screen shot of where in the editor I made the change to creation code:

http://s1121.photobucket.com/albums/l509/drcrook/?action=view&current=netbeans_GUI.png

[java]

/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.

    */

    package doggyui_swingv2;

    import com.jme3.system.AppSettings;

    import com.jme3.system.JmeCanvasContext;

    import java.awt.Dimension;

    import javax.swing.JFrame;

    /**

    *
  • @author David

    */

    public class Main extends com.jme3.app.SimpleApplication

    {

    public Main()

    {

    }

    static JmeCanvasContext ctx;

    /**
  • @param args the command line arguments

    /

    public static void main(String[] args)

    {

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

    {

    public void run()

    {

    AppSettings settings = new AppSettings(true);

    settings.setWidth(640);

    settings.setHeight(480);

    Main canvasApplication = new Main();

    canvasApplication.setSettings(settings);

    canvasApplication.createCanvas(); // create canvas!

    ctx = (JmeCanvasContext) canvasApplication.getContext();

    ctx.setSystemListener(canvasApplication);

    Dimension dim = new Dimension(640, 480);

    ctx.getCanvas().setPreferredSize(dim);

    canvasApplication.initComponents();

    canvasApplication.startCanvas();

    }

    });

    }

    /
    * This method is called from within the constructor to
  • initialize the form.

    */

    private void initComponents() {

    jTabbedPane1 = new javax.swing.JTabbedPane();

    jPanel1 = new javax.swing.JPanel();

    jLabel1 = new javax.swing.JLabel();

    jLabel2 = new javax.swing.JLabel();

    jLabel3 = new javax.swing.JLabel();

    jLabel4 = new javax.swing.JLabel();

    jPanel2 = new javax.swing.JPanel();

    jButton1 = new javax.swing.JButton();

    jButton2 = new javax.swing.JButton();

    jPanel3 = ctx.getCanvas();

    jButton3 = new javax.swing.JButton();

    window.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jLabel1.setText(“Welcome to Doggy UI v1.0 Alpha”);

    jLabel2.setText(“Created by”);

    jLabel3.setText(“Dr. David Roberts”);

    jLabel4.setText(“David Crook”);

    javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);

    jPanel1.setLayout(jPanel1Layout);

    jPanel1Layout.setHorizontalGroup(

    jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGroup(jPanel1Layout.createSequentialGroup()

    .addContainerGap()

    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addComponent(jLabel1)

    .addComponent(jLabel4)

    .addComponent(jLabel3)

    .addComponent(jLabel2))

    .addContainerGap(206, Short.MAX_VALUE))

    );

    jPanel1Layout.setVerticalGroup(

    jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGroup(jPanel1Layout.createSequentialGroup()

    .addContainerGap()

    .addComponent(jLabel1)

    .addGap(18, 18, 18)

    .addComponent(jLabel2)

    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

    .addComponent(jLabel3)

    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

    .addComponent(jLabel4)

    .addContainerGap(154, Short.MAX_VALUE))

    );

    jTabbedPane1.addTab(“Doggy UI”, jPanel1);

    jButton1.setText(“Start Server”);

    jButton2.setText(“Stop Server”);

    javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);

    jPanel3.setLayout(jPanel3Layout);

    jPanel3Layout.setHorizontalGroup(

    jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGap(0, 258, Short.MAX_VALUE)

    );

    jPanel3Layout.setVerticalGroup(

    jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGap(0, 200, Short.MAX_VALUE)

    );

    jButton3.setText(“Sit”);

    javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);

    jPanel2.setLayout(jPanel2Layout);

    jPanel2Layout.setHorizontalGroup(

    jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGroup(jPanel2Layout.createSequentialGroup()

    .addContainerGap()

    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addComponent(jButton3, javax.swing.GroupLayout.PREFERRED_SIZE, 78, javax.swing.GroupLayout.PREFERRED_SIZE)

    .addGroup(jPanel2Layout.createSequentialGroup()

    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addComponent(jButton1)

    .addComponent(jButton2))

    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

    .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))

    .addContainerGap())

    );

    jPanel2Layout.setVerticalGroup(

    jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGroup(jPanel2Layout.createSequentialGroup()

    .addContainerGap()

    .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)

    .addGroup(jPanel2Layout.createSequentialGroup()

    .addComponent(jButton1)

    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)

    .addComponent(jButton2)))

    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)

    .addComponent(jButton3)

    .addContainerGap())

    );

    jTabbedPane1.addTab(“Data Collection”, jPanel2);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(window.getContentPane());

    window.getContentPane().setLayout(layout);

    layout.setHorizontalGroup(

    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGroup(layout.createSequentialGroup()

    .addContainerGap()

    .addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 380, Short.MAX_VALUE)

    .addContainerGap())

    );

    layout.setVerticalGroup(

    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)

    .addGroup(layout.createSequentialGroup()

    .addContainerGap()

    .addComponent(jTabbedPane1)

    .addContainerGap())

    );

    window.pack();

    window.setVisible(true);

    }// </editor-fold>

    public void simpleInitApp()

    {

    //ensure input doesn’t get mapped to canvas.

    flyCam.setDragToRotate(true);

    }

    private javax.swing.JButton jButton1;

    private javax.swing.JButton jButton2;

    private javax.swing.JButton jButton3;

    private javax.swing.JLabel jLabel1;

    private javax.swing.JLabel jLabel2;

    private javax.swing.JLabel jLabel3;

    private javax.swing.JLabel jLabel4;

    private javax.swing.JPanel jPanel1;

    private javax.swing.JPanel jPanel2;

    private javax.swing.JPanel jPanel3;

    private javax.swing.JTabbedPane jTabbedPane1;

    private javax.swing.JFrame window;

    }

    [/java]

My laptop died right when I was adding the picture, so here is exatly where in the netbeans gui I made the change. (circled in red)

Please let me know if that is infact the incorrect place.

Link to image


Thanks,

~David