2009-08-10 13 views
9

Ich habe ein bisschen eine ungewöhnliche Frage: Wie kann ich eine "Command Console" mit Swing erstellen?Erstellen Sie eine "Command" -Konsole

Was ich haben möchte, ist eine Konsole, wo die Benutzer Befehle eingeben, drücken Sie die Eingabetaste, und die Ausgabe des Befehls wird unter angezeigt. Ich möchte dem Benutzer nicht erlauben, die "Eingabeaufforderung" und die ältere Ausgabe zu ändern. Ich denke an etwas wie Windows CMD.EXE.

Ich habe mir this Frage angesehen, aber es beantwortet meine Frage nicht.

+0

Meinst du sowas wie den BeanShell-Arbeitsbereich? – Kryten

+0

Warum würden Sie Swing verwenden? Was ist falsch daran, eine Java-Konsolenanwendung direkt zu erstellen? – Juliet

+0

Das ist eine bessere Antwort als die, an die ich dachte. :-) – Jay

Antwort

0

Mit Commandline können Sie beliebige Befehle mit Plexus ausführen. Es behandelt das Entweichen der Argumente, die umgebungsspezifische Ausführung und ermöglicht es Ihnen, Konsumenten an stdout und stderr anzuhängen, so dass Sie sich auf die Handhabung konzentrieren können.

Hier ist ein Link zu another answe r Ich gab, zeigt, wie Sie eine Befehlszeile einrichten und die Ausgabe verarbeiten können.

2

Wenn ich Ihre Frage richtig verstanden habe, möchten Sie Befehle ausführen, die für Ihre Anwendung spezifisch sind. Mein Rat wäre, wenn das tatsächlich der Fall ist, zwei Textareas zu verwenden, eine Zeile, die den Rest des Raumes einnimmt. Fügen Sie einige Keypress-Event-Handler zu dem kleinen, der bearbeitbar wäre, hinzu und machen Sie den anderen schreibgeschützt. Wenn Sie einen einzelnen Textbereich haben müssen, können Sie ihn schreibgeschützt machen und dann ein paar Tastendruck-Handler hinzufügen, um Zeicheneingabe und Auf-/Ab-Tastendrücke zu verarbeiten.

Ich hoffe, ich habe Ihre Frage richtig verstanden, viel Glück.

0

Ich würde Shortcuts (wie groovy/bohnenschale) nicht versuchen, es sei denn, sie passen genau auf Ihre Bedürfnisse. Zu versuchen, ein High-Level-Tool zu machen, was Sie wollen, wenn es nicht das ist, was es bereits tut, kann das Frustrierendste am Programmieren sein.

Es sollte ziemlich einfach sein, einen Textbereich und "machen Sie es zu Ihren", aber es wäre viel einfacher zu tun, wie jemand anderes vorgeschlagen und eine einzeilige Textsteuerung in Kombination mit einem mehrzeiligen Anzeigebereich verwenden .

In beiden Fällen wollen Sie ziemlich genau die Kontrolle über das gesamte System behalten, einige Tastenanschläge abfangen und filtern, die Eingabe in den "Anzeige" -Bereich deaktivieren, wenn Sie sich entscheiden, einen Klick auf Ihren Anzeigebereich zu senden Focus auf Ihr Eingabefeld, ...

Wenn Sie die Single-Box-Sache machen, sollten Sie sicherstellen, dass Ihre Eingabe immer am unteren Rand der Box ist und dass Sie ihre Cursorposition steuern (Sie wahrscheinlich nicht Ich möchte, dass sie in der Lage sind, eine Eingabe für jede Zeile außer der letzten Zeile vorzunehmen.

Ich schlage vor, dass Sie nicht davon ausgehen, dass eine einzige Kontrolle nur ohne Änderung funktioniert, erwarten Sie, die Beinarbeit zu tun, und alles wird gut.

1

Versuchen Sie diesen 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); 
} 

Es hat eine JPanel als Panel verwendet und eine JLabel als Konsole. Die Befehle werden an ein CommandListener-Objekt übergeben und der zurückgegebene Wert wird an die Konsole ausgegeben.

8

Beanshell bietet eine JConsole, eine Befehlszeile Eingabekonsole mit den folgenden Merkmalen:

  • ein blinkender Cursor
  • Befehl Geschichte
  • Cut/Copy/Paste, die Auswahl mit STRG + Pfeiltasten
  • Befehlserledigung
  • Unicode-Zeicheneingabe
  • farbige Textausgabe
  • ... und alles ist in einem Bildlauffenster verpackt.

Die Beanshell JAR-Dateien sind von http://www.beanshell.org/download.html verfügbar und die Quelle über SVN von svn co http://ikayzo.org/svn/beanshell

Für weitere Informationen über JConsole sehen http://www.beanshell.org/manual/jconsole.html

Hier ist ein Beispiel für die Verwendung Beanshell des JConsole in Ihrer Anwendung zur Verfügung:

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

    } 
} 

Hinweis: JConsole gibt ";" wenn Sie Enter selbst drücken.

+0

Dies funktioniert nicht für mich. Ich benutze 'bsh-2.0b4.jar'. Geben Sie 'quit' ein und drücken Sie die Enter-Taste, bringt nur den Cursor zur neuen Zeile. Die Hintergrundfarbe ist weiß. Die Buchstabenfarben sind schwarz. Ich sehe nie 'Sie tippte:'. –

0

Wenn Sie

etwas wie Windows CMD.EXE wollen.

Verwenden Sie cmd.exe. Alles, was Sie mit System.out.println("") drucken, wird dort angezeigt. Sie müssen eine .bat-Datei erstellen, in der sich die kompilierte Datei befindet.

echo off 
cls 
java -jar fileName.jar