Getting started with JInput

After a number of requests I’ve given in and written this :slight_smile:

Any comments on this information should be made in other threads and I’ll update this one to prevent it getting messy.

  • Go here and download the latest JInput binaries.
  • Unpack the zip file somewhere temporarily. You should get a dist folder, and in there,
    [list]
    [li]jinput-dx8.dll
  • jinput-raw.dll
  • jinput-test.jar
  • jinput-wintab.dll
  • jinput.jar
  • libjinput-linux.so
  • libjinput-osx.jnilib
    [/li]
  • Copy jinput.jar and the dlls, so, or jnilib to somewhere handy and add the natives to your java.library.path.
    [/list]

The jinput-test.jar contains 3 test applications, one to dump the name and details of each controller, one to open up a gui to show the values of each of the components on each of the controllers, and a rumble test for any rumbling controllers.

You can run the tests in the dist folder by running

java -Djava.library.path=. -cp jinput.jar:jinput-test.jar net.java.games.input.test.ControllerTextTest
java -Djava.library.path=. -cp jinput.jar:jinput-test.jar net.java.games.input.test.ControllerReadTest
java -Djava.library.path=. -cp jinput.jar:jinput-test.jar net.java.games.input.test.RumbleTest

On windows you’ll need to change the :'s to ;'s

Without reproducing the javadoc here, the basic principle is that you ask the DefaultControllerEnvironment for a list of controllers. Controllers are things, a joystick, the keyboard etc. Each controller potentially has subcontrollers, but for most devices, these are not used.
Each controller also has a list of components, buttons and axis.
Components have a value and a bunch of information about it, relative or absolute, normalised (values are between -1 and +1).

At it’s simplest, thats it, and thats as much detail as I want to go in to here :slight_smile:

HTH

Endolf

Ok, simple code time.

Here is the source for getting the list of controllers, their components and some of the static details about them.

Get a list of the controllers JInput knows about and can interact with


        Controller[] ca = ControllerEnvironment.getDefaultEnvironment().getControllers();

        for(int i =0;i<ca.length;i++){

            /* Get the name of the controller */
            System.out.println(ca[i].getName());

Get the type of the controller, e.g. GAMEPAD, MOUSE, KEYBOARD, see http://www.newdawnsoftware.com/resources/jinput/apidocs/net/java/games/input/Controller.Type.html.

            System.out.println("Type: "+ca[i].getType().toString());

            /* Get this controllers components (buttons and axis) */
            Component[] components = ca[i].getComponents();
            System.out.println("Component Count: "+components.length);
            for(int j=0;j<components.length;j++){
                
                /* Get the components name */
                System.out.println("Component "+j+": "+components[j].getName());

Get it’s identifier, E.g. BUTTON.PINKIE, AXIS.POV and KEY.Z, see http://www.newdawnsoftware.com/resources/jinput/apidocs/net/java/games/input/Component.Identifier.html

                System.out.println("    Identifier: "+ components[j].getIdentifier().getName());

Display if this component is relative or absolute (change in position or it’s location. Mice are normally relative giving the number of units it has been moved since last polled (do not confuse this with pixels on the screen), Joysticks are normally absolute, giving the amount it’s being pushed forwards, regardless of where it was last poll.

                System.out.print("    ComponentType: ");
                if (components[j].isRelative()) {
                    System.out.print("Relative");
                } else {
                    System.out.print("Absolute");
                }
                if (components[j].isAnalog()) {
                    System.out.print(" Analog");
                } else {
                    System.out.print(" Digital");
                }
            }
        }

To see it all put together check out the ControllerTextTest in CVS here

Endolf

Next!

This is how to poll controllers/components and get their values.


		Controller[] controllers = ControllerEnvironment.getDefaultEnvironment().getControllers();
		Controller firstMouse=null;
		for(int i=0;i<controllers.length && firstMouse==null;i++) {

Check if the type of the controller is a mouse


			if(controllers[i].getType()==Controller.Type.MOUSE) {
				// Found a mouse
				firstMouse = controllers[i];
			}
		}
		if(firstMouse==null) {
			// Couldn't find a mouse
			System.out.println("Found no mouse");
			System.exit(0);
		}
		
		System.out.println("First mouse is: " + firstMouse.getName());
		
		while(true) {

Poll, you need to do this often, if you don’t the buffers in the underlying OS might get full, and then information will be lost

 
			firstMouse.poll();
			Component[] components = firstMouse.getComponents();
			StringBuffer buffer = new StringBuffer();
			for(int i=0;i<components.length;i++) {
				if(i>0) {
					buffer.append(", ");
				}
				buffer.append(components[i].getName());
				buffer.append(": ");

Get the value this component had last time it was polled (a few lines up from here), check this is an analog or digital component and display an appropriate value


				if(components[i].isAnalog()) {
					buffer.append(components[i].getPollData());
				} else {
					if(components[i].getPollData()==1.0f) {
						buffer.append("On");
					} else {
						buffer.append("Off");
					}
				}
			}
			System.out.println(buffer.toString());
			
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

As of version 2 of JInput we also have event queues, this means that whilst you must still poll the devices, you don’t have to read everything every poll, by using the event queues you can get just the changed components.


		while(true) {
			Controller[] controllers = ControllerEnvironment.getDefaultEnvironment().getControllers();
			if(controllers.length==0) {
				System.out.println("Found no controllers.");
				System.exit(0);
			}
			
			for(int i=0;i<controllers.length;i++) {
				controllers[i].poll();

Everything up to here is not new.
Now we get hold of the event queue for this device.


				EventQueue queue = controllers[i].getEventQueue();

Create an event object to pass down to get populated with the information. The underlying system may not hold the data in a JInput friendly way, so it only gets converted when asked for.

				Event event = new Event();

Now we read from the queue until it’s empty. The 3 main things from the event are a time stamp (it’s in nanos, so it should be accurate, but only relative to other events. It’s purpose is for knowing the order events happened in. Then we can get the component that this event relates to, and the new value.


				while(queue.getNextEvent(event)) {
					StringBuffer buffer = new StringBuffer(controllers[i].getName());
					buffer.append(" at ");
					buffer.append(event.getNanos()).append(", ");
					Component comp = event.getComponent();
					buffer.append(comp.getName()).append(" changed to ");
					float value = event.getValue(); 
					if(comp.isAnalog()) {
						buffer.append(value);
					} else {
						if(value==1.0f) {
							buffer.append("On");
						} else {
							buffer.append("Off");
						}
					}
					System.out.println(buffer.toString());
				}
			}
			
			try {
				Thread.sleep(20);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}

Thats all for now folks :slight_smile:

Endolf