Reading Joystick with JInput on Linux

In this blog we try to read JoyStick input with the help of Jinput api.

First we need to dwonload the jinput-linux.jar file. Also we need to download the lwjgl-2.9.1.zip i.e. light weight java gaming library.
Jinout makes use of lwjgl for recognizing controllers.

Now lets check the code from which we will recognize our joystick also to test it.

package com.joystick;

import java.awt.Dimension;
import java.awt.FlowLayout;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JToggleButton;
import net.java.games.input.Component;
import net.java.games.input.Component.Identifier;
import net.java.games.input.Controller;
import net.java.games.input.ControllerEnvironment;


public class JoystickTest {

public static void main(String args[]) {

new JoystickTest();
}


final JFrameWindow window;
private ArrayList<Controller> foundControllers;

public JoystickTest() {
window = new JFrameWindow();

foundControllers = new ArrayList();
searchForControllers();

// If at least one controller was found we start showing controller data on window.
if(!foundControllers.isEmpty())
startShowingControllerData();
else
window.addControllerName("No controller found!");
}

/**
* Search (and save) for controllers of type Controller.Type.STICK,
* Controller.Type.GAMEPAD, Controller.Type.WHEEL and Controller.Type.FINGERSTICK.
*/
private void searchForControllers() {
Controller[] controllers = ControllerEnvironment.getDefaultEnvironment().getControllers();

for(int i = 0; i < controllers.length; i++){
Controller controller = controllers[i];

if (
controller.getType() == Controller.Type.STICK ||
controller.getType() == Controller.Type.GAMEPAD ||
controller.getType() == Controller.Type.WHEEL ||
controller.getType() == Controller.Type.FINGERSTICK
)
{
// Add new controller to the list of all controllers.
foundControllers.add(controller);

// Add new controller to the list on the window.
window.addControllerName(controller.getName() + " - " + controller.getType().toString() + " type");
}
}
}

/**
* Starts showing controller data on the window.
*/
private void startShowingControllerData(){
while(true)
{
// Currently selected controller.
int selectedControllerIndex = window.getSelectedControllerName();
Controller controller = foundControllers.get(selectedControllerIndex);

// Pull controller for current data, and break while loop if controller is disconnected.
if( !controller.poll() ){
window.showControllerDisconnected();
break;
}

// X axis and Y axis
int xAxisPercentage = 0;
int yAxisPercentage = 0;
// JPanel for other axes.
JPanel axesPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 25, 2));
axesPanel.setBounds(0, 0, 200, 190);

// JPanel for controller buttons
JPanel buttonsPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 1, 1));
buttonsPanel.setBounds(6, 19, 246, 110);

// Go trough all components of the controller.
Component[] components = controller.getComponents();
for(int i=0; i < components.length; i++)
{
Component component = components[i];
Identifier componentIdentifier = component.getIdentifier();

// Buttons
if(component.getName().contains("Button")){
// Is button pressed?
boolean isItPressed = true;
if(component.getPollData() == 0.0f)
isItPressed = false;

// Button index
String buttonIndex;
buttonIndex = component.getIdentifier().toString();

// Create and add new button to panel.
JToggleButton aToggleButton = new JToggleButton(buttonIndex, isItPressed);
aToggleButton.setPreferredSize(new Dimension(48, 25));
aToggleButton.setEnabled(false);
buttonsPanel.add(aToggleButton);

// We know that this component was button so we can skip to next component.
continue;
}

// Hat switch
if(componentIdentifier == Component.Identifier.Axis.POV){
float hatSwitchPosition = component.getPollData();
window.setHatSwitch(hatSwitchPosition);

// We know that this component was hat switch so we can skip to next component.
continue;
}

// Axes
if(component.isAnalog()){
float axisValue = component.getPollData();
int axisValueInPercentage = getAxisValueInPercentage(axisValue);

// X axis
if(componentIdentifier == Component.Identifier.Axis.X){
xAxisPercentage = axisValueInPercentage;
continue; // Go to next component.
}
// Y axis
if(componentIdentifier == Component.Identifier.Axis.Y){
yAxisPercentage = axisValueInPercentage;
continue; // Go to next component.
}

// Other axis
} catch (InterruptedException ex) {
Logger.getLogger(JoystickTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

JLabel progressBarLabel = new JLabel(component.getName());
JProgressBar progressBar = new JProgressBar(0, 100);
progressBar.setValue(axisValueInPercentage);
axesPanel.add(progressBarLabel);
axesPanel.add(progressBar);
}
}

// Now that we go trough all controller components,
// we add butons panel to window,
window.setControllerButtons(buttonsPanel);
// set x and y axes,
window.setXYAxis(xAxisPercentage, yAxisPercentage);
} catch (InterruptedException ex) {
Logger.getLogger(JoystickTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

// add other axes panel to window.
window.addAxisPanel(axesPanel);

// We have to give processor some rest.
try {
Thread.sleep(25);
} catch (InterruptedException ex) {
Logger.getLogger(JoystickTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
}

/**
* Given value of axis in percentage.
* Percentages increases from left/top to right/bottom.
* If idle (in center) returns 50, if joystick axis is pushed to the left/top
* edge returns 0 and if it's pushed to the right/bottom returns 100.
*
* @return value of axis in percentage.
*/
public int getAxisValueInPercentage(float axisValue)
{
return (int)(((2 - (1 - axisValue)) * 100) / 2);
}
}

NOTE : For running the above program we need to put lwjgl to our java library path.
I am running the above program in eclipse. So in run configuration i added this : -Djava.library.path=/home/sorabh/Projects/lwjgl-2.9.1/native/linux

JoystickRecognition

JoystickRecognition

Leave a Reply