Create a Local Terminal Emulator App in JavaFX

Viewed 622

How would I go about creating a local terminal in textarea type of app in javafx. Thank you in advance!

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();
        }
1 Answers

Here is a rough start.

One key component is to use Process.

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

Another key component is to read the process return data.

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

Instead of just printing the line, we will use Task and its message property to print to our 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 ;
    }   
}

enter image description here

Related