Я стремлюсь разработать командную оболочку с использованием Java. Одной важной функцией, которую я должен был немедленно реализовать, было «автоматическое завершение», чему способствует командная оболочка при нажатии клавиши «tab». Я полагал, что для этого мне нужно прочитать команду ввода посимвольно в неблокирующем режиме.
К сожалению, насколько я понял, ни один из Java API не поддерживает неблокирующий ввод. То есть Java API, которые предназначены для чтения ввода, ждут (блокируют) до тех пор, пока пользователь не нажмет клавишу «Ввод», что крайне нежелательно в моем случае. Кроме того, я решил не использовать сторонние библиотеки Java. (например, JLine).
Итак, мне пришлось прибегнуть к JNI. Родной файл .C выглядит следующим образом:
JNIEXPORT jint JNICALL Java_autoComplete_IOUtils_read_1character(JNIEnv *env, jobject obj)
{
int ch = getch(); // getch() - non-blocking input and doesn't echo the characters
return (jint)ch;
}
И соответствующий метод Java, в котором вызывается вышеупомянутый нативный метод:
public static String GetLine()
{
int i = 0;
do
{
char variable = (char) read_character(); // Native method is invoked here
System.out.println(variable); // Just printing it for my reference
cmdLine = new StringBuffer(cmdLine).insert(i, variable).toString(); // cmdLine is of type String
i++;
} while ((search(cmdLine.charAt(i - 1), interruptableCharacterArray)) == false);
return (new String(cmdLine));
}
//Checks if the entered character is any one of those keys in the interruptableCharacterArray . As of now , interruptableCharacterArray contains only '\t' (The tab key )
private static boolean search(char charAt,char[] interruptableCharacterArray2)
{
for (int i = 0; i < index; i++)
{
if (interruptableCharacterArray2[i] == charAt)
return true;
}
return false;
}
Также я могу заверить вас, что нет никаких проблем с подключением родной .dll. И «InterruptableCharacterArray» на данный момент содержит только «\ t» (клавиша «tab»). Следовательно, значение индекса на данный момент равно 1.
Проблема:
1> Кажется, что элемент управления не блокируется:
char variable = (char) read_character();
То есть, похоже, что пользователь не может вводить данные через консоль Java в той строке, которая предназначена для этого. И такая же проблема даже в случае getche() (не блокирует, но эхо)
Вместо этого на каждой итерации для «переменной» берется какое-то значение мусора по умолчанию, которое выводится на консоль при выполнении следующего оператора:
System.out.println(variable);
Однако этот мой код работает как шарм, когда getch() заменяется его блокирующими аналогами, такими как getc(stdin),getchar() и т.д.
Я не могу понять, в чем именно заключается проблема с вызовом getch() через JNI.
2> Кроме того, я был бы признателен, если бы были предложены какие-либо другие альтернативные решения для достижения того же.
Заранее спасибо !
Редактировать: Командная оболочка должна быть реализована как в ОС Windows, так и в ОС Unix.