私は最近JAVAを学び始めました。少しシェルのようなプログラムを作成しようとしましたが(私はコマンドを実行するためにシステムシェルに依存しません)。パラメータがJavaで評価されるのを待っている
私は、基本的なI/Oの事は仕事を得るために管理が、私は次のような状況でこだわっている:
場合、コマンドがチェックする「/ファイルへのメイクファイルパス/」のは、私はコマンドを使用しましょう
私の問題は、ユーザーがY、Nなどを入力するのを待つことです。シェルインターフェイス(AJTextArea)をロックしないでください。
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);
}
私は同時実行性/スレッド化で解決策を見つけようとしましたが、解決策が見つかりませんでした。
Light @Holgerのコメントでは、リスナーが既に存在することがわかるので、これはGUIコードの部分です。私の問題は、コマンドが上に示したaskメソッドを使ってユーザー入力を要求すると、実行はユーザー入力を待つことなく、現在のwhile(response.isEmpty())がデッドロックを引き起こすことになります。
私はユーザーがGUIでenterを押すまで、ask()メソッドの実行を保持するソリューションを探しています。
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