Compile and run the application
This part is easy. Assuming that jna.jar
, Kernel32.java
, and LocalTime.java
are located in the current directory, invoke javac -cp jna.jar;. LocalTime.java
to compile the application's source code. Assuming a Windows platform, invoke java -cp jna.jar;. LocalTime
to run the application. You should see output similar to Listing 4.
Listing 4. Output generated from LocalTime.java
Year is 2007
Month is 12
Day of Week is 3
Day is 19
Hour is 12
Minute is 35
Second is 13
Milliseconds are 156
Accessing joystick device info
Although the previous example introduces JNA, obtaining the local time and date is not actually a good use of this technology, or even JNI. Java's System.currentTimeMillis()
method already returns this information, albeit expressed in milliseconds. Accessing a joystick device is a more appropriate use of JNA because Java does not provide an API for game controllers.
Ideally, you would build a platform-independent Java library that uses JNA to access the native Joystick APIs on Linux, Mac OS X, Windows, and Unix platforms. For brevity and convenience, this example will focus exclusively on accessing the Windows Joystick API. I'll also limit the focus to just a small part of the API.
As with GetLocalTime()
, your first step is to identify the Joystick API's DLL. The name of this DLL is winmm.dll
, which includes the Joystick API with other multimedia APIs -- winmm.dll
is located in the same directory as kernel32.dll
. You also need to know the C-based declarations for the joystick functions to be used. These function declarations are shown in Listing 5.
Listing 5. C-based declarations for some Joystick API functions
#define MAXPNAMELEN 32
typedef struct
{
WORD wMid; // manufacturer identifier
WORD wPid; // product identifier
TCHAR szPname [MAXPNAMELEN]; // product name
UINT wXmin; // minimum x position
UINT wXmax; // maximum x position
UINT wYmin; // minimum y position
UINT wYmax; // maximum y position
UINT wZmin; // minimum z position
UINT wZmax; // maximum z position
UINT wNumButtons; // number of buttons
UINT wPeriodMin; // smallest supported polling interval when captured
UINT wPeriodMax; // largest supported polling interval when captured
}
JOYCAPS, *LPJOYCAPS;
MMRESULT joyGetDevCaps(UINT IDDevice, LPJOYCAPS lpjc, UINT cbjc);
UINT joyGetNumDevs(VOID);
Functions of the Joystick API
Windows implements the Joystick API via several functions that begin with the joy
prefix, and structures that various joy
functions use. For example, joyGetNumDevs()
returns the maximum number of joystick devices supported by the platform, and joyGetDevCaps()
returns an attached joystick's capabilities.
The joyGetDevCaps()
function takes three arguments:
- A device ID ranging from 0 through
joyGetNumDevs()
-1 - The address of a
JOYCAPS
structure that holds returned capability information - The size of the
JOYCAPS
structure in bytes
Although it appears otherwise, this function returns a 32-bit unsigned integer, where zero indicates an attached joystick.
The JOYCAPS
structure identifies three types. In addition to the Windows WORD
(16-bit unsigned short integer) type, which maps to Java's 16-bit signed short
integer type, this structure specifies the Windows-defined UINT
(32-bit unsigned integer) type, which maps to Java's 32-bit signed int
eger type, and the Windows text character type known as TCHAR
.
Microsoft introduced TCHAR
to let developers smoothly migrate functions with ASCII text arguments to functions with wide character (think Unicode) text arguments. Also, functions with text arguments are implemented as macros that map to ASCII or wide-character functions. For example, joyGetDevCaps()
is really a macro that maps to joyGetDevCapsA()
and joyGetDevCapsW()
.