gpt4 book ai didi

java - 如何将 System.in 重定向到 JavaFX TextField?

转载 作者:行者123 更新时间:2023-12-04 22:46:08 25 4
gpt4 key购买 nike

我正在研究新项目。我正在尝试通过以太网从 Java 向外部计算机 (Linux) 发送命令。我正在使用 Jsch 创建 shell 连接。我将 shell 输入和输出设置为 System.out 和 System.in。

((ChannelShell)channel).setInputStream(System.in);
((ChannelShell)channel).setOutputStream(System.out);

它在控制台中有效!但我需要从 javafx GUI 应用程序远程它。我已经解决了将 System.out 重定向到 TextArea 的问题:

    public void redirectOutputStream() {
OutputStream out = new OutputStream() {

private final StringBuilder sb = new StringBuilder();

@Override
public void write(int b) throws IOException {
if (b == '\r') {
return;
}

if (b == '\n') {
final String tmp = sb.toString() + "\n";
text.add(tmp);
updateText(text);
sb.setLength(0);
} else {
sb.append((char) b);
}
}
};

System.setOut(new PrintStream(out, true));
// System.setErr(new PrintStream(out, true));
}

但现在我还需要将 System.in 重定向到 TextField,这样我就可以在 TextField 中写入一些内容,按回车键并通过 shell 将其发送到外部计算机。

如有任何帮助,我们将不胜感激。谢谢!

编辑:抱歉,对我仍然不起作用:( ...现在我有了这段代码(我正在使用 javafx):

/** Tmp queue for standard input redirecting */
BlockingQueue<Integer> stdInQueue = new LinkedBlockingQueue<>();



@Override
public void initialize(URL arg0, ResourceBundle arg1) {
redirectOutputStream();
redirectInputStream();
}


/** redirects standard System.out to GUI command_window */
public void redirectOutputStream() {
OutputStream out = new OutputStream() {

private final StringBuilder sb = new StringBuilder();

@Override
public void write(int b) throws IOException {
if (b == '\r') {
return;
}
if (b == '\n') {
final String tmp = sb.toString() + "\n";
text.add(tmp);
updateText(text);
sb.setLength(0);
} else {
sb.append((char) b);
}
}
};
System.setOut(new PrintStream(out, true));
System.setErr(new PrintStream(out, true));
}

/** redirects standard System.in to GUI command_line */
public void redirectInputStream() {
InputStream in = new InputStream() {

@Override
public int read() throws IOException {
try {
int c = stdInQueue.take().intValue();
return c;
} catch (InterruptedException exc) {
Thread.currentThread().interrupt();
return -1;
}
}
};
System.setIn(in);
}


@FXML
void sendButtonPressed(ActionEvent event) {
if (!command_line.getText().isEmpty()) {
for (char c : command_line.getText().toCharArray()) {
System.out.write(new Integer(c)); //display in ListView (output)
stdInQueue.add(new Integer(c));
}
System.out.write(new Integer('\n')); //display in ListView (output)
stdInQueue.add(new Integer('\n'));
command_line.clear();
}
}

System.out 和 System.err 的重定向工作得很好。它正在显示在 javafx ListView 中。

问题仍然是在 ListView 下我有一个“命令行”javafx TextField,我需要将一些 ssh 命令写入此 TextField 并在按“输入”或单击“发送”按钮时将其重定向到 System.in .

之所以需要这样做,是因为我使用的是SSH通信,是为System.in和System.out设置的。它完全适用于控制台(已测试),但不适用于我的 GUI 应用程序。

感谢任何进一步的建议!

最佳答案

你可以设置一个BlockingQueue<Integer>将单个字符发送到,然后让输入流从中获取字符:

BlockingQueue<Integer> stdInQueue = new LinkedBlockingQueue<>();

System.setIn(new InputStream() {

@Override
public int read() throws IOException {
try {
int c = stdInQueue.take().intValue();
return c;
} catch (InterruptedException exc) {
Thread.currentThread().interrupt();
return -1 ;
}
}
});

textField.setOnAction(e -> {
for (char c : textField.getText().toCharArray()) {
stdInQueue.add(new Integer(c));
}
stdInQueue.add(new Integer('\n'));
textField.clear();
});

这是一个快速演示:为了测试,我只是设置了一个从 System.in 读取的后台线程:

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.TextField;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class StdInFromTextField extends Application {

@Override
public void start(Stage primaryStage) {

TextField textField = new TextField();

BlockingQueue<Integer> stdInQueue = new LinkedBlockingQueue<>();

System.setIn(new InputStream() {

@Override
public int read() throws IOException {
try {
int c = stdInQueue.take().intValue();
return c;
} catch (InterruptedException exc) {
Thread.currentThread().interrupt();
return -1 ;
}
}
});

textField.setOnAction(e -> {
for (char c : textField.getText().toCharArray()) {
stdInQueue.add(new Integer(c));
}
stdInQueue.add(new Integer('\n'));
textField.clear();
});

// for testing:
Thread readThread = new Thread(() -> {
try {
int i ;
while ((i = System.in.read()) != -1) {
System.out.print((char)i);
}
} catch (IOException exc) {
exc.printStackTrace();
}
});
readThread.setDaemon(true);
readThread.start();

primaryStage.setScene(new Scene(new StackPane(textField), 300, 120));
primaryStage.show();
}

public static void main(String[] args) {
launch(args);
}
}

关于java - 如何将 System.in 重定向到 JavaFX TextField?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41267435/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com