我最近开始学习JAVA,并试图创建一个小壳程序(我不依赖于系统shell执行命令)。等待参数在Java中的价值
我设法得到基本的I/O东西的工作,但我被困在以下情况:
比方说,我用命令“Makefile文件路径/到/文件”命令将检查存在并询问“文件已存在!你想删除它吗?是/否”
我的问题是等待用户输入Y,N或其他任何东西,而不锁定外壳接口(JTextArea)。
import java.util.StringTokenizer;
public abstract class Command {
private final String bin;
protected Shell shell;
public Command(Shell shell, final String bin) {
this.shell = shell;
this.bin = bin;
}
String getBin() {
return this.bin;
}
protected String ask(String question) {
shell.setQuestionAsked(true);
shell.setResponse("");
shell.write(question);
String response = shell.getResponse();
while(response.isEmpty()) {
response = shell.getResponse();
}
shell.setQuestionAsked(false);
return response;
}
public abstract void execute(StringTokenizer stringTokenizer);
}
我试图在并发/线程中找到解决方案,但找不到解决方案。
在@Holger评论中,这是GUI代码部分,因为您可以看到一个Listener已经存在。我的问题在于,当一个命令用上面显示的ask方法询问用户输入时,执行不会等待用户输入,只是继续或在当前的while(response.isEmpty())中导致死锁。
所以我正在寻找一个解决方案来保持ask()方法的执行,直到用户在GUI中按下Enter键。
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.IOException;
public class ShellPanel extends Shell {
private JTextArea shellArea;
private JPanel panel;
private JScrollPane scrollPanel;
private int bufferLength = 0;
private String oldText = "";
ShellPanel() {
shellArea.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
case KeyEvent.VK_DOWN:
e.consume();
break;
case KeyEvent.VK_LEFT:
if (shellArea.getCaretPosition() <= bufferLength) {
e.consume();
}
break;
case KeyEvent.VK_BACK_SPACE:
if (shellArea.getText().length() <= bufferLength) {
e.consume();
}
break;
case KeyEvent.VK_DELETE:
break;
case KeyEvent.VK_ENTER:
read(getNewInput());
updateReferences();
e.consume();
break;
case KeyEvent.VK_HOME:
shellArea.setCaretPosition(bufferLength);
break;
}
}
});
shellArea.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
switch (e.getButton()) {
case MouseEvent.BUTTON3:
String selected = shellArea.getSelectedText();
StringSelection selection = new StringSelection(selected);
if (!selected.isEmpty()) {
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection);
}
try {
String clip = (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor);
if (!clip.isEmpty()) {
shellArea.append(clip);
}
} catch (UnsupportedFlavorException | IOException e1) {
e1.printStackTrace();
}
break;
}
}
});
init();
updateReferences();
}
JPanel getPanel() {
return panel;
}
private void updateReferences() {
oldText = shellArea.getText();
bufferLength = oldText.length();
shellArea.setCaretPosition(bufferLength);
}
@Override
public void write(String content) {
shellArea.append(content);
updateReferences();
}
private String getNewInput() {
return this.shellArea.getText().replace(this.oldText, "");
}
@Override
public void clear() {
this.shellArea.setText("");
}
}
感谢
不要等待。将一个监听器添加到事件发生时将被调用的文本区域中,并且如果该事件意味着必要的先决条件(即,输入了“Y”或“N”),则可以执行期望的操作。 – Holger
谢谢@Holger,我忘了提到一个监听器已经存在,我将添加GUI代码来澄清我的声明 – Shalien
您需要在单独的线程中执行此操作。 – ACV