java 创建一个“命令”控制台

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1255373/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 15:50:26  来源:igfitidea点击:

Create a "Command" Console

javaswingconsole

提问by

I have a bit of an unusual question: How can I create a "Command Console" using Swing?

我有一个不寻常的问题:如何使用 Swing 创建“命令控制台”?

What I want to have is a console where the users type in commands, press enter, and the output from the command is displayed under. I don't want to allow the user to change the "prompt" and older output. I am thinking of something like Windows CMD.EXE.

我想要的是一个控制台,用户可以在其中输入命令,按 Enter,然后命令的输出就会显示在下面。我不想让用户更改“提示”和较旧的输出。我在想像 Windows CMD.EXE 这样的东西。

I had a look at thisquestion, however it doesn't answer my question.

我看过这个问题,但它没有回答我的问题。

回答by tekumara

BeanShell provides a JConsole, a command line input console with the following features:

BeanShell 提供了一个 JConsole,一个命令行输入控制台,具有以下功能:

  • a blinking cursor
  • command history
  • cut/copy/paste including selection with CTRL+arrow keys
  • command completion
  • Unicode character input
  • coloured text output
  • ...and it all comes wrapped in a scroll pane.
  • 闪烁的光标
  • 命令历史
  • 剪切/复制/粘贴,包括使用 CTRL+箭头键进行选择
  • 命令完成
  • Unicode 字符输入
  • 彩色文本输出
  • ...这一切都包含在滚动窗格中。

The BeanShell JARs are available from http://www.beanshell.org/download.htmland the source is available via SVN from svn co http://ikayzo.org/svn/beanshell

BeanShell JAR 可从http://www.beanshell.org/download.html 获得,源代码可通过 SVN 从svn co http://ikayzo.org/svn/beanshell

For more info on JConsole see http://www.beanshell.org/manual/jconsole.html

有关 JConsole 的更多信息,请参阅http://www.beanshell.org/manual/jconsole.html

Here is an example of using BeanShell's JConsole in your application:

以下是在您的应用程序中使用 BeanShell 的 JConsole 的示例:

import java.awt.Color;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;

import javax.swing.JFrame;

import bsh.util.GUIConsoleInterface;
import bsh.util.JConsole;

/** 
 * Example of using the BeanShell project's JConsole in
 * your own application.
 * 
 * JConsole is a command line input console that has support 
 * for command history, cut/copy/paste, a blinking cursor, 
 * command completion, Unicode character input, coloured text 
 * output and comes wrapped in a scroll pane.
 * 
 * For more info, see http://www.beanshell.org/manual/jconsole.html
 * 
 * @author tukushan
 */
public class JConsoleExample {

    public static void main(String[] args) {

        //define a frame and add a console to it
        JFrame frame = new JFrame("JConsole example");

        JConsole console = new JConsole();

        frame.getContentPane().add(console);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600,400);

        frame.setVisible(true);

        inputLoop(console, "JCE (type 'quit' to exit): ");

        System.exit(0);
    }

    /**
     * Print prompt and echos commands entered via the JConsole
     * 
     * @param console a GUIConsoleInterface which in addition to 
     *         basic input and output also provides coloured text
     *         output and name completion
     * @param prompt text to display before each input line
     */
    private static void inputLoop(GUIConsoleInterface console, String prompt) {
        Reader input = console.getIn();
        BufferedReader bufInput = new BufferedReader(input);

        String newline = System.getProperty("line.separator");

        console.print(prompt, Color.BLUE);

        String line;
        try {
            while ((line = bufInput.readLine()) != null) {
                console.print("You typed: " + line + newline, Color.ORANGE);

                // try to sync up the console
                //System.out.flush();
                //System.err.flush();
                //Thread.yield();  // this helps a little

                if (line.equals("quit")) break; 
                console.print(prompt, Color.BLUE);
            }
            bufInput.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

NB: JConsole returns ";" if you hit Enter by itself.

注意:JConsole 返回“;” 如果您自己按 Enter 键。

回答by Vinay Sajip

Take a look at the Groovy Console. This is what it looks like:

看看Groovy 控制台。这是它的样子:

Groovy Console http://groovy.codehaus.org/download/attachments/36800/GroovyConsole.gif

Groovy 控制台 http://groovy.codehaus.org/download/attachments/36800/GroovyConsole.gif

Although it's a console for Groovy rather than arbitrary commands, you should be able to adapt ideas and/or code from it to get what you need.

尽管它是 Groovy 的控制台而不是任意命令,但您应该能够从中调整想法和/或代码以获得您需要的东西。

回答by Jeff Cooper

If I understand your question correctly, you're looking to execute commands specific to your application. My advice would be, if this is in fact the case, to use two textareas, one that's a single line and one that takes up the rest of the space. Add some keypress event handlers to the small one, which would be editable, and make the other one read-only. If you must have a single text area, you could make it read-only and then add a few keypress handlers to handle character input and up/down keypresses.

如果我正确理解了您的问题,那么您希望执行特定于您的应用程序的命令。我的建议是,如果事实确实如此,使用两个 textareas,一个是一行,一个占据其余空间。将一些按键事件处理程序添加到可编辑的小事件处理程序中,并使另一个成为只读事件处理程序。如果您必须有一个文本区域,您可以将其设为只读,然后添加一些按键处理程序来处理字符输入和向上/向下按键。

Hope I've understood your question correctly, best of luck.

希望我已经正确理解了你的问题,祝你好运。

回答by Kryten

Try this code:

试试这个代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

/**
 *
 * @author Alistair
 */
public class Console extends JPanel implements KeyListener {

    private static final long serialVersionUID = -4538532229007904362L;
    private JLabel keyLabel;
    private String prompt = "";
    public boolean ReadOnly = false;
    private ConsoleVector vec = new ConsoleVector();
    private ConsoleListener con = null;
    private String oldTxt = "";
    private Vector history = new Vector();
    private int history_index = -1;
    private boolean history_mode = false;

    public Console() {
        super();
        setSize(300, 200);
        setLayout(new FlowLayout(FlowLayout.CENTER));
        keyLabel = new JLabel("");
        setFocusable(true);
        keyLabel.setFocusable(true);
        keyLabel.addKeyListener(this);
        addKeyListener(this);
        add(keyLabel);
        setVisible(true);
    }

    public void registerConsoleListener(ConsoleListener c) {
        this.con = c;
    }

    public String getPrompt() {
        return this.prompt;
    }

    public void setPrompt(String s) {
        this.prompt = s;
    }

    private void backspace() {
        if (!this.vec.isEmpty()) {
            this.vec.remove(this.vec.size() - 1);
            this.print();
        }
    }

    @SuppressWarnings("unchecked")
    private void enter() {
        String com = this.vec.toString();
        String return$ = "";
        if (this.con != null) {
            return$ = this.con.receiveCommand(com);
        }

        this.history.add(com);
        this.vec.clear();
        if (!return$.equals("")) {
            return$ = return$ + "<br>";
        }
        // <HTML> </HTML>
        String h = this.keyLabel.getText().substring(6, this.keyLabel.getText().length() - 7);
        this.oldTxt = h.substring(0, h.length() - 1) + "<BR>" + return$;
        this.keyLabel.setText("<HTML>" + this.oldTxt + this.prompt + "_</HTML>");
    }

    private void print() {
        this.keyLabel.setText("<HTML>" + this.oldTxt + this.prompt + this.vec.toString() + "_</HTML>");
        this.repaint();
    }

    @SuppressWarnings("unchecked")
    private void print(String s) {
        this.vec.add(s);
        this.print();
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
        this.handleKey(e);
    }

    private void history(int dir) {
        if (this.history.isEmpty()) {
            return;
        }
        if (dir == 1) {
            this.history_mode = true;
            this.history_index++;
            if (this.history_index > this.history.size() - 1) {
                this.history_index = 0;
            }
            // System.out.println(this.history_index);
            this.vec.clear();
            String p = (String) this.history.get(this.history_index);
            this.vec.fromString(p.split(""));

        } else if (dir == 2) {
            this.history_index--;
            if (this.history_index < 0) {
                this.history_index = this.history.size() - 1;
            }
            // System.out.println(this.history_index);
            this.vec.clear();
            String p = (String) this.history.get(this.history_index);
            this.vec.fromString(p.split(""));
        }

        print();
    }

    private void handleKey(KeyEvent e) {

        if (!this.ReadOnly) {
            if (e.getKeyCode() == 38 | e.getKeyCode() == 40) {
                if (e.getKeyCode() == 38) {
                    history(1);
                } else if (e.getKeyCode() == 40 & this.history_mode != false) {
                    history(2);
                }
            } else {
                this.history_index = -1;
                this.history_mode = false;
                if (e.getKeyCode() == 13 | e.getKeyCode() == 10) {
                    enter();
                } else if (e.getKeyCode() == 8) {
                    this.backspace();
                } else {
                    if (e.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
                        this.print(String.valueOf(e.getKeyChar()));
                    }
                }
            }
        }
    }
}


class ConsoleVector extends Vector {

    private static final long serialVersionUID = -5527403654365278223L;

    @SuppressWarnings("unchecked")
    public void fromString(String[] p) {
        for (int i = 0; i < p.length; i++) {
            this.add(p[i]);
        }
    }

    public ConsoleVector() {
        super();
    }

    @Override
    public String toString() {
        StringBuffer s = new StringBuffer();
        for (int i = 0; i < this.size(); i++) {
            s.append(this.get(i));
        }
        return s.toString();
    }
}

public interface ConsoleListener {
    public String receiveCommand(String command);
}

It uses a JPanel as the panel and a JLabel as the console. The commands are passed to a CommandListener object and the returned value is printed to the console.

它使用 JPanel 作为面板,使用 JLabel 作为控制台。命令被传递到一个 CommandListener 对象,返回的值被打印到控制台。

回答by Marlon Abeykoon

If you want

如果你想

something like Windows CMD.EXE.

类似于 Windows CMD.EXE。

use cmd.exe. All you print using System.out.println("")will appear there. What you have to do is create a .bat file where your compiled file is.

使用 cmd.exe。您打印使用的所有内容System.out.println("")都会出现在那里。您需要做的是在您编译的文件所在的位置创建一个 .bat 文件。

echo off
cls
java -jar fileName.jar

回答by Bill K

I wouldn't try shortcuts (like groovy/beanshell) unless they fit your needs exactly. Trying to make a high-level tool do what you want when it's not what it already does can be the most frustrating thing about programming.

我不会尝试使用快捷方式(例如 groovy/beanshell),除非它们完全符合您的需求。试图让一个高级工具做你想做的事情,而它已经不是它已经做的事情,这可能是编程中最令人沮丧的事情。

It should be fairly easy to take a text area and "Make it your own", but it would be much easier to do as someone else suggested and use a one-line text control combined with a multi-line display area.

使用文本区域并“使其成为您自己的”应该相当容易,但是按照其他人的建议并使用单行文本控件与多行显示区域相结合会容易得多。

In either case you want to keep pretty close control on the whole system, intercept and filter some keystrokes, disable input to the "Display" area if you decide to go with that, force a click on your display area to send focus to your input field, ...

在任何一种情况下,您都希望对整个系统保持非常密切的控制,拦截和过滤一些击键,如果您决定这样做,则禁用“显示”区域的输入,强制单击您的显示区域以将焦点发送到您的输入场地, ...

If you do the single box thing, you'll want to make sure your input is always at the bottom of the box and that you control their cursor positioning (you probably don't want them able to do any input to any line except the last line).

如果你做单框的事情,你会想确保你的输入总是在框的底部,并且你控制他们的光标定位(你可能不希望他们能够对任何行进行任何输入,除了最后一行)。

I suggest you don't assume a single control is just going to work without modification, expect to do the legwork and everything will be fine.

我建议您不要假设单个控件无需修改就可以工作,而是期望进行跑腿工作,一切都会好起来的。

回答by Rich Seller

You can execute arbitrary commands with Plexus using Commandline. It handles escaping of the arguments, environment specific execution, and allows you to attach consumers to stdout and stderr, leaving you to focus on the handling.

您可以使用命令行通过 Plexus 执行任意命令。它处理参数的转义、特定于环境的执行,并允许您将使用者附加到 stdout 和 stderr,让您专注于处理。

Here's a link to another answer I gave, showing how you can set up a Commandline and handle the output.

这是我给出的另一个答案的链接,展示了如何设置命令行和处理输出。