创建一个“命令”控制台

时间:2009-08-10 14:53:40

标签: java swing console

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

我想要的是一个控制台,用户输入命令,按回车键,命令输出显示在。我不想让用户更改“提示”和旧输出。我在想像Windows CMD.EXE。

我查看了this个问题,但它没有回答我的问题。

7 个答案:

答案 0 :(得分:8)

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

  • 一个闪烁的光标
  • 命令历史记录
  • 剪切/复制/粘贴,包括使用CTRL +箭头键选择
  • 命令完成
  • Unicode字符输入
  • 彩色文字输出
  • ...这一切都包含在滚动窗格中。

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

获取

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

以下是在您的应用程序中使用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();
        }

    }
}

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

答案 1 :(得分:3)

看看Groovy Console。这就是它的样子:

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

虽然它是Groovy的控制台而不是任意命令,但您应该能够从中调整想法和/或代码以获得所需的内容。

答案 2 :(得分:2)

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

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

答案 3 :(得分:1)

试试这段代码:

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);
}

它使用JPanel作为面板,使用JLabel作为控制台。这些命令将传递给CommandListener对象,并将返回的值打印到控制台。

答案 4 :(得分:0)

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

这是我给出的another answe r的链接,展示了如何设置命令行并处理输出。

答案 5 :(得分:0)

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

采用文本区域和“自己制作”应该相当容易,但是像其他人建议的那样更容易,并且使用单行文本控件和多行显示区域。

在任何一种情况下,你想要对整个系统保持非常接近的控制,拦截并过滤一些击键,如果你决定使用它,禁用“显示”区域的输入,强制点击显示区域以发送焦点到您的输入字段,...

如果您执行单个框的操作,您需要确保输入始终位于框的底部,并且您可以控制它们的光标位置(您可能不希望它们能够对任何输入执行任何输入除最后一行之外的行。)

我建议你不要假设一个控件只是在没有修改的情况下工作,期望做好腿部工作,一切都会好的。

答案 6 :(得分:0)

如果你想要

  

类似于Windows CMD.EXE。

使用cmd.exe。您使用System.out.println("")打印的所有内容都会显示在那里。您需要做的是创建一个.bat文件,其中包含您的编译文件。

echo off
cls
java -jar fileName.jar