在 JavaFX 中创建本地终端模拟器应用程序

Create a Local Terminal Emulator App in JavaFX

我将如何着手在 javafx 中的 textarea 类型应用程序中创建本地终端。提前致谢!

try {
            String[] comm = new String[] {"/bin/bash", "-c", "open -a Terminal \"`pwd`\""};
            Runtime.getRuntime().exec(comm);
        } 
        
        catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

这是一个粗略的开始。

一个关键组件是使用 Process

Process process = Runtime.getRuntime().exec("command-here")

另一个关键组件是读取进程return数据。

BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) 
{
    System.out.println(line);
    
}  

我们将使用 Task 及其消息 属性 打印到我们的 TextArea.

而不是仅打印该行
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.TextArea;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;


/**
 * JavaFX App
 */
public class App extends Application 
{   
    TextArea textArea = new TextArea("ping www.google.com");
    
    @Override
    public void start(Stage stage) 
    {
        textArea.setOnKeyPressed((t) -> {
            try 
            {
                if(t.getCode() == KeyCode.ENTER)
                {
                    String[] splitText = textArea.getText().split("\n");
                    Process process = Runtime.getRuntime().exec(splitText[splitText.length -1]);
                    Task<Void> task = printResults(process);
                    task.messageProperty().addListener((obs, oldText, newText)->{
                        textArea.appendText(newText + "\n");
                    });
                    task.setOnSucceeded((workerStateEvent) -> {
                        textArea.setEditable(true);
                    });
                    Thread thread = new Thread(task);
                    thread.setDaemon(true);
                    thread.start();
                }
            } catch (IOException ex) 
            {
                Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
            }
        });
        
        var scene = new Scene(new StackPane(textArea), 640, 480);
        stage.setScene(scene);
        stage.show();
    }

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

    Task<Void> printResults(Process process)
    {
        textArea.setEditable(false);
        Task<Void> task = new Task<Void>() 
        {
            @Override protected Void call(){
                try 
                {
                    BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
                    String line = "";
                    while ((line = reader.readLine()) != null) 
                    {
                        updateMessage(line);
                    }   
                } 
                catch (IOException ex) 
                {
                    Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
                }

                return null;
            }
        };
            
        return task ;
    }   
}