JPanel 中的 Java Linux 终端
- 2024-10-23 08:47:00
- admin 原创
- 59
问题描述:
我正在制作一个脚本编辑器,希望能够运行程序中的 Bash/Shell/Python/等脚本...到目前为止,我有办法运行它们,但是脚本无法让用户输入;代码如下:
package com.hightide.ui.terminal;
import javax.swing.*;
import java.awt.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
/**
* Created by peter on 9/1/15.
*/
public class JTerminal extends JPanel {
private final JTextArea jta;
public JTerminal(){
super();
setLayout(new BorderLayout());
jta = new JTextArea("-- HIGH TIDE SCRIPTING EDITOR VERSION 0.0 --
");
jta.setBackground(Color.BLACK);
jta.setForeground(Color.WHITE);
jta.setEditable(false);
JScrollPane jsp = new JScrollPane(jta);
add(jsp, BorderLayout.CENTER);
}
private void execute(String command){
try {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(command);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));
System.out.println("Here is the standard output of the command:
");
String s;
Boolean more = true;
while (more) {
s = stdInput.readLine();
if (s != null) {
jta.append(s);
}else more = false;
}
jta.append("
Errors:
");
more = true;
while (more){
s = stdError.readLine();
if (s != null) {
jta.append(stdError.readLine());
}else{
more = false;
}
}
}catch(Exception e){
System.out.println("Something went wrong:
"+e.getMessage());
}
}
@SuppressWarnings("unused")
public void run(File f, String runWith, String options){ //OPTIONS MUST BE BLANK NOT NULL IF NO OPTIONS
execute(runWith+" "+f.getAbsolutePath()+" "+options);
}
}
非常感谢任何帮助/想法!!!
解决方案 1:
这是我之前对关于在 内部执行终端命令的问题的回答的修改JTextArea
,但阻止用户修改之前输出的文本......
此版本增加了向正在运行的进程发送文本的功能
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringJoiner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
public class QuickTerminal {
public static void main(String[] args) {
new QuickTerminal();
}
public QuickTerminal() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ConsolePane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public interface CommandListener {
public void commandOutput(String text);
public void commandCompleted(String cmd, int result);
public void commandFailed(Exception exp);
}
public class ConsolePane extends JPanel implements CommandListener, Terminal {
private JTextArea textArea;
private int userInputStart = 0;
private Command cmd;
public ConsolePane() {
cmd = new Command(this);
setLayout(new BorderLayout());
textArea = new JTextArea(20, 30);
((AbstractDocument) textArea.getDocument()).setDocumentFilter(new ProtectedDocumentFilter(this));
add(new JScrollPane(textArea));
InputMap im = textArea.getInputMap(WHEN_FOCUSED);
ActionMap am = textArea.getActionMap();
Action oldAction = am.get("insert-break");
am.put("insert-break", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
int range = textArea.getCaretPosition() - userInputStart;
try {
String text = textArea.getText(userInputStart, range).trim();
System.out.println("[" + text + "]");
userInputStart += range;
if (!cmd.isRunning()) {
cmd.execute(text);
} else {
try {
cmd.send(text + "
");
} catch (IOException ex) {
appendText("!! Failed to send command to process: " + ex.getMessage() + "
");
}
}
} catch (BadLocationException ex) {
Logger.getLogger(QuickTerminal.class.getName()).log(Level.SEVERE, null, ex);
}
oldAction.actionPerformed(e);
}
});
}
@Override
public void commandOutput(String text) {
SwingUtilities.invokeLater(new AppendTask(this, text));
}
@Override
public void commandFailed(Exception exp) {
SwingUtilities.invokeLater(new AppendTask(this, "Command failed - " + exp.getMessage()));
}
@Override
public void commandCompleted(String cmd, int result) {
appendText("
> " + cmd + " exited with " + result + "
");
appendText("
");
}
protected void updateUserInputPos() {
int pos = textArea.getCaretPosition();
textArea.setCaretPosition(textArea.getText().length());
userInputStart = pos;
}
@Override
public int getUserInputStart() {
return userInputStart;
}
@Override
public void appendText(String text) {
textArea.append(text);
updateUserInputPos();
}
}
public interface UserInput {
public int getUserInputStart();
}
public interface Terminal extends UserInput {
public void appendText(String text);
}
public class AppendTask implements Runnable {
private Terminal terminal;
private String text;
public AppendTask(Terminal textArea, String text) {
this.terminal = textArea;
this.text = text;
}
@Override
public void run() {
terminal.appendText(text);
}
}
public class Command {
private CommandListener listener;
private ProcessRunner runner;
public Command(CommandListener listener) {
this.listener = listener;
}
public boolean isRunning() {
return runner != null && runner.isAlive();
}
public void execute(String cmd) {
if (!cmd.trim().isEmpty()) {
List<String> values = new ArrayList<>(25);
if (cmd.contains("\"")) {
while (cmd.contains("\"")) {
String start = cmd.substring(0, cmd.indexOf("\""));
cmd = cmd.substring(start.length());
String quote = cmd.substring(cmd.indexOf("\"") + 1);
cmd = cmd.substring(cmd.indexOf("\"") + 1);
quote = quote.substring(0, cmd.indexOf("\""));
cmd = cmd.substring(cmd.indexOf("\"") + 1);
if (!start.trim().isEmpty()) {
String parts[] = start.trim().split(" ");
values.addAll(Arrays.asList(parts));
}
values.add(quote.trim());
}
if (!cmd.trim().isEmpty()) {
String parts[] = cmd.trim().split(" ");
values.addAll(Arrays.asList(parts));
}
for (String value : values) {
System.out.println("[" + value + "]");
}
} else {
if (!cmd.trim().isEmpty()) {
String parts[] = cmd.trim().split(" ");
values.addAll(Arrays.asList(parts));
}
}
runner = new ProcessRunner(listener, values);
}
}
public void send(String cmd) throws IOException {
runner.write(cmd);
}
}
public class ProcessRunner extends Thread {
private List<String> cmds;
private CommandListener listener;
private Process process;
public ProcessRunner(CommandListener listener, List<String> cmds) {
this.cmds = cmds;
this.listener = listener;
start();
}
@Override
public void run() {
try {
System.out.println("cmds = " + cmds);
ProcessBuilder pb = new ProcessBuilder(cmds);
pb.redirectErrorStream();
process = pb.start();
StreamReader reader = new StreamReader(listener, process.getInputStream());
// Need a stream writer...
int result = process.waitFor();
// Terminate the stream writer
reader.join();
StringJoiner sj = new StringJoiner(" ");
cmds.stream().forEach((cmd) -> {
sj.add(cmd);
});
listener.commandCompleted(sj.toString(), result);
} catch (Exception exp) {
exp.printStackTrace();
listener.commandFailed(exp);
}
}
public void write(String text) throws IOException {
if (process != null && process.isAlive()) {
process.getOutputStream().write(text.getBytes());
process.getOutputStream().flush();
}
}
}
public class StreamReader extends Thread {
private InputStream is;
private CommandListener listener;
public StreamReader(CommandListener listener, InputStream is) {
this.is = is;
this.listener = listener;
start();
}
@Override
public void run() {
try {
int value = -1;
while ((value = is.read()) != -1) {
listener.commandOutput(Character.toString((char) value));
}
} catch (IOException exp) {
exp.printStackTrace();
}
}
}
public class ProtectedDocumentFilter extends DocumentFilter {
private UserInput userInput;
public ProtectedDocumentFilter(UserInput userInput) {
this.userInput = userInput;
}
public UserInput getUserInput() {
return userInput;
}
@Override
public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {
if (offset >= getUserInput().getUserInputStart()) {
super.insertString(fb, offset, string, attr);
}
}
@Override
public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
if (offset >= getUserInput().getUserInputStart()) {
super.remove(fb, offset, length); //To change body of generated methods, choose Tools | Templates.
}
}
@Override
public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
if (offset >= getUserInput().getUserInputStart()) {
super.replace(fb, offset, length, text, attrs); //To change body of generated methods, choose Tools | Templates.
}
}
}
}
所以,我自己编写了一个非常简单的 Windows 批处理文件......
@echo off
@echo Hello World!
set /p pathName=Enter The Value:%=%
@echo %pathName%
它并没有做太多的事情,它输出“Hello World!”并提示用户输入一个值,该值进一步回显到屏幕上然后终止......
并用它来测试上述代码......
相关推荐
热门文章
项目管理软件有哪些?
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件
热门标签
云禅道AD