FengGUI - Widgets, window titles, and window buttons not appearing

I posted this on the FengGUI forums, but so far have not found a solution, so I was wondering if any of you jME FengGUI users had any suggestions:


I just wanted a small example to see how FengGUI works - so I pieced together a bit of code using examples from the wiki, and from the jME wiki.  All of the widgets, window titles, and window buttons are not rendered.  They appear to be there, I can click them (the close/minimize/maximize buttons work), but I cannot see them.

Here is a screen shot:
http://www.tsourceweb.com/files/fenggui_error.png

I am on ubuntu, and compiled the latest version of the code from the svn.

Here is my test code:

import org.fenggui.ComboBox;
import org.fenggui.TextEditor;
import org.fenggui.composite.TextArea;
import org.fenggui.event.ISelectionChangedListener;
import org.fenggui.event.SelectionChangedEvent;
import org.fenggui.layout.StaticLayout;

import com.jme.app.BaseGame;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.light.PointLight;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jme.scene.state.LightState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.util.Timer;
import com.jme.util.lwjgl.LWJGLTimer;

import org.fenggui.Button;
import org.fenggui.CheckBox;
import org.fenggui.Container;
//import org.fenggui.Display;
import org.fenggui.FengGUI;
import org.fenggui.Label;
import org.fenggui.RadioButton;
import org.fenggui.ToggableGroup;
import org.fenggui.composite.Window;
import org.fenggui.event.ButtonPressedEvent;
import org.fenggui.event.IButtonPressedListener;
import org.fenggui.layout.RowLayout;
import org.fenggui.util.Point;
import org.fenggui.util.Spacing;


/**
 * FengJME - A test class for integrating FengGUI and jME.
 *
 * @author Josh (updated by neebie)
 *
 */
public class FengJME extends BaseGame
{
   Camera cam; // Camera for jME
   Node rootNode; // The root node for the jME scene
   PointLight light; // Changeable light
   FengJMEInputHandler input;
   Timer timer;

   Box box; // A box

   org.fenggui.Display disp; // FengGUI's display


   /* (non-Javadoc)
    * @see com.jme.app.BaseGame#cleanup()
    */
   @Override
   protected void cleanup()
   {
      // Clean up the mouse
      MouseInput.get().removeListeners();
      MouseInput.destroyIfInitalized();
      // Clean up the keyboard
      KeyInput.destroyIfInitalized();
   }


   /* (non-Javadoc)
    * @see com.jme.app.BaseGame#initGame()
    */
   @Override
   protected void initGame()
   {
      // Create our root node
      rootNode = new Node("rootNode");
      // Going to enable z-buffering
      ZBufferState buf = display.getRenderer().createZBufferState();
      buf.setEnabled(true);
      buf.setFunction(ZBufferState.CF_LEQUAL);
      // ... and set the z-buffer on our root node
      rootNode.setRenderState(buf);

      // Create a white light and enable it
      light = new PointLight();
      light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
      light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
      light.setLocation(new Vector3f(100, 100, 100));
      light.setEnabled(true);
      /** Attach the light to a lightState and the lightState to rootNode. */
      LightState lightState = display.getRenderer().createLightState();
      lightState.setEnabled(true);
      lightState.attach(light);
      rootNode.setRenderState(lightState);

      // Create our box
      box = new Box("The Box", new Vector3f(-1, -1, -1), new Vector3f(1, 1, 1));
      box.updateRenderState();
      // Rotate the box 25 degrees along the x and y axes.
      Quaternion rot = new Quaternion();
      rot.fromAngles(FastMath.DEG_TO_RAD * 25, FastMath.DEG_TO_RAD * 25, 0.0f);
      box.setLocalRotation(rot);
      // Attach the box to the root node
      rootNode.attachChild(box);

      // Update our root node
      rootNode.updateGeometricState(0.0f, true);
      rootNode.updateRenderState();

      // Create the GUI
      initGUI();
   }


   /**
    * Create our GUI.  FengGUI init code goes in here
    *
    */
   protected void initGUI()
   {
      // Grab a display using an LWJGL binding
      //      (obviously, since jME uses LWJGL)
      disp = new org.fenggui.Display(new org.fenggui.binding.render.lwjgl.LWJGLBinding());
      disp.setDepthTestEnabled(true);

      input = new FengJMEInputHandler(disp);

      Window crazy = FengGUI.createWindow(disp, true, true, true, true);
      crazy.setTitle("thatscrazy");
      crazy.pack();

      Window window = FengGUI.createWindow(disp, true, false, false, true);
      window.setTitle("hot drinks");
      window.setPosition(new Point(50,200));
      window.getContentContainer().setLayoutManager(new RowLayout(false));
      window.getContentContainer().getAppearance().setPadding(new Spacing(10, 10));

      final ToggableGroup<String> toggableGroup = new ToggableGroup<String>();
      RadioButton<String> radioButtonCoffee = new RadioButton<String>("coffee", toggableGroup, "coffee");
      RadioButton<String> radioButtonTea = new RadioButton<String>("tea", toggableGroup, "tea");
      radioButtonTea.setSelected(true);

      Container container = new Container(new RowLayout(true));
      container.addWidget(radioButtonCoffee);
      container.addWidget(radioButtonTea);
      window.getContentContainer().addWidget(container);

      final CheckBox<String> checkBoxMilk = new CheckBox<String>("milk");
      final CheckBox<String> checkBoxSugar = new CheckBox<String>("sugar");
      window.getContentContainer().addWidget(checkBoxMilk);
      window.getContentContainer().addWidget(checkBoxSugar);

      final Label label = new Label("---");
      final Window dialog = FengGUI.createWindow(disp, true, false, false, true);
      dialog.setTitle("you ordered:");
      dialog.setPosition(new Point(250,250));
      dialog.getContentContainer().addWidget(label);
      dialog.pack();

      Button button = new Button("submit your order");
      button.addButtonPressedListener(new IButtonPressedListener() {
         public void buttonPressed(ButtonPressedEvent arg0) {

            String temp = toggableGroup.getSelectedValue();
            if (checkBoxMilk.isSelected()) {
               if (checkBoxSugar.isSelected())
                  temp += " with milk and sugar.";
               else
                  temp += " with milk.";
            }
            else
               if (checkBoxSugar.isSelected())
                  temp += " with sugar.";

            label.setText(temp);
            dialog.pack();
         }
      });

      window.getContentContainer().addWidget(button);
      window.pack();
      // Update the display with the newly added components
      disp.layout();
   }


   /* (non-Javadoc)
    * @see com.jme.app.BaseGame#initSystem()
    */
   @Override
   protected void initSystem()
   {
      try
      {
         // Initialize our jME display system
         display = DisplaySystem.getDisplaySystem(properties.getRenderer());
         display.createWindow(properties.getWidth(), properties.getHeight(), properties.getDepth(), properties
               .getFreq(), properties.getFullscreen());

         // Get a camera based on the window settings
         cam = display.getRenderer().createCamera(display.getWidth(), display.getHeight());
      }
      catch (JmeException ex)
      {
         ex.printStackTrace();
         System.exit(1);
      }

      /** Set a black background.*/
      display.getRenderer().setBackgroundColor(ColorRGBA.black);
      /** Set up how our camera sees. */
      cam.setFrustumPerspective(45.0f, (float) display.getWidth() / (float) display.getHeight(), 1, 1000);
      Vector3f loc = new Vector3f(0.0f, 0.0f, 15.0f);
      Vector3f left = new Vector3f(-1.0f, 0.0f, 0.0f);
      Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
      Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);
      /** Move our camera to a correct place and orientation. */
      cam.setFrame(loc, left, up, dir);
      /** Signal that we've changed our camera's location/frustum. */
      cam.update();
      /** Assign the camera to this renderer.*/
      display.getRenderer().setCamera(cam);

      // We want a cursor to interact with FengGUI
      MouseInput.get().setCursorVisible(true);

      // Bind the Escape key to kill our test app
      KeyBindingManager.getKeyBindingManager().set("quit", KeyInput.KEY_ESCAPE);

      // Create our timer
      timer = new LWJGLTimer();
   }


   /* (non-Javadoc)
    * @see com.jme.app.BaseGame#reinit()
    */
   @Override
   protected void reinit()
   {
      // TODO Auto-generated method stub

   }


   /* (non-Javadoc)
    * @see com.jme.app.BaseGame#render(float)
    */
   @Override
   protected void render(float interpolation)
   {
      // First we draw our jME scene.  This must be called before
      //   anything will even show up.
      //   FIXME: This throws a NullPointerException when the app exits.
      //          Must investigate why.
      display.getRenderer().clearBuffers();

      // We could draw the GUI here, but I find it cleaner to just do
      //    all the jME engine calls together.
      display.getRenderer().draw(rootNode);

      // Then we display the GUI
      disp.display();
   }


   /* (non-Javadoc)
    * @see com.jme.app.BaseGame#update(float)
    */
   @Override
   protected void update(float interpolation)
   {
      timer.update();
      float tpf = timer.getTimePerFrame();
      input.update(tpf);
      if (!input.wasKeyHandled())
      {
         // Check to see if Escape was pressed
         if (KeyBindingManager.getKeyBindingManager().isValidCommand("quit")) finish();
      }
   }


   /**
    * @param args
    */
   public static void main(String[] args)
   {
      FengJME app = new FengJME();
      app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG);
      app.start();
   }
}



All the relevant code is in the initGUI() function.  The FengJMEInputHandler is definitely not the problem - I removed that section of the code and still got the same rendering issues.  Any help would be greatly appreciated.


On the suggestion of one of the FengGUI guys I also tried changing disp.setDepthTestEnabled(true); to false instead, but that did not change the results.

I can also reproduce the same results on an XP machine.

If no one has an answer - maybe someone could post a small (working) jME FengGUI sample that I can run and use process of elimination to figure out what's causing the issue.



After reading through the GUI descriptions it seemed like FengGUI was the best as far as cross platform and being most actively developed, that's why I chose it, but it's kind of a dealbreaker if I can't even get the widgets to show up! ::grin::

in the wiki are two FengGUI examples

http://www.jmonkeyengine.com/wiki/doku.php?id=integrating_fenggui_with_jme

try to set default renderstates before drawing FengGUI:


for (RenderState rs: Renderer.defaultStateList){
    rs.apply();
}

No change adding that before and/or after my initGUI() call…

mhh not in the init, try to add it before the disp.display(); call in the render() method

Still no change, here's the other file in case you want to compile and play with the app:


import org.fenggui.Display;
import org.fenggui.event.key.Key;
import org.fenggui.event.mouse.MouseButton;
import org.lwjgl.input.Keyboard;
 
import com.jme.input.InputHandler;
import com.jme.input.MouseInput;
import com.jme.input.MouseInputListener;
import com.jme.input.action.InputActionEvent;
import com.jme.input.action.KeyInputAction;
 
/**
 * FengJMEInputHandler
 *
 * @author Joshua Keplinger
 *
 */
public class FengJMEInputHandler extends InputHandler
{
   
   private Display disp;
   private KeyInputAction keyAction;
   
   private boolean keyHandled;
   private boolean mouseHandled;
   
   public FengJMEInputHandler(Display disp)
   {
      this.disp = disp;
      
      keyAction = new KeyAction();
      addAction(keyAction, DEVICE_KEYBOARD, BUTTON_ALL, AXIS_NONE, false);
      
      MouseInput.get().addListener(new MouseListener());
   }
   
   public void update(float time)
   {
      keyHandled = false;
      mouseHandled = false;
      super.update(time);
   }
   
   public boolean wasKeyHandled()
   {
      return keyHandled;
   }
   
   public boolean wasMouseHandled()
   {
      return mouseHandled;
   }
   
   private class KeyAction extends KeyInputAction
   {
      
      public void performAction(InputActionEvent evt)
      {
         char character = evt.getTriggerCharacter();
         Key key = mapKeyEvent();
         if(evt.getTriggerPressed()) {
            keyHandled = disp.fireKeyPressedEvent(character, key);
            // Bug workaround see note after code
            if (key == Key.LETTER || key == Key.DIGIT)
               keyHandled = disp.fireKeyTypedEvent(character);
         } else
            keyHandled = disp.fireKeyReleasedEvent(character, key);
      }
      
      /**
       * Helper method that maps LWJGL key events to FengGUI.
       * @return The Key enumeration of the last key pressed.
       */
      private Key mapKeyEvent()
      {
         Key keyClass;
         
           switch(Keyboard.getEventKey())
           {
              case Keyboard.KEY_BACK:
                 keyClass = Key.BACKSPACE;
                  break;
              case Keyboard.KEY_RETURN:
                 keyClass = Key.ENTER;
                  break;
              case Keyboard.KEY_DELETE:
                 keyClass = Key.DELETE;
                  break;
              case Keyboard.KEY_UP:
                 keyClass = Key.UP;
                 break;
              case Keyboard.KEY_RIGHT:
                 keyClass = Key.RIGHT;
                  break;
              case Keyboard.KEY_LEFT:
                 keyClass = Key.LEFT;
                  break;
              case Keyboard.KEY_DOWN:
                 keyClass = Key.DOWN;
                  break;
              case Keyboard.KEY_SCROLL:
                 keyClass = Key.SHIFT;
                  break;
              case Keyboard.KEY_LMENU:
                 keyClass = Key.ALT;
                  break;
              case Keyboard.KEY_RMENU:
                 keyClass = Key.ALT;
                  break;
              case Keyboard.KEY_LCONTROL:
                 keyClass = Key.CTRL;
                  break;
              case Keyboard.KEY_RSHIFT:
                 keyClass = Key.SHIFT;
                  break;    
              case Keyboard.KEY_LSHIFT:
                 keyClass = Key.SHIFT;
                  break;             
              case Keyboard.KEY_RCONTROL:
                 keyClass = Key.CTRL;
                  break;
              case Keyboard.KEY_INSERT:
                 keyClass = Key.INSERT;
                  break;
              case Keyboard.KEY_F12:
                 keyClass = Key.F12;
                  break;
              case Keyboard.KEY_F11:
                 keyClass = Key.F11;
                  break;
              case Keyboard.KEY_F10:
                 keyClass = Key.F10;
                  break;
              case Keyboard.KEY_F9:
                 keyClass = Key.F9;
                  break;
              case Keyboard.KEY_F8:
                 keyClass = Key.F8;
                  break;
              case Keyboard.KEY_F7:
                 keyClass = Key.F7;
                  break;
              case Keyboard.KEY_F6:
                 keyClass = Key.F6;
                  break;
              case Keyboard.KEY_F5:
                 keyClass = Key.F5;
                  break;
              case Keyboard.KEY_F4:
                 keyClass = Key.F4;
                  break;
              case Keyboard.KEY_F3:
                 keyClass = Key.F3;
                  break;
              case Keyboard.KEY_F2:
                 keyClass = Key.F2;
                  break;
              case Keyboard.KEY_F1:
                 keyClass = Key.F1;
                  break;
              default:
                 if("1234567890".indexOf(Keyboard.getEventCharacter()) != -1) {
                    keyClass = Key.DIGIT;
                 } else {
                    // @todo must not necessarily be a letter!! #
                    keyClass = Key.LETTER;
                 }
                 break;
          }
         
           return keyClass;
      }
      
   }
   
   private class MouseListener implements MouseInputListener
   {
      
      private boolean down;
      private int lastButton;
      
      public void onButton(int button, boolean pressed, int x, int y)
      {
         down = pressed;
         lastButton = button;
         if(pressed)
            mouseHandled = disp.fireMousePressedEvent(x, y, getMouseButton(button), 1);
         else
            mouseHandled = disp.fireMouseReleasedEvent(x, y, getMouseButton(button), 1);
      }
 
      public void onMove(int xDelta, int yDelta, int newX, int newY)
      {
         // If the button is down, the mouse is being dragged
         if(down)
            mouseHandled = disp.fireMouseDraggedEvent(newX, newY, getMouseButton(lastButton), 0);
         else
            mouseHandled = disp.fireMouseMovedEvent(newX, newY, null, 0);
      }
 
      public void onWheel(int wheelDelta, int x, int y)
      {
         // wheelDelta is positive if the mouse wheel rolls up
                        if(wheelDelta > 0)
                      mouseHandled = disp.fireMouseWheel(x, y, true, wheelDelta, 1);
                        else
                                mouseHandled = disp.fireMouseWheel(x, y, false, wheelDelta, 1);
 
                        // note (johannes): wheeling code not tested on jME, please report problems on www.fenggui.org/forum/
      }
      
      /**
       * Helper method that maps the mouse button to the equivalent
       * FengGUI MouseButton enumeration.
       * @param button The button pressed or released.
       * @return The FengGUI MouseButton enumeration matching the
       * button.
       */
      private MouseButton getMouseButton(int button)
      {
         switch(button)
         {
            case 0:
               return MouseButton.LEFT;
            case 1:
               return MouseButton.RIGHT;
            case 2:
               return MouseButton.MIDDLE;
            default:
               return MouseButton.LEFT;
         }
      }
      
   }
   
}



Yeah I know, the wiki is way outdated apparently, that was the first place I looked - they didn't compile properly with the current FengGUI version.  I merged one of those examples with part of an example from the FengGUI wiki to get the mess I have now. (since their examples work, but are meant for JOGL)

This works for me (once I re-worked the imports)



FengJme.java


import com.jme.app.BaseGame;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.light.PointLight;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jme.scene.state.LightState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.util.Timer;
import com.jme.util.lwjgl.LWJGLTimer;
import org.fenggui.Button;
import org.fenggui.CheckBox;
import org.fenggui.Container;
import org.fenggui.FengGUI;
import org.fenggui.Label;
import org.fenggui.RadioButton;
import org.fenggui.ToggableGroup;
import org.fenggui.composites.Window;
import org.fenggui.event.ButtonPressedEvent;
import org.fenggui.event.IButtonPressedListener;
import org.fenggui.layout.RowLayout;
import org.fenggui.render.lwjgl.LWJGLBinding;
import org.fenggui.util.Point;
import org.fenggui.util.Spacing;





/**
 * FengJME - A test class for integrating FengGUI and jME.
 *
 * @author Josh (updated by neebie)
 *
 */
public class FengJME extends BaseGame {

    Camera cam; // Camera for jME
    Node rootNode; // The root node for the jME scene
    PointLight light; // Changeable light
    FengInputHandler input;
    Timer timer;
    Box box; // A box
    org.fenggui.Display disp; // FengGUI's display


    /* (non-Javadoc)
     * @see com.jme.app.BaseGame#cleanup()
     */
    @Override
    protected void cleanup() {
        // Clean up the mouse
        MouseInput.get().removeListeners();
        MouseInput.destroyIfInitalized();
        // Clean up the keyboard
        KeyInput.destroyIfInitalized();
    }


    /* (non-Javadoc)
     * @see com.jme.app.BaseGame#initGame()
     */
    @Override
    protected void initGame() {
        // Create our root node
        rootNode = new Node( "rootNode" );
        // Going to enable z-buffering
        ZBufferState buf = display.getRenderer().createZBufferState();
        buf.setEnabled( true );
        buf.setFunction( ZBufferState.CF_LEQUAL );
        // ... and set the z-buffer on our root node
        rootNode.setRenderState( buf );

        // Create a white light and enable it
        light = new PointLight();
        light.setDiffuse( new ColorRGBA( 1.0f, 1.0f, 1.0f, 1.0f ) );
        light.setAmbient( new ColorRGBA( 0.5f, 0.5f, 0.5f, 1.0f ) );
        light.setLocation( new Vector3f( 100, 100, 100 ) );
        light.setEnabled( true );
        /** Attach the light to a lightState and the lightState to rootNode. */
        LightState lightState = display.getRenderer().createLightState();
        lightState.setEnabled( true );
        lightState.attach( light );
        rootNode.setRenderState( lightState );

        // Create our box
        box = new Box( "The Box", new Vector3f( -1, -1, -1 ), new Vector3f( 1, 1, 1 ) );
        box.updateRenderState();
        // Rotate the box 25 degrees along the x and y axes.
        Quaternion rot = new Quaternion();
        rot.fromAngles( FastMath.DEG_TO_RAD * 25, FastMath.DEG_TO_RAD * 25, 0.0f );
        box.setLocalRotation( rot );
        // Attach the box to the root node
        rootNode.attachChild( box );

        // Update our root node
        rootNode.updateGeometricState( 0.0f, true );
        rootNode.updateRenderState();

        // Create the GUI
        initGUI();
    }

    /**
     * Create our GUI.  FengGUI init code goes in here
     *
     */
    protected void initGUI() {
        // Grab a display using an LWJGL binding
        //      (obviously, since jME uses LWJGL)
        disp = new org.fenggui.Display( new LWJGLBinding() );
        disp.setDepthTestEnabled( true );

        input = new FengInputHandler( disp );

        Window crazy = FengGUI.createWindow( disp, true, true, true, true );
        crazy.setTitle( "thatscrazy" );
        crazy.pack();

        Window window = FengGUI.createWindow( disp, true, false, false, true );
        window.setTitle( "hot drinks" );
        window.setPosition( new Point( 50, 200 ) );
        window.getContentContainer().setLayoutManager( new RowLayout( false ) );
        window.getContentContainer().getAppearance().setPadding( new Spacing( 10, 10 ) );

        final ToggableGroup<String> toggableGroup = new ToggableGroup<String>();
        RadioButton<String> radioButtonCoffee = new RadioButton<String>( "coffee", toggableGroup, "coffee" );
        RadioButton<String> radioButtonTea = new RadioButton<String>( "tea", toggableGroup, "tea" );
        radioButtonTea.setSelected( true );

        Container container = new Container( new RowLayout( true ) );
        container.addWidget( radioButtonCoffee );
        container.addWidget( radioButtonTea );
        window.getContentContainer().addWidget( container );

        final CheckBox<String> checkBoxMilk = new CheckBox<String>( "milk" );
        final CheckBox<String> checkBoxSugar = new CheckBox<String>( "sugar" );
        window.getContentContainer().addWidget( checkBoxMilk );
        window.getContentContainer().addWidget( checkBoxSugar );

        final Label label = new Label( "---" );
        final Window dialog = FengGUI.createWindow( disp, true, false, false, true );
        dialog.setTitle( "you ordered:" );
        dialog.setPosition( new Point( 250, 250 ) );
        dialog.getContentContainer().addWidget( label );
        dialog.pack();

        Button button = new Button( "submit your order" );
        button.addButtonPressedListener( new IButtonPressedListener() {

            public void buttonPressed( ButtonPressedEvent arg0 ) {

                String temp = toggableGroup.getSelectedValue();
                if( checkBoxMilk.isSelected() ){
                    if( checkBoxSugar.isSelected() ){
                        temp += " with milk and sugar.";
                    } else{
                        temp += " with milk.";
                    }
                } else if( checkBoxSugar.isSelected() ){
                    temp += " with sugar.";
                }

                label.setText( temp );
                dialog.pack();
            }
        } );

        window.getContentContainer().addWidget( button );
        window.pack();
        // Update the display with the newly added components
        disp.layout();
    }


    /* (non-Javadoc)
     * @see com.jme.app.BaseGame#initSystem()
     */
    @Override
    protected void initSystem() {
        try{
            // Initialize our jME display system
            display = DisplaySystem.getDisplaySystem( properties.getRenderer() );
            display.createWindow( properties.getWidth(), properties.getHeight(), properties.getDepth(), properties.getFreq(), properties.getFullscreen() );

            // Get a camera based on the window settings
            cam = display.getRenderer().createCamera( display.getWidth(), display.getHeight() );
        } catch( JmeException ex ){
            ex.printStackTrace();
            System.exit( 1 );
        }

        /** Set a black background.*/
        display.getRenderer().setBackgroundColor( ColorRGBA.black );
        /** Set up how our camera sees. */
        cam.setFrustumPerspective( 45.0f, (float) display.getWidth() / (float) display.getHeight(), 1, 1000 );
        Vector3f loc = new Vector3f( 0.0f, 0.0f, 15.0f );
        Vector3f left = new Vector3f( -1.0f, 0.0f, 0.0f );
        Vector3f up = new Vector3f( 0.0f, 1.0f, 0.0f );
        Vector3f dir = new Vector3f( 0.0f, 0f, -1.0f );
        /** Move our camera to a correct place and orientation. */
        cam.setFrame( loc, left, up, dir );
        /** Signal that we've changed our camera's location/frustum. */
        cam.update();
        /** Assign the camera to this renderer.*/
        display.getRenderer().setCamera( cam );

        // We want a cursor to interact with FengGUI
        MouseInput.get().setCursorVisible( true );

        // Bind the Escape key to kill our test app
        KeyBindingManager.getKeyBindingManager().set( "quit", KeyInput.KEY_ESCAPE );

        // Create our timer
        timer = new LWJGLTimer();
    }


    /* (non-Javadoc)
     * @see com.jme.app.BaseGame#reinit()
     */
    @Override
    protected void reinit() {
    // TODO Auto-generated method stub

    }


    /* (non-Javadoc)
     * @see com.jme.app.BaseGame#render(float)
     */
    @Override
    protected void render( float interpolation ) {
        // First we draw our jME scene.  This must be called before
        //   anything will even show up.
        //   FIXME: This throws a NullPointerException when the app exits.
        //          Must investigate why.
        display.getRenderer().clearBuffers();

        // We could draw the GUI here, but I find it cleaner to just do
        //    all the jME engine calls together.
        display.getRenderer().draw( rootNode );

        // Then we display the GUI
        disp.display();
    }


    /* (non-Javadoc)
     * @see com.jme.app.BaseGame#update(float)
     */
    @Override
    protected void update( float interpolation ) {
        timer.update();
        float tpf = timer.getTimePerFrame();
        input.update( tpf );
        if( !input.wasKeyHandled() ){
            // Check to see if Escape was pressed
            if( KeyBindingManager.getKeyBindingManager().isValidCommand( "quit" ) ){
                finish();
            }
        }
    }

    /**
     * @param args
     */
    public static void main( String[] args ) {
        FengJME app = new FengJME();
        app.setDialogBehaviour( ALWAYS_SHOW_PROPS_DIALOG );
        app.start();
    }
}



FengInputHandler.java



import com.jme.input.InputHandler;
import com.jme.input.MouseInput;
import com.jme.input.MouseInputListener;
import com.jme.input.action.InputActionEvent;
import com.jme.input.action.KeyInputAction;


import org.fenggui.Display;
import org.fenggui.event.Key;
import org.fenggui.event.mouse.MouseButton;
import org.lwjgl.input.Keyboard;



public class FengInputHandler extends InputHandler {

    private Display disp;
    private KeyInputAction keyAction;
    private boolean keyHandled,  mouseHandled,  mouseOverGui;

    public FengInputHandler( Display disp ) {
        this.disp = disp;

        keyAction = new KeyAction();
        addAction( keyAction, DEVICE_KEYBOARD, BUTTON_ALL, AXIS_NONE, false );

        MouseInput.get().addListener( new MouseListener() );
    }

    @Override
    public void update( float time ) {
        reset();
        super.update( time );
    }

    public boolean wasKeyHandled() {
        return keyHandled;
    }

    public boolean wasMouseHandled() {
        return mouseHandled;
    }

    public boolean isMouseOverGui() {
        return mouseOverGui;
    }

    public void setMouseOverGui( boolean mouseOver ) {
        mouseOverGui = mouseOver;
    }

    public void reset() {
        keyHandled = false;
        mouseHandled = false;
    }



    private class KeyAction extends KeyInputAction {

        public void performAction( InputActionEvent evt ) {
            char character = evt.getTriggerCharacter();
            Key key = mapKeyEvent();
            if( evt.getTriggerPressed() ){
                keyHandled = disp.fireKeyPressedEvent( character, key );

                // Bug workaround see note after code
                if( key == Key.LETTER || key == Key.DIGIT ){
                    keyHandled = disp.fireKeyTypedEvent( character );
                }
            } else{
                keyHandled = disp.fireKeyReleasedEvent( character, key );
            }
        }

        /**
         * Helper method that maps LWJGL key events to FengGUI.
         * @return The Key enumeration of the last key pressed.
         */
        private Key mapKeyEvent() {
            Key keyClass;

            switch( Keyboard.getEventKey() ){
                case Keyboard.KEY_BACK:
                    keyClass = Key.BACKSPACE;
                    break;
                case Keyboard.KEY_RETURN:
                    keyClass = Key.ENTER;
                    break;
                case Keyboard.KEY_DELETE:
                    keyClass = Key.DELETE;
                    break;
                case Keyboard.KEY_UP:
                    keyClass = Key.UP;
                    break;
                case Keyboard.KEY_RIGHT:
                    keyClass = Key.RIGHT;
                    break;
                case Keyboard.KEY_LEFT:
                    keyClass = Key.LEFT;
                    break;
                case Keyboard.KEY_DOWN:
                    keyClass = Key.DOWN;
                    break;
                case Keyboard.KEY_SCROLL:
                    keyClass = Key.SHIFT;
                    break;
                case Keyboard.KEY_LMENU:
                    keyClass = Key.ALT;
                    break;
                case Keyboard.KEY_RMENU:
                    keyClass = Key.ALT;
                    break;
                case Keyboard.KEY_LCONTROL:
                    keyClass = Key.CTRL;
                    break;
                case Keyboard.KEY_RSHIFT:
                    keyClass = Key.SHIFT;
                    break;
                case Keyboard.KEY_LSHIFT:
                    keyClass = Key.SHIFT;
                    break;
                case Keyboard.KEY_RCONTROL:
                    keyClass = Key.CTRL;
                    break;
                case Keyboard.KEY_INSERT:
                    keyClass = Key.INSERT;
                    break;
                case Keyboard.KEY_F12:
                    keyClass = Key.F12;
                    break;
                case Keyboard.KEY_F11:
                    keyClass = Key.F11;
                    break;
                case Keyboard.KEY_F10:
                    keyClass = Key.F10;
                    break;
                case Keyboard.KEY_F9:
                    keyClass = Key.F9;
                    break;
                case Keyboard.KEY_F8:
                    keyClass = Key.F8;
                    break;
                case Keyboard.KEY_F7:
                    keyClass = Key.F7;
                    break;
                case Keyboard.KEY_F6:
                    keyClass = Key.F6;
                    break;
                case Keyboard.KEY_F5:
                    keyClass = Key.F5;
                    break;
                case Keyboard.KEY_F4:
                    keyClass = Key.F4;
                    break;
                case Keyboard.KEY_F3:
                    keyClass = Key.F3;
                    break;
                case Keyboard.KEY_F2:
                    keyClass = Key.F2;
                    break;
                case Keyboard.KEY_F1:
                    keyClass = Key.F1;
                    break;
                default:
                    if( "1234567890".indexOf( Keyboard.getEventCharacter() ) != -1 ){
                        keyClass = Key.DIGIT;
                    } else{
                        // @todo must not necessarily be a letter!! #
                        keyClass = Key.LETTER;
                    }
                    break;
                }

            return keyClass;
        }
        }



    private class MouseListener implements MouseInputListener {

        private boolean down;
        private int lastButton;

        public void onButton( int button, boolean pressed, int x, int y ) {
            down = pressed;
            lastButton = button;

            if( pressed ){
                mouseHandled = disp.fireMousePressedEvent( x, y, getMouseButton( button ), 1 );
            } else{
                mouseHandled = disp.fireMouseReleasedEvent( x, y, getMouseButton( button ), 1 );
            }
        }

        public void onMove( int xDelta, int yDelta, int newX, int newY ) {

            // If the button is down, the mouse is being dragged
            if( down ){
                mouseHandled = disp.fireMouseDraggedEvent( newX, newY, getMouseButton( lastButton ) );
            } else{
                mouseHandled = disp.fireMouseMovedEvent( newX, newY );
            }
        }

        public void onWheel( int wheelDelta, int x, int y ) {

            // wheelDelta is positive if the mouse wheel rolls up
            if( wheelDelta > 0 ){
                mouseHandled = disp.fireMouseWheel( x, y, true, wheelDelta );
            } else{
                mouseHandled = disp.fireMouseWheel( x, y, false, wheelDelta );
            }

        // note (johannes): wheeling code not tested on jME, please report problems on www.fenggui.org/forum/
        }

        /**
         * Helper method that maps the mouse button to the equivalent
         * FengGUI MouseButton enumeration.
         * @param button The button pressed or released.
         * @return The FengGUI MouseButton enumeration matching the
         * button.
         */
        private MouseButton getMouseButton( int button ) {
            switch( button ){
                case 0:
                    return MouseButton.LEFT;
                case 1:
                    return MouseButton.RIGHT;
                case 2:
                    return MouseButton.MIDDLE;
                default:
                    return MouseButton.LEFT;
                }
        }
        }
    }

Here are the errors I end up with after a straight compile on the code you posted, no changes.


FengInputHandler.java:9: cannot find symbol
symbol  : class Key
location: package org.fenggui.event
import org.fenggui.event.Key;
                        ^
FengInputHandler.java:80: cannot find symbol
symbol  : class Key
location: class FengInputHandler.KeyAction
        private Key mapKeyEvent() {
                ^
FengJME.java:26: package org.fenggui.composites does not exist
import org.fenggui.composites.Window;
                             ^
FengJME.java:30: package org.fenggui.render.lwjgl does not exist
import org.fenggui.render.lwjgl.LWJGLBinding;
                               ^
FengInputHandler.java:63: cannot find symbol
symbol  : class Key
location: class FengInputHandler.KeyAction
            Key key = mapKeyEvent();
            ^
FengInputHandler.java:68: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                if( key == Key.LETTER || key == Key.DIGIT ){
                           ^
FengInputHandler.java:68: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                if( key == Key.LETTER || key == Key.DIGIT ){
                                                ^
FengInputHandler.java:81: cannot find symbol
symbol  : class Key
location: class FengInputHandler.KeyAction
            Key keyClass;
            ^
FengInputHandler.java:85: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.BACKSPACE;
                               ^
FengInputHandler.java:88: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.ENTER;
                               ^
FengInputHandler.java:91: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.DELETE;
                               ^
FengInputHandler.java:94: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.UP;
                               ^
FengInputHandler.java:97: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.RIGHT;
                               ^
FengInputHandler.java:100: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.LEFT;
                               ^
FengInputHandler.java:103: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.DOWN;
                               ^
FengInputHandler.java:106: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.SHIFT;
                               ^
FengInputHandler.java:109: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.ALT;
                               ^
FengInputHandler.java:112: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.ALT;
                               ^
FengInputHandler.java:115: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.CTRL;
                               ^
FengInputHandler.java:118: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.SHIFT;
                               ^
FengInputHandler.java:121: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.SHIFT;
                               ^
FengInputHandler.java:124: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.CTRL;
                               ^
FengInputHandler.java:127: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.INSERT;
                               ^
FengInputHandler.java:130: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.F12;
                               ^
FengInputHandler.java:133: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.F11;
                               ^
FengInputHandler.java:136: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.F10;
                               ^
FengInputHandler.java:139: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.F9;
                               ^
FengInputHandler.java:142: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.F8;
                               ^
FengInputHandler.java:145: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.F7;
                               ^
FengInputHandler.java:148: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.F6;
                               ^
FengInputHandler.java:151: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.F5;
                               ^
FengInputHandler.java:154: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.F4;
                               ^
FengInputHandler.java:157: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.F3;
                               ^
FengInputHandler.java:160: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.F2;
                               ^
FengInputHandler.java:163: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                    keyClass = Key.F1;
                               ^
FengInputHandler.java:167: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                        keyClass = Key.DIGIT;
                                   ^
FengInputHandler.java:170: cannot find symbol
symbol  : variable Key
location: class FengInputHandler.KeyAction
                        keyClass = Key.LETTER;
                                   ^
FengInputHandler.java:201: fireMouseDraggedEvent(int,int,org.fenggui.event.mouse.MouseButton,int) in org.fenggui.Display cannot be applied to (int,int,org.fenggui.event.mouse.MouseButton)
                mouseHandled = disp.fireMouseDraggedEvent( newX, newY, getMouseButton( lastButton ) );
                                   ^
FengInputHandler.java:203: fireMouseMovedEvent(int,int,org.fenggui.event.mouse.MouseButton,int) in org.fenggui.Display cannot be applied to (int,int)
                mouseHandled = disp.fireMouseMovedEvent( newX, newY );
                                   ^
FengInputHandler.java:211: fireMouseWheel(int,int,boolean,int,int) in org.fenggui.Display cannot be applied to (int,int,boolean,int)
                mouseHandled = disp.fireMouseWheel( x, y, true, wheelDelta );
                                   ^
FengInputHandler.java:213: fireMouseWheel(int,int,boolean,int,int) in org.fenggui.Display cannot be applied to (int,int,boolean,int)
                mouseHandled = disp.fireMouseWheel( x, y, false, wheelDelta );
                                   ^
FengJME.java:119: cannot find symbol
symbol  : class LWJGLBinding
location: class FengJME
        disp = new org.fenggui.Display( new LWJGLBinding() );
                                            ^
FengJME.java:124: cannot find symbol
symbol  : class Window
location: class FengJME
        Window crazy = FengGUI.createWindow( disp, true, true, true, true );
        ^
FengJME.java:128: cannot find symbol
symbol  : class Window
location: class FengJME
        Window window = FengGUI.createWindow( disp, true, false, false, true );
        ^
FengJME.java:150: cannot find symbol
symbol  : class Window
location: class FengJME
        final Window dialog = FengGUI.createWindow( disp, true, false, false, true );
              ^
45 errors



Obviously I can make it work with a few changes here and there, but once it 'works' I still get the error described earlier with missing widgets.  Maybe there is a problem with the code on https://fenggui.svn.sourceforge.net/svnroot/fenggui - and everyone else is just using older, working code...

I guess I'll try the Alpha 10 package from their SF page, but that was built a pathetically long time ago (Sept 10, 2007) - which kind of defeats the choice of FengGUI based on it being a regularly improved project...


EDIT:
Yes, if I use the old SF package instead of their updated svn version it compiles from the code basixs posted without any errors, and runs/displays properly.  Well, that is a disappointment

I believe that was the last release, although there appears to be work on the SVN I am not sure they have made a new release for it.



(Just because something was released a while ago doesn't make it any less desirable; to the contrary, since it has been posted there so long it would seem to me that it is probably pretty stable.)

According to Marc (admin at FengGUI) - the svn version contains a lot of fixes. 



The reason I consider update frequency important is that I do not want to end up stuck with an unsupported/unupdated product at some point.  My whole reason for using external libraries like FengGUI and jME are so I don't have to worry about keeping up with constant changes in the graphics hardware industry and can focus on the high level (fun) stuff instead.



That said, I spent a bit of time fiddling around with the code further, and got it to display the widget text now - but not the widgets themselves.



I commented out the code to draw the jME stuff:

// display.getRenderer().draw(rootNode);



as well as removing the code which was suggested earlier to apply all the renderstates.  If that code is anywhere in the program it will only display the FengGUI windows and not any of the text.



Now I just need to figure out how to get the widgets themselves to appear - and how to make it display properly when the jME root node is being rendered.



Here is a screen shot of where I'm at right now, if anyone is curious:

http://www.tsourceweb.com/files/fenggui_error2.png



Marc did mention this - since I am not familiar with openGL I'll have to rely on you guys to tell me whether it has anything to do with the issues I'm seeing, and how to fix it if it does:


One thing that changed is that FengGUI doesn't set the texture unit to the first one explicitly. So if you use multi-texturing you should do that yourself before a call to the display() method of the Display class. I don't think it has something to do with that but you can try it just to be sure.

If this hidden surge of interest from the java3d community comes to light, maybe they will take Fenggui under there wing.



I use an old version of Fenggui - poss sept 07, marc was quite radical in the changes he made and I needed to focus on something that mostly worked…

Just an update, I figured out why it wasn't displaying the widgets (I still have to see if I can get it to play nice with the jME scene rendering turned on - but at least FengGUI seems to work fully now)



You guys may want to update the FengGUI examples on the wiki so that no one else has to try to muddle their way through this.  Quoted from my post over at FengGUI:

Quote:
I figured out the last problem - this one was not related to jME as far as I can tell.

The widgets were not appearing because the example I was using was using the new function to create the objects, rather than using the FengGUI.create functions.  I'm not sure if this is expected behavior - or what differs between these two methods.  In my opinion they should behave/look the same whichever way you create them, both for clarity's sake, and also for backward compatibility - since directly creating the widgets renders properly when using older versions of the FengGUI library.

Here are two examples:

This works:

      final ToggableGroup<String> toggableGroup3 = new ToggableGroup<String>();
      Container container3 = FengGUI.createContainer();
      RadioButton<String> radioButtonCoffee3 = FengGUI.createRadioButton(container3,"coffee3",toggableGroup3);
      RadioButton<String> radioButtonTea3 = FengGUI.createRadioButton(container3,"tea3",toggableGroup3);
      window.getContentContainer().addWidget(container3);



This does not work:

      final ToggableGroup<String> toggableGroup2 = new ToggableGroup<String>();
      RadioButton<String> radioButtonCoffee2 = new RadioButton<String>("coffee2", toggableGroup, "coffee2");
      RadioButton<String> radioButtonTea2 = new RadioButton<String>("tea2", toggableGroup, "tea2");
      radioButtonTea2.setSelected(true);
      Container container2 = new Container(new RowLayout(true));
      container2.addWidget(radioButtonCoffee2);
      container2.addWidget(radioButtonTea2);
      window.getContentContainer().addWidget(container2);



See this screenshot for an example of how those code snippets look:
www.tsourceweb.com/files/fenggui_fixed.png

Marc was correct, the final problem getting jME and FengGUI to play nicely was solved by setting the texture unit using GL13.glActiveTexture(GL13.GL_TEXTURE0);



Here is the full example code if you want to post it on the wiki or anything - most of this is code from the jME wiki or the FengGUI wiki - with some modifications by myself to make everything work properly with the newest version of FengGUI from their svn.



Screenshot:

www.tsourceweb.com/files/fenggui_working.png



Inputhandler:

import org.fenggui.Display;
import org.fenggui.event.key.Key;
import org.fenggui.event.mouse.MouseButton;
import org.lwjgl.input.Keyboard;
 
import com.jme.input.InputHandler;
import com.jme.input.MouseInput;
import com.jme.input.MouseInputListener;
import com.jme.input.action.InputActionEvent;
import com.jme.input.action.KeyInputAction;
 
/**
 * FengJMEInputHandler
 *
 * @author Joshua Keplinger
 *
 */
public class FengJMEInputHandler extends InputHandler
{
   
   private Display disp;
   private KeyInputAction keyAction;
   
   private boolean keyHandled;
   private boolean mouseHandled;
   
   public FengJMEInputHandler(Display disp)
   {
      this.disp = disp;
      
      keyAction = new KeyAction();
      addAction(keyAction, DEVICE_KEYBOARD, BUTTON_ALL, AXIS_NONE, false);
      
      MouseInput.get().addListener(new MouseListener());
   }
   
   public void update(float time)
   {
      keyHandled = false;
      mouseHandled = false;
      super.update(time);
   }
   
   public boolean wasKeyHandled()
   {
      return keyHandled;
   }
   
   public boolean wasMouseHandled()
   {
      return mouseHandled;
   }
   
   private class KeyAction extends KeyInputAction
   {
      
      public void performAction(InputActionEvent evt)
      {
         char character = evt.getTriggerCharacter();
         Key key = mapKeyEvent();
         if(evt.getTriggerPressed()) {
            keyHandled = disp.fireKeyPressedEvent(character, key);
            // Bug workaround see note after code
            if (key == Key.LETTER || key == Key.DIGIT)
               keyHandled = disp.fireKeyTypedEvent(character);
         } else
            keyHandled = disp.fireKeyReleasedEvent(character, key);
      }
      
      /**
       * Helper method that maps LWJGL key events to FengGUI.
       * @return The Key enumeration of the last key pressed.
       */
      private Key mapKeyEvent()
      {
         Key keyClass;
         
           switch(Keyboard.getEventKey())
           {
              case Keyboard.KEY_BACK:
                 keyClass = Key.BACKSPACE;
                  break;
              case Keyboard.KEY_RETURN:
                 keyClass = Key.ENTER;
                  break;
              case Keyboard.KEY_DELETE:
                 keyClass = Key.DELETE;
                  break;
              case Keyboard.KEY_UP:
                 keyClass = Key.UP;
                 break;
              case Keyboard.KEY_RIGHT:
                 keyClass = Key.RIGHT;
                  break;
              case Keyboard.KEY_LEFT:
                 keyClass = Key.LEFT;
                  break;
              case Keyboard.KEY_DOWN:
                 keyClass = Key.DOWN;
                  break;
              case Keyboard.KEY_SCROLL:
                 keyClass = Key.SHIFT;
                  break;
              case Keyboard.KEY_LMENU:
                 keyClass = Key.ALT;
                  break;
              case Keyboard.KEY_RMENU:
                 keyClass = Key.ALT;
                  break;
              case Keyboard.KEY_LCONTROL:
                 keyClass = Key.CTRL;
                  break;
              case Keyboard.KEY_RSHIFT:
                 keyClass = Key.SHIFT;
                  break;    
              case Keyboard.KEY_LSHIFT:
                 keyClass = Key.SHIFT;
                  break;             
              case Keyboard.KEY_RCONTROL:
                 keyClass = Key.CTRL;
                  break;
              case Keyboard.KEY_INSERT:
                 keyClass = Key.INSERT;
                  break;
              case Keyboard.KEY_F12:
                 keyClass = Key.F12;
                  break;
              case Keyboard.KEY_F11:
                 keyClass = Key.F11;
                  break;
              case Keyboard.KEY_F10:
                 keyClass = Key.F10;
                  break;
              case Keyboard.KEY_F9:
                 keyClass = Key.F9;
                  break;
              case Keyboard.KEY_F8:
                 keyClass = Key.F8;
                  break;
              case Keyboard.KEY_F7:
                 keyClass = Key.F7;
                  break;
              case Keyboard.KEY_F6:
                 keyClass = Key.F6;
                  break;
              case Keyboard.KEY_F5:
                 keyClass = Key.F5;
                  break;
              case Keyboard.KEY_F4:
                 keyClass = Key.F4;
                  break;
              case Keyboard.KEY_F3:
                 keyClass = Key.F3;
                  break;
              case Keyboard.KEY_F2:
                 keyClass = Key.F2;
                  break;
              case Keyboard.KEY_F1:
                 keyClass = Key.F1;
                  break;
              default:
                 if("1234567890".indexOf(Keyboard.getEventCharacter()) != -1) {
                    keyClass = Key.DIGIT;
                 } else {
                    // @todo must not necessarily be a letter!! #
                    keyClass = Key.LETTER;
                 }
                 break;
          }
         
           return keyClass;
      }
      
   }
   
   private class MouseListener implements MouseInputListener
   {
      
      private boolean down;
      private int lastButton;
      
      public void onButton(int button, boolean pressed, int x, int y)
      {
         down = pressed;
         lastButton = button;
         if(pressed)
            mouseHandled = disp.fireMousePressedEvent(x, y, getMouseButton(button), 1);
         else
            mouseHandled = disp.fireMouseReleasedEvent(x, y, getMouseButton(button), 1);
      }
 
      public void onMove(int xDelta, int yDelta, int newX, int newY)
      {
         // If the button is down, the mouse is being dragged
         if(down)
            mouseHandled = disp.fireMouseDraggedEvent(newX, newY, getMouseButton(lastButton), 0);
         else
            mouseHandled = disp.fireMouseMovedEvent(newX, newY, null, 0);
      }
 
      public void onWheel(int wheelDelta, int x, int y)
      {
         // wheelDelta is positive if the mouse wheel rolls up
                        if(wheelDelta > 0)
                      mouseHandled = disp.fireMouseWheel(x, y, true, wheelDelta, 1);
                        else
                                mouseHandled = disp.fireMouseWheel(x, y, false, wheelDelta, 1);
 
                        // note (johannes): wheeling code not tested on jME, please report problems on www.fenggui.org/forum/
      }
      
      /**
       * Helper method that maps the mouse button to the equivalent
       * FengGUI MouseButton enumeration.
       * @param button The button pressed or released.
       * @return The FengGUI MouseButton enumeration matching the
       * button.
       */
      private MouseButton getMouseButton(int button)
      {
         switch(button)
         {
            case 0:
               return MouseButton.LEFT;
            case 1:
               return MouseButton.RIGHT;
            case 2:
               return MouseButton.MIDDLE;
            default:
               return MouseButton.LEFT;
         }
      }
      
   }
   
}



main code:

import org.fenggui.ComboBox;
import org.fenggui.TextEditor;
import org.fenggui.composite.Window;
import org.fenggui.composite.TextArea;
import org.fenggui.event.ISelectionChangedListener;
import org.fenggui.event.SelectionChangedEvent;
import org.fenggui.layout.StaticLayout;

import com.jme.app.BaseGame;
import com.jme.input.KeyBindingManager;
import com.jme.input.KeyInput;
import com.jme.input.MouseInput;
import com.jme.light.PointLight;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.shape.Box;
import com.jme.scene.state.LightState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.system.JmeException;
import com.jme.util.Timer;
import com.jme.util.lwjgl.LWJGLTimer;
import com.jme.renderer.Renderer;
import com.jme.scene.state.RenderState;

import org.fenggui.Button;
import org.fenggui.CheckBox;
import org.fenggui.Container;
import org.fenggui.FengGUI;
import org.fenggui.Label;
import org.fenggui.RadioButton;
import org.fenggui.ToggableGroup;
import org.fenggui.event.ButtonPressedEvent;
import org.fenggui.event.IButtonPressedListener;
import org.fenggui.layout.RowLayout;
import org.fenggui.util.Point;
import org.fenggui.util.Spacing;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
/**
 * FengJME - A test class for integrating FengGUI and jME.
 *
 * @author Josh (updated by neebie)
 *
 */
public class FengJME extends BaseGame
{
   Camera cam; // Camera for jME
   Node rootNode; // The root node for the jME scene
   PointLight light; // Changeable light
   FengJMEInputHandler input;
   Timer timer;

   Box box; // A box

   org.fenggui.Display disp; // FengGUI's display


   /* (non-Javadoc)
    * @see com.jme.app.BaseGame#cleanup()
    */
   @Override
   protected void cleanup()
   {
      // Clean up the mouse
      MouseInput.get().removeListeners();
      MouseInput.destroyIfInitalized();
      // Clean up the keyboard
      KeyInput.destroyIfInitalized();
   }


   /* (non-Javadoc)
    * @see com.jme.app.BaseGame#initGame()
    */
   @Override
   protected void initGame()
   {

      // Create our root node
      rootNode = new Node("rootNode");
      // Going to enable z-buffering
      ZBufferState buf = display.getRenderer().createZBufferState();
      buf.setEnabled(true);
      buf.setFunction(ZBufferState.CF_LEQUAL);
      // ... and set the z-buffer on our root node
      rootNode.setRenderState(buf);

      // Create a white light and enable it
      light = new PointLight();
      light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
      light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
      light.setLocation(new Vector3f(100, 100, 100));
      light.setEnabled(true);

      /** Attach the light to a lightState and the lightState to rootNode. */

      LightState lightState = display.getRenderer().createLightState();
      lightState.setEnabled(true);
      lightState.attach(light);
      rootNode.setRenderState(lightState);

      // Create our box
      box = new Box("The Box", new Vector3f(-1, -1, -1), new Vector3f(1, 1, 1));
      box.updateRenderState();
      // Rotate the box 25 degrees along the x and y axes.
      Quaternion rot = new Quaternion();
      rot.fromAngles(FastMath.DEG_TO_RAD * 25, FastMath.DEG_TO_RAD * 25, 0.0f);
      box.setLocalRotation(rot);
      // Attach the box to the root node
      rootNode.attachChild(box);

      // Update our root node
      rootNode.updateGeometricState(0.0f, true);
      rootNode.updateRenderState();


      // Create the GUI
      initGUI();
   }


   /**
    * Create our GUI.  FengGUI init code goes in here
    *
    */
   protected void initGUI()
   {
      // Grab a display using an LWJGL binding
      //      (obviously, since jME uses LWJGL)
      disp = new org.fenggui.Display(new org.fenggui.binding.render.lwjgl.LWJGLBinding());

      input = new FengJMEInputHandler(disp);

      final Window dialog = FengGUI.createWindow(disp, true, false, false, true);
      final Label label = FengGUI.createLabel(dialog.getContentContainer(),"---");
      dialog.setTitle("you ordered:");
      dialog.setPosition(new Point(250,250));
      dialog.pack();

      Window window = FengGUI.createWindow(disp, true, false, false, true);
      window.setTitle("hot drinks");
      window.setPosition(new Point(50,200));
      window.getContentContainer().setLayoutManager(new RowLayout(false));
      window.getContentContainer().getAppearance().setPadding(new Spacing(10, 10));

      final ToggableGroup<String> toggableGroup = new ToggableGroup<String>();
      Container container = new Container(new RowLayout(true));
      RadioButton<String> radioButtonCoffee = FengGUI.createRadioButton(container, "coffee", toggableGroup);
      RadioButton<String> radioButtonTea = FengGUI.createRadioButton(container, "tea", toggableGroup);
      radioButtonCoffee.setValue("coffee");
      radioButtonTea.setValue("tea");
      radioButtonTea.setSelected(true);
      window.getContentContainer().addWidget(container);
      final CheckBox<String> checkBoxMilk = FengGUI.createCheckBox(window.getContentContainer(), "milk");
      final CheckBox<String> checkBoxSugar = FengGUI.createCheckBox(window.getContentContainer(), "sugar");

      Button button = FengGUI.createButton(window.getContentContainer(), "submit your order");
      button.addButtonPressedListener(new IButtonPressedListener() {
         public void buttonPressed(ButtonPressedEvent arg0) {

            String temp = toggableGroup.getSelectedValue();
            if (checkBoxMilk.isSelected()) {
               if (checkBoxSugar.isSelected())
                  temp += " with milk and sugar.";
               else
                  temp += " with milk.";
            }
            else
               if (checkBoxSugar.isSelected())
                  temp += " with sugar.";

            label.setText(temp);
            dialog.pack();
         }
      });

      window.pack();

      // Update the display with the newly added components
      disp.layout();
   }


   /* (non-Javadoc)
    * @see com.jme.app.BaseGame#initSystem()
    */
   @Override
   protected void initSystem()
   {

      try
      {
         // Initialize our jME display system
         display = DisplaySystem.getDisplaySystem(properties.getRenderer());
         display.createWindow(properties.getWidth(), properties.getHeight(), properties.getDepth(), properties.getFreq(), properties.getFullscreen());

         // Get a camera based on the window settings
         cam = display.getRenderer().createCamera(display.getWidth(), display.getHeight());
      }
      catch (JmeException ex)
      {
         ex.printStackTrace();
         System.exit(1);
      }

      // We want a cursor to interact with FengGUI
      MouseInput.get().setCursorVisible(true);

      // Bind the Escape key to kill our test app
      KeyBindingManager.getKeyBindingManager().set("quit", KeyInput.KEY_ESCAPE);

      // Set a black background.
      display.getRenderer().setBackgroundColor(ColorRGBA.black);
      // Set up how our camera sees.
      cam.setFrustumPerspective(45.0f, (float) display.getWidth() / (float) display.getHeight(), 1, 1000);
      Vector3f loc = new Vector3f(0.0f, 0.0f, 15.0f);
      Vector3f left = new Vector3f(-1.0f, 0.0f, 0.0f);
      Vector3f up = new Vector3f(0.0f, 1.0f, 0.0f);
      Vector3f dir = new Vector3f(0.0f, 0f, -1.0f);
      //  Move our camera to a correct place and orientation.
      cam.setFrame(loc, left, up, dir);
      //  Signal that we've changed our camera's location/frustum.
      cam.update();
      //  Assign the camera to this renderer.
      display.getRenderer().setCamera(cam);

      // Create our timer
      timer = new LWJGLTimer();
   }


   /* (non-Javadoc)
    * @see com.jme.app.BaseGame#reinit()
    */
   @Override
   protected void reinit() {}


   /* (non-Javadoc)
    * @see com.jme.app.BaseGame#render(float)
    */
   @Override
   protected void render(float interpolation)
   {
      // Clear previous
      display.getRenderer().clearBuffers();

      // Draw jME stuff
      display.getRenderer().draw(rootNode);

      // Set back to first texture unit so GUI displays properly
      GL13.glActiveTexture(GL13.GL_TEXTURE0);

      // Draw GUI
      disp.display();
   }


   /* (non-Javadoc)
    * @see com.jme.app.BaseGame#update(float)
    */
   @Override
   protected void update(float interpolation)
   {
      timer.update();
      float tpf = timer.getTimePerFrame();
      input.update(tpf);
      if (!input.wasKeyHandled())
      {
         // Check to see if Escape was pressed
         if (KeyBindingManager.getKeyBindingManager().isValidCommand("quit")) finish();
      }
   }


   /**
    * @param args
    */
   public static void main(String[] args)
   {
      FengJME app = new FengJME();
      app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG);
      app.start();
   }
}


In case anyone does add the updated one to the wiki - be aware that a fireMouseClickEvent should be added to the input handler - here's a hacked up version I made just to test it.  Without this event, the FengGUI combobox will not work properly.


import org.fenggui.Display;
import org.fenggui.event.key.Key;
import org.fenggui.event.mouse.MouseButton;
import org.lwjgl.input.Keyboard;

import com.jme.input.InputHandler;
import com.jme.input.MouseInput;
import com.jme.input.MouseInputListener;
import com.jme.input.action.InputActionEvent;
import com.jme.input.action.KeyInputAction;

/**
 * FengJMEInputHandler
 *
 * @author Joshua Keplinger
 *
 */
public class FengJMEInputHandler extends InputHandler
{

   private Display disp;
   private KeyInputAction keyAction;

   private boolean keyHandled;
   private boolean mouseHandled;

   public FengJMEInputHandler(Display disp)
   {
      this.disp = disp;

      keyAction = new KeyAction();
      addAction(keyAction, DEVICE_KEYBOARD, BUTTON_ALL, AXIS_NONE, false);

      MouseInput.get().addListener(new MouseListener());
   }

   public void update(float time)
   {
      keyHandled = false;
      mouseHandled = false;
      super.update(time);
   }

   public boolean wasKeyHandled()
   {
      return keyHandled;
   }

   public boolean wasMouseHandled()
   {
      return mouseHandled;
   }

   private class KeyAction extends KeyInputAction
   {

      public void performAction(InputActionEvent evt)
      {
         char character = evt.getTriggerCharacter();
         Key key = mapKeyEvent();
         if(evt.getTriggerPressed()) {
            keyHandled = disp.fireKeyPressedEvent(character, key);
            // Bug workaround see note after code
            if (key == Key.LETTER || key == Key.DIGIT)
               keyHandled = disp.fireKeyTypedEvent(character);
         } else
            keyHandled = disp.fireKeyReleasedEvent(character, key);
      }

      /**
       * Helper method that maps LWJGL key events to FengGUI.
       * @return The Key enumeration of the last key pressed.
       */
      private Key mapKeyEvent()
      {
         Key keyClass;

           switch(Keyboard.getEventKey())
           {
              case Keyboard.KEY_BACK:
                 keyClass = Key.BACKSPACE;
                  break;
              case Keyboard.KEY_RETURN:
                 keyClass = Key.ENTER;
                  break;
              case Keyboard.KEY_DELETE:
                 keyClass = Key.DELETE;
                  break;
              case Keyboard.KEY_UP:
                 keyClass = Key.UP;
                 break;
              case Keyboard.KEY_RIGHT:
                 keyClass = Key.RIGHT;
                  break;
              case Keyboard.KEY_LEFT:
                 keyClass = Key.LEFT;
                  break;
              case Keyboard.KEY_DOWN:
                 keyClass = Key.DOWN;
                  break;
              case Keyboard.KEY_SCROLL:
                 keyClass = Key.SHIFT;
                  break;
              case Keyboard.KEY_LMENU:
                 keyClass = Key.ALT;
                  break;
              case Keyboard.KEY_RMENU:
                 keyClass = Key.ALT;
                  break;
              case Keyboard.KEY_LCONTROL:
                 keyClass = Key.CTRL;
                  break;
              case Keyboard.KEY_RSHIFT:
                 keyClass = Key.SHIFT;
                  break;
              case Keyboard.KEY_LSHIFT:
                 keyClass = Key.SHIFT;
                  break;
              case Keyboard.KEY_RCONTROL:
                 keyClass = Key.CTRL;
                  break;
              case Keyboard.KEY_INSERT:
                 keyClass = Key.INSERT;
                  break;
              case Keyboard.KEY_F12:
                 keyClass = Key.F12;
                  break;
              case Keyboard.KEY_F11:
                 keyClass = Key.F11;
                  break;
              case Keyboard.KEY_F10:
                 keyClass = Key.F10;
                  break;
              case Keyboard.KEY_F9:
                 keyClass = Key.F9;
                  break;
              case Keyboard.KEY_F8:
                 keyClass = Key.F8;
                  break;
              case Keyboard.KEY_F7:
                 keyClass = Key.F7;
                  break;
              case Keyboard.KEY_F6:
                 keyClass = Key.F6;
                  break;
              case Keyboard.KEY_F5:
                 keyClass = Key.F5;
                  break;
              case Keyboard.KEY_F4:
                 keyClass = Key.F4;
                  break;
              case Keyboard.KEY_F3:
                 keyClass = Key.F3;
                  break;
              case Keyboard.KEY_F2:
                 keyClass = Key.F2;
                  break;
              case Keyboard.KEY_F1:
                 keyClass = Key.F1;
                  break;
              default:
                 if("1234567890".indexOf(Keyboard.getEventCharacter()) != -1) {
                    keyClass = Key.DIGIT;
                 } else {
                    // @todo must not necessarily be a letter!! #
                    keyClass = Key.LETTER;
                 }
                 break;
          }

           return keyClass;
      }

   }

   private class MouseListener implements MouseInputListener
   {

      private boolean down;
      private int lastButton;

      private int lastX = -100;
      private int lastY = -100;

      public void onButton(int button, boolean pressed, int x, int y)
      {
         down = pressed;
         lastButton = button;
         if(pressed)
         {
            lastX = x;
            lastY = y;
            mouseHandled = disp.fireMousePressedEvent(x, y, getMouseButton(button), 1);
         }
         else
         {
            mouseHandled = disp.fireMouseReleasedEvent(x, y, getMouseButton(button), 1);

            if (x == lastX && y == lastY && getMouseButton(button) == MouseButton.LEFT)
            {
               boolean rtnVal = disp.fireMouseClickEvent(x, y, getMouseButton(button), 1);

               if (mouseHandled == false)
               {
                  mouseHandled = rtnVal;
               }
            }

            lastX = -100;
            lastY = -100;
         }
      }

      public void onMove(int xDelta, int yDelta, int newX, int newY)
      {
         // If the button is down, the mouse is being dragged
         if(down)
            mouseHandled = disp.fireMouseDraggedEvent(newX, newY, getMouseButton(lastButton), 0);
         else
            mouseHandled = disp.fireMouseMovedEvent(newX, newY, null, 0);
      }

      public void onWheel(int wheelDelta, int x, int y)
      {
         // wheelDelta is positive if the mouse wheel rolls up
                        if(wheelDelta > 0)
                      mouseHandled = disp.fireMouseWheel(x, y, true, wheelDelta, 1);
                        else
                                mouseHandled = disp.fireMouseWheel(x, y, false, -wheelDelta, 1);

                        // note (johannes): wheeling code not tested on jME, please report problems on www.fenggui.org/forum/
      }

      /**
       * Helper method that maps the mouse button to the equivalent
       * FengGUI MouseButton enumeration.
       * @param button The button pressed or released.
       * @return The FengGUI MouseButton enumeration matching the
       * button.
       */
      private MouseButton getMouseButton(int button)
      {
         switch(button)
         {
            case 0:
               return MouseButton.LEFT;
            case 1:
               return MouseButton.RIGHT;
            case 2:
               return MouseButton.MIDDLE;
            default:
               return MouseButton.LEFT;
         }
      }

   }

}



EDIT: Corrected wheeldelta issue - wheeldelta should always be passed into FengGUI as a positive value, even though jME uses both positive and negative values, so we need to flip the sign.