我前几天问了一个关于在摆动GUI中获取键盘输入的问题 - 实际上是MCR输入。一位用户发现了某人编写的低级键盘钩子。非常酷,它主要起作用。我必须学习一些新东西来实现它(总是很乐意这样做),而且我可能无法完全理解正在发生的事情。
事情是,并且我将发布下面的代码,当我实现键盘钩子的线程时,它现在运行一次while循环(而在CardRead.java中成功== false)。如果我硬编码样本数据,它只运行一次。如果我删除键盘钩子并使用普通的Scanner.nextLine()(这意味着我必须在控制台中单击以向应用程序提供输入),它只运行一次。用键盘输入观察者开始一个新线程?两次。我不明白为什么,或如何解决它。我很高兴只是明白究竟发生了什么 - 如果你们中的一个人告诉我如何修复它,我会欣喜若狂。
以下是代码:
CardRead.java
public class CardRead {
public static String raw_card_data;
int readcount = 1;
String[] tracks = new String[2];
String[] tracks_final = new String[2];
public static void main()
{
// This doesn't happen until after card is swiped, dunno why.
//GUI.outputArea.setText(GUI.outputArea.getText() + "\n\n Scan card \n");
boolean success = false;
while (success == false)
{
//raw_card_data = "%test?;testing?"; // <-- using this, runs thru once
// using THIS, runs through twice.
// create an event source - reads from stdin
final KB_EventSource evSrc = new KB_EventSource();
// create an observer
final KB_RespHandler respHandler = new KB_RespHandler();
// subscribe the observer to the event source
evSrc.addObserver( respHandler );
// starts the event thread
Thread kb_thread = new Thread(evSrc);
kb_thread.start();
// sleep until card swiped
while (raw_card_data == null)
{
try
{
Thread.sleep(1000);
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
System.out.println(raw_card_data);
// Tokenize raw_card_data
StringTokenizer tokenizer = new StringTokenizer(raw_card_data, "?");
int i = 0;
do
{
tracks[i] = tokenizer.nextToken();
System.out.println(i + ": " + tracks[i]);
i++;
}
while (tokenizer.hasMoreTokens());
//System.out.println(track1);
//System.out.println(track2);
tracks_final[0] = tracks[0].substring(1,tracks[0].length());
if (tracks[1] != null)
{
tracks_final[1] = tracks[1].substring(1,tracks[1].length());
}
if ( (readcount <= 5) && ( (tracks_final[0].equals("E") || tracks_final[0].equals(null) ) || (tracks_final[1].equals("E") || tracks_final[1].equals(null)) ) )
{
GUI.notout.setText("Card Read Unsuccessful. Scan Again.");
GUI.outputArea.setText(GUI.outputArea.getText() + "Card read unsuccessful. Scan again. \n");
success = false;
readcount++;
}
else if (readcount <= 5)
{
GUI.notout.setText("Card Successfully Read");
GUI.outputArea.setText(GUI.outputArea.getText() + "\n Success! \n");
GUI.outputArea.setText(GUI.outputArea.getText() + "Track 1 = " + tracks_final[0] + "\n");
GUI.outputArea.setText(GUI.outputArea.getText() + "Track 2 = " + tracks_final[1] + "\n");
success = true;
} // end if else chain
} // end while success == false
} // end public void main
} // end class CardRead
KB_RespHandler.java
import java.util.Observable;
import java.util.Observer;
public class KB_RespHandler implements Observer
{
private String resp;
public void update (Observable obj, Object arg)
{
if (arg instanceof String)
{
resp = (String) arg;
CardRead.raw_card_data = resp;
}
}
}
KB_EventSource.java
import de.ksquared.system.keyboard.*;
import java.util.Observable;
public class KB_EventSource extends Observable implements Runnable
{
public static String temp = "";
public static String output = "";
public void run()
{
new GlobalKeyListener().addKeyListener(new KeyAdapter()
{
@Override public void keyPressed(KeyEvent event)
{
switch(event.getVirtualKeyCode())
{
case KeyEvent.VK_0:
if (event.isShiftPressed() == true)
temp += ")";
else if (event.isShiftPressed() == false)
temp += "0";
break;
case KeyEvent.VK_1:
if (event.isShiftPressed() == true)
temp += "!";
else if (event.isShiftPressed() == false)
temp += "1";
break;
/*insert processing for other keys here*/
case KeyEvent.VK_SPACE:
if (event.isShiftPressed() == true)
temp += " ";
else if (event.isShiftPressed() == false)
temp += " ";
break;
case KeyEvent.VK_RETURN:
/*if (event.isShiftPressed() == true)
temp += "\n";
else if (event.isShiftPressed() == false)
temp += "\n";*/
setChanged();
notifyObservers(temp);
//clearChanged();
break;
} // end switch (event.getVirtualKeyCode())*/
} // end public void keyPressed
});
while(true)
try
{
Thread.sleep(100);
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
所以,我不知道发生了什么。我想也许我需要在收到输入后停止线程kb_thread
,但我找不到任何方法来做到这一点。不推荐thread.stop()
和thread.destroy()
,Eclipse和Google告诉我不要使用它们。这甚至可能不是我需要做的事情。
答案 0 :(得分:0)
“CardRead.java”中的评论说“成功后哪个会改变成功=真实”。
这是否意味着它可能会失败,因此它不会改变success
?
如果这是真的那么raw_card_data
仍然是非空的,它会再试一次。
我假设你在某个时候再次将raw_card_data
重置为null。
另一方面,这个:
if (event.isShiftPressed() == true)
temp += ")";
else if (event.isShiftPressed() == false)
temp += "0";
可以简化为:
if (event.isShiftPressed())
temp += ")";
else
temp += "0";