This is merely to update some of the information posted by Whackjack on his Integrating FengGUI with jME article. I am leaving the old article intact because many people seem to still use the old version. My article is meant to apply to the current version of FengGUI, obtained from their SVN.

All the examples posted here are a synthesis of examples from both the jME wiki and the FengGUI wiki - with updates by myself to make them work properly with the newer version of FengGUI.

For an alternative version implemented as a listener instead of an input handler, see NewFengJMEInputListener.

FengJMEInputHandler.java

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, negative otherwise
			// we need to flip the delta, because FengGUI expects a positive wheelDelta
			// certain widgets will only scroll in one direction otherwise.
			if(wheelDelta > 0)
				mouseHandled = disp.fireMouseWheel(x, y, true, wheelDelta, 1);
			else
				mouseHandled = disp.fireMouseWheel(x, y, false, -wheelDelta, 1);
		}
 
		/**
		 * 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;
			}
		}
 
	}
 
}

FengJME.java

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();
	}
}

/var/www/wiki/data/pages/new_integrating_fenggui_with_jme.txt · Last modified: 2010/03/29 16:54 by erlend_sh  
Recent changes · Show pagesource · Login

Recent changes RSS feed Creative Commons License Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki

subscribe to jME latest jme headlines


site design by bleedcrimson designs © 2008