そこで私は、インターフェイスを備えたプログラムを使用して Minecraft サーバーを実行できるようにする Java アプリに取り組んできました。シェル スクリプトを実行すると、すべての出力がウィンドウに表示され、入力を書き込むことができます。次に、入力はプロセスによって読み取られ、解釈されます。これにより、「start」、「stop」、「help」、「op」などのサブコマンドを使用できます。ただし、入力をプロセスに送信する方法がわかりません。
コンソールは次のようになります。
私は次のことを試しました:
public void createConsoleInput(final InputStream inputStream /* Obtained via process.getInputStream() */)
{
final Thread consoleThread = new Thread()
{
@Override
public void run()
{
final BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
consoleInput.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
try
{
String cmd = consoleInput.getText();
lastmessage = cmd;
System.out.println("» /" + cmd);
br.read(cmd.toCharArray());
consoleInput.setText("");
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
});
}
};
consoleThread.start();
}
上の図で「入力」とラベル付けしたフィールドは、加速すると actionPerformed() メソッドを実行します。ただし、次の行でフリーズしているようです。br.read(cmd.toCharArray());
プロセスが外部で強制終了された後、フリーズが解除されます。強制終了されるまで、 System.out の部分も実行しません。だから、私の質問は次のとおりです。これを適切に行うにはどうすればよいですか?
編集:
ライターに変えたらハングしなくなりました。代わりに、コンソール メッセージを出力するだけです。
public void createConsoleInput(final BufferedWriter writer)
{
final Thread consoleThread = new Thread()
{
@Override
public void run()
{
consoleInput.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
try
{
String cmd = consoleInput.getText();
lastmessage = cmd;
System.out.println("» /" + cmd);
writer.write(cmd);
consoleInput.setText("");
}
catch (IOException e1)
{
e1.printStackTrace();
}
}
});
}
};
consoleThread.start();
}
ライターには次のようにアクセスします。
BufferedWriter stdin = new BufferedWriter(new OutputStreamWriter(p.getOutputStream()));
EDIT 2:コードをいじってみましたが、何も修正されていないようです。間違ったストリームに書いているような気がします。