基本上,我需要暂停我的程序而我正在等待主JFrame中的JTextField的输入,以及所有其他元素,因此它不是弹出窗口。但是,我正在这样做的方式它暂停整个程序,因为我正在使用while(true)或类似的东西。
以下是我的GUI的外观,以便您更好地了解我在说什么;
当我输入命令start
并按回车键时,您可以看到程序卡住了。
这是我初始化同步的方式:
input = new JTextField();
inputScrollPane = new JScrollPane(input, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
input.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (waitingForInput) {
synchronized (holder) {
holder.add(input.getText());
holder.notify();
}
waitingForInput = false;
}
JTextField sauce = (JTextField) e.getSource();
appendCommand(sauce.getText());
sauce.setText("");
}
});
以下是我在LinkedStack上调用notify时会发生什么......
public String getInput(String s) {
appendInput(s + ": ");
input.requestFocus();
synchronized (holder) {
while (holder.isEmpty())
//System.out.println("input inside 2"); //STOPS HERE
try {
holder.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("input inside 3");
String nextString = holder.remove(0);
System.out.println(nextString);
return nextString;
}
/*Document document = getConsoleInput().getDocument();
Element rootElem = document.getDefaultRootElement();
int numLines = rootElem.getElementCount();
Element lineElem = rootElem.getElement(numLines - 2);
int lineStart = lineElem.getStartOffset();
int lineEnd = lineElem.getEndOffset();
try {
System.out.println(document.getText(lineStart, lineEnd - lineStart));
return document.getText(lineStart, lineEnd - lineStart);
} catch (BadLocationException e) {
e.printStackTrace();
return "-1";
} */ //another attempt I had
}
这是按顺序调用的方法的层次结构或链:
我初始化JTextField的开始:
input = new JTextField();
inputScrollPane = new JScrollPane(input, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
input.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (waitingForInput) {
synchronized (holder) {
holder.add(input.getText());
holder.notify();
}
waitingForInput = false;
}
JTextField sauce = (JTextField) e.getSource();
appendCommand(sauce.getText()); //<<<
sauce.setText("");
}
});
在EDT内部调用的AppendCommand(String s)方法
public void appendCommand(String s) {
appendInput(s);
if (!testIfValid(s)) return;
handler = new CommandHandler(getCurrentInstance());
switch (CommandList.valueOf(s.toUpperCase())) {
case HELP:
handler.help();
break;
case START:
handler.start(currentLevelActive); //<<<<<<<<<<<
break;
case STOP:
break;
case EXIT:
break;
//default:
}
}
下一个:
public void start(Level l) {
level_instance = l;
if (level_instance != null) {
level_instance.start();
} else {
//CREATE new level
int width = 0, height = 0;
boolean go;
console_instance.waitingForInput(true);
console_instance.setInputMessage("Enter level width : ");
InputThread widthThread = new InputThread("width", console_instance);
while (!widthThread.done) {
} ///STOPS HERE ETERNALY!!
width = widthThread.getInputResult();
...
InputThread类:
class InputThread extends Thread {
Console console_instance;
String choice;
int inputResult;
boolean done;
public InputThread(String s, Console c) {
console_instance = c;
choice = s;
}
@Override
public void run() {
String s = "";
console_instance.setWaitingForInput(true);
do {
s = console_instance.getInput("Enter " + choice + " of the level"); // <<<<<<<<<<
} while (!isInt(s));
inputResult = Integer.parseInt(s);
done = true;
}
public int getInputResult() {
return inputResult;
}
private boolean isInt(String s) {
int i;
boolean b;
try {
i = Integer.parseInt(s);
b = true;
if (i < 0) {
b = false;
}
} catch (NumberFormatException ne) {
b = false;
}
return b;
}
}
Console.getInput(String s)方法:
public String getInput(String s) {
appendInput(s + ": ");
input.requestFocus();
synchronized (holder) {
while (holder.isEmpty())
//System.out.println("input inside 2"); //STOPS HERE
try {
holder.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("input inside 3");
String nextString = holder.remove(0);
System.out.println(nextString);
return nextString;
}
}
以及它在那个循环中停止的位置。然而,这也会停止整个计划。
对于可能的解决方案,我试图隔离Threads中的部分代码,但无济于事......如果你可以帮我修改这段代码以使其正常运行或给我另一种方法来实现这一目标,那就太好了。
SwingWorker
,首先是在EDT线程中,由于UI仍然挂起,然后在getInput(String s)
方法中,它不起作用。对于后者,这就是代码的样子:
public String getInput(String s) {
waitingForInput = true;
appendInput(s + ": ");
input.requestFocus();
String result = "";
synchronized (holder) {
worker = new SwingWorker<String, String>() {
@Override
public String doInBackground() {
while (holder.isEmpty()) {
//System.out.println("input inside 2"); //STOPS HERE
try {
holder.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return holder.remove(0);
}
@Override
public void done() {
String s ="";
try {
s = super.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println(s);
}
};
while(!worker.isDone()) {}
try {
result = worker.get().toString();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println(result);
return result;
}
答案 0 :(得分:0)
我设法通过将原始Map
包装在另一个Map
内来解决问题,该put(...)
在调用包装好的地图CommandHandler
时调用方法。这将它传递给我的另一个班级{{1}},并从那里开始自我解释。