Re: [OT] Win32 JNI Console Class [was: Re: Clear the Screen]
From: Russell Allen (whoopass069_at_hotmail.com)
Date: 01/29/04
- Previous message: Soren Kuula: "Re: Writing Unicode-16 to a text file"
- In reply to: Anthony Borla: "[OT] Win32 JNI Console Class [was: Re: Clear the Screen]"
- Next in thread: Roman: "Re: [OT] Win32 JNI Console Class [was: Re: Clear the Screen]"
- Reply: Roman: "Re: [OT] Win32 JNI Console Class [was: Re: Clear the Screen]"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: 28 Jan 2004 19:15:16 -0800
Can anyone help me with this one? I am looking for a makefile to fill
in for the one mentioned in the previous posting for so I can compile
this all myself. I have the Borland v5.5 command line tools. I have no
clue where to go here. I tried skipping the 'makefile' idea and tried
using following syntax and it compiled but I don't think it compiled
the way it supposed to (windows freaked when I tried to use the DLL)
cpp32 -I\j2sdk1.4.2_03\include -I\j2sdk1.4.2_03\include\win
32 -I\Borland\BCC55\Include -oConsoleImp.dll ConsoleImp.cpp
So I am assuming I am missing a lot here. Any help would be
appreciated.
Russ
"Anthony Borla" <ajborla@bigpond.com> wrote in message news:<UOcMb.6483$Wa.2950@news-server.bigpond.net.au>...
> "Denz" <RUBBISH@RUBBISHhotmail.com> wrote in message
> news:Hz%Lb.4898$Wa.2751@news-server.bigpond.net.au...
> >
> > Something like this Console class would be
> > great. Ive just downloaded JCurses but so far looks
> > like overkill- when just a few methods like clear screen
> > and cursor position would go such a long way...
> >
>
> I quite like JCurses, *but* I fully agree with you - too much functionality.
> Having thought about it a little more, all that is minimally required:
>
> * Console information accessor [e.g. get max lines, columns, etc]
> * A clear screen method
> * Cursor position set / get methods
> * A character read method i.e. accept a sing;le character
> without needing to press ENTER [could be designed to
> also accept 'special' keys like F1, though best, I think, to
> keep it simple and ignore non-standard keys]
>
> with other functionality such as:
>
> * A string read method [e.g. up to X characters in
> length without pressing ENTER; ESC could abort
> input process; extend to not echo typed keys so
> as to allow password-type input]
> * Support character atributes like colour etc
> * Cursor hide / unhide
>
> would be purely optional.
>
> It is easy enough to make a start with this by creating a Console class:
>
> public class Console
> {
> public static native int getMaxRows();
> public static native int getMaxCols();
>
> public static native void cls();
>
> public static native int getCurRow();
> public static native int getCurCol();
>
> public static native void setCurPos(int row, int col);
>
> public static native char inputKey(int[] keyData);
> }
>
> Below you will find a JNI implementation for such a class. Since we're
> dealing with JNI such code is strictly system-specific, so will work only on
> the targeted platform, in this case, Win32 i.e. it should run ok on all
> Win9x and up platforms.
>
> The included files:
>
> * A batch file called 'mkConsole.bat' used to document / generate
> the steps in creating the native code
>
> * The Java source files:
>
> - Console.java, the Java interface to the JNI routines
> - TestConsole.java, a minimal test harness for these routines
>
> * C++ source files:
>
> - Console.h
> - ConsoleImp.cpp
>
> Assuming you use a Win32 system [I hope so :)] you will need to provide:
>
> * C++ Compiler capable of generating Win32 DLL's
> * Suitable 'make' file for this compiler
>
> The code was tested with Borland 5.5.1 and J2SDK 1.4.1, and appears to work
> ok. The code is provided 'as is' for educational purposes. It goes without
> saying that I accept no reponsibility for this code's use by others.
>
> It may be worthwhile for anyone contemplating the use of this code to first:
>
> * Read the JNI tutorial on the Sun site
> * Consult Win32 documentation regarding 'console applications'
> for some insight into the code
>
> Sadly, the codes its provision alienates a substantial segment of the Java
> community. It is hoped, though, that other may be motivated to implement
> this, or similar functionality, for their own platform, and - hopefully -
> post it. It would be interesting to see how these simple tasks are performed
> on other platforms.
>
> I hope this helps.
>
> Anthony Borla
>
> // FILE: mkConsole.bat ========================
> @echo off
>
> :: Compile JAVA Source containing Native Method calls
> javac -deprecation TestConsole.java
>
> :: Create .h header from Java Source
> javah -jni TestConsole
>
> :: Implement Native Method (C++) and create a .DLL
> :: 1) Compile ConsoleImp.cpp
> :: 2) Create ConsoleImp.dll
> :: *** You need to implement this for your compiler ***
> make -fConsoleImp.mak
>
> :: Execute Java Program which calls Native Method
> :: 1) Loads ConsoleImp.dll
> :: 2) Calls 'Console' native method
> java TestConsole
>
>
> // FILE: Console.java ========================
> public class Console
> {
> // Load DLL
> static
> {
> try
> {
> System.loadLibrary("ConsoleImp");
> }
>
> catch (UnsatisfiedLinkError e)
> {
> System.out.println("Could not locate DLL");
> System.exit(1);
> }
> }
>
> public static native int getMaxRows();
> public static native int getMaxCols();
>
> public static native void cls();
>
> public static native int getCurRow();
> public static native int getCurCol();
>
> public static native void setCurPos(int row, int col);
>
> public static native char inputKey(int[] keyData);
> }
>
> // FILE: TestConsole.java =====================
> public class TestConsole
> {
> public static void main(String[] args)
> {
> System.out.println("Start...");
>
> Console.cls();
>
> System.out.println(Console.getMaxRows());
> System.out.println(Console.getMaxCols());
>
> Console.setCurPos(10, 5);
>
> System.out.println(Console.getCurRow());
> System.out.println(Console.getCurCol());
>
> char key;
> int[] keyData = new int[]{0, 0};
>
> System.out.print("Press a key: ");
> key = Console.inputKey(keyData);
>
> System.out.print(key + ", " + (int)key);
>
> if (key == 0)
> System.out.println("A special key was pressed");
>
> System.out.println("Key Code: " + keyData[0]);
> System.out.println("Key Scan: " + keyData[1]);
>
> System.out.println("End...");
> }
> }
>
>
> // FILE: Console.h ========================
> /* DO NOT EDIT THIS FILE - it is machine generated */
> #include <jni.h>
> /* Header for class Console */
>
> #ifndef _Included_Console
> #define _Included_Console
> #ifdef __cplusplus
> extern "C" {
> #endif
> /*
> * Class: Console
> * Method: getMaxRows
> * Signature: ()I
> */
> JNIEXPORT jint JNICALL Java_Console_getMaxRows
> (JNIEnv *, jclass);
>
> /*
> * Class: Console
> * Method: getMaxCols
> * Signature: ()I
> */
> JNIEXPORT jint JNICALL Java_Console_getMaxCols
> (JNIEnv *, jclass);
>
> /*
> * Class: Console
> * Method: cls
> * Signature: ()V
> */
> JNIEXPORT void JNICALL Java_Console_cls
> (JNIEnv *, jclass);
>
> /*
> * Class: Console
> * Method: getCurRow
> * Signature: ()I
> */
> JNIEXPORT jint JNICALL Java_Console_getCurRow
> (JNIEnv *, jclass);
>
> /*
> * Class: Console
> * Method: getCurCol
> * Signature: ()I
> */
> JNIEXPORT jint JNICALL Java_Console_getCurCol
> (JNIEnv *, jclass);
>
> /*
> * Class: Console
> * Method: setCurPos
> * Signature: (II)V
> */
> JNIEXPORT void JNICALL Java_Console_setCurPos
> (JNIEnv *, jclass, jint, jint);
>
> /*
> * Class: Console
> * Method: inputKey
> * Signature: ([I)C
> */
> JNIEXPORT jchar JNICALL Java_Console_inputKey
> (JNIEnv *, jclass, jintArray);
>
> #ifdef __cplusplus
> }
> #endif
> #endif
>
> // FILE: ConsoleImp.cpp ======================
> // *** Plaform-specific Header(s)
> // *** Here is for Win32
> #include <windows.h>
> // ***
>
> #include <jni.h>
> #include "Console.h"
>
> JNIEXPORT jint JNICALL Java_Console_getMaxRows(JNIEnv *, jclass)
> {
> CONSOLE_SCREEN_BUFFER_INFO csbi;
>
> ::GetConsoleScreenBufferInfo(
> ::GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
>
> return csbi.dwSize.Y;
> }
>
> JNIEXPORT jint JNICALL Java_Console_getMaxCols(JNIEnv *, jclass)
> {
> CONSOLE_SCREEN_BUFFER_INFO csbi;
>
> ::GetConsoleScreenBufferInfo(
> ::GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
>
> return csbi.dwSize.X;
> }
>
> JNIEXPORT void JNICALL Java_Console_cls(JNIEnv *, jclass)
> {
> COORD coordScreen = { 0, 0 };
> CONSOLE_SCREEN_BUFFER_INFO csbi;
>
> DWORD cCharsWritten;
> DWORD dwConSize;
>
> HANDLE hConsole = ::GetStdHandle(STD_OUTPUT_HANDLE);
>
> // Get the number of character cells in the current buffer
> ::GetConsoleScreenBufferInfo(hConsole, &csbi);
>
> // Compute Console size
> dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
>
> // Fill the entire screen with blanks
> ::FillConsoleOutputCharacter(hConsole, (TCHAR) ' ',
> dwConSize, coordScreen, &cCharsWritten);
>
> // Get the current text attribute
> ::GetConsoleScreenBufferInfo(hConsole, &csbi);
>
> // Set the buffer's attributes accordingly
> ::FillConsoleOutputAttribute(hConsole, csbi.wAttributes,
> dwConSize, coordScreen, &cCharsWritten);
>
> // Home the cursor at (0, 0)
> ::SetConsoleCursorPosition(hConsole, coordScreen);
>
> return;
> }
>
> JNIEXPORT jint JNICALL Java_Console_getCurRow(JNIEnv *, jclass)
> {
> CONSOLE_SCREEN_BUFFER_INFO csbi;
>
> ::GetConsoleScreenBufferInfo(
> ::GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
>
> return csbi.dwCursorPosition.Y;
> }
>
> JNIEXPORT jint JNICALL Java_Console_getCurCol(JNIEnv *, jclass)
> {
> CONSOLE_SCREEN_BUFFER_INFO csbi;
>
> ::GetConsoleScreenBufferInfo(
> ::GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
>
> return csbi.dwCursorPosition.X;
> }
>
> JNIEXPORT void JNICALL Java_Console_setCurPos(JNIEnv* env, jclass obj, jint
> row, jint col)
> {
> COORD coord; coord.X = col; coord.Y = row;
>
> ::SetConsoleCursorPosition(
> ::GetStdHandle(STD_OUTPUT_HANDLE), coord);
> }
>
> JNIEXPORT jchar JNICALL Java_Console_inputKey(JNIEnv* env, jclass obj,
> jintArray keyData)
> {
> const char NUL = '\0',
> ESC = '\x1B';
>
> const int TIMEOUT_MILLIS = 1000;
>
> jsize len = env->GetArrayLength(keyData);
> jint* keyData_ = env->GetIntArrayElements(keyData, 0);
>
> DWORD omode, nmode; DWORD itemsRead = 0;
> INPUT_RECORD ir;
> char inputBuffer[4] = { NUL };
>
> HANDLE hConsole = ::GetStdHandle(STD_INPUT_HANDLE);
>
> ::GetConsoleMode(hConsole, &omode);
> nmode = omode & ~ENABLE_LINE_INPUT & ~ENABLE_ECHO_INPUT;
> ::SetConsoleMode(hConsole, nmode);
>
> do
> {
> ::FlushConsoleInputBuffer(hConsole);
> ::WaitForSingleObject(hConsole, TIMEOUT_MILLIS);
> ::PeekConsoleInput(hConsole, &ir, 1, &itemsRead);
>
> if (itemsRead > 0)
> {
> if (ir.EventType == KEY_EVENT)
> {
> // Discard all non-keydown events
> if (ir.Event.KeyEvent.bKeyDown == FALSE)
> {
> ::ReadConsoleInput(hConsole, &ir, 1, &itemsRead);
> continue;
> }
>
> // Got ASCII key, so extract, flush, and exit
> if (ir.Event.KeyEvent.uChar.AsciiChar != NUL)
> {
> if (ir.Event.KeyEvent.uChar.AsciiChar == ESC)
> {
> ::ReadConsoleInput(hConsole, &ir, 1, &itemsRead);
> inputBuffer[0] = ESC;
> }
> else
> ::ReadFile(hConsole, inputBuffer, 1, &itemsRead, NULL);
>
> keyData_[0] = ir.Event.KeyEvent.wVirtualKeyCode;
> keyData_[1] = ir.Event.KeyEvent.wVirtualScanCode;
>
> break;
> }
>
> // Got 'special' key, so determine appropriate actions
> switch (ir.Event.KeyEvent.dwControlKeyState)
> {
> case ENHANCED_KEY:
> ::ReadConsoleInput(hConsole, &ir, 1, &itemsRead);
> break;
>
> case LEFT_ALT_PRESSED: case LEFT_CTRL_PRESSED:
> case RIGHT_ALT_PRESSED: case RIGHT_CTRL_PRESSED:
> ::ReadFile(hConsole, inputBuffer, 1, &itemsRead, NULL);
> inputBuffer[0] = NUL;
> break;
>
> case SHIFT_PRESSED:
> ::ReadFile(hConsole, inputBuffer, 1, &itemsRead, NULL);
> break;
> }
>
> keyData_[0] = ir.Event.KeyEvent.wVirtualKeyCode;
> keyData_[1] = ir.Event.KeyEvent.wVirtualScanCode;
> }
> else
> {
> // Not Key Event, so just extract and discard
> ::ReadConsoleInput(hConsole, &ir, 1, &itemsRead);
> }
> }
>
> } while (itemsRead == 0);
>
> ::FlushConsoleInputBuffer(hConsole);
> ::SetConsoleMode(hConsole, omode);
>
> env->ReleaseIntArrayElements(keyData, keyData_, 0);
>
> return inputBuffer[0];
> }
- Previous message: Soren Kuula: "Re: Writing Unicode-16 to a text file"
- In reply to: Anthony Borla: "[OT] Win32 JNI Console Class [was: Re: Clear the Screen]"
- Next in thread: Roman: "Re: [OT] Win32 JNI Console Class [was: Re: Clear the Screen]"
- Reply: Roman: "Re: [OT] Win32 JNI Console Class [was: Re: Clear the Screen]"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]