Terminal Programmieren

Damarus

Mitglied
Hi,

ich hab mir als Langzeitaufgabe heute vorgenommen ein kleines Terminalprogramm zu programmieren. Eine funktionierende GUI in der ich ein Kommando eingeben kann, welches bei druck auf Enter ausgelesen wird, habe ich schon.
Nur scheitere ich nun an einem ziemlichen Kernpunkt. Und zwar weiß ich nicht wie ich nun mit Hilfe der Eingabe ein Kommando ausführen lassen kann. Ich könnte das ganze zwar so machen, dass ich alle vorhandenen Kommandos manuell in ein Array eingebe, überprüfe, mit welchem Fach die Eingabe übereinstimmt und dann über ein Switch-Case das entsprechende Kommando ausführe, aber das wäre ja ziemlich unflexibel und bei wachsender Anzahl an Kommandos würde das Programm immer langsamer werden.
Ich habe mir mal die Sourcecodes von diversen Open Source Java Terminals angesehen und bemerkt, dass dort die Kommandos in Hashtables ([c]java.util.Hashtable[/c]) gespeichert werden. Nur habe ich keine Ahnung, was das nun ist und wie man damit arbeitet (Aus der Dokumentation werde ich auch nicht schlau).
Am Ende hätte ich am liebsten pro Kommando eine Klasse (Die sich möglicherweise von einer Klasse "Command" o.Ä. ableiten). Also wie realisiere ich das?

Hier mal mein Code:
Java:
package com.damarus;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class JShell extends JPanel implements KeyListener {

	private static final long serialVersionUID = 1L;

	JTextField field = new JTextField();
	JEditorPane editor = new JEditorPane();

	public JShell() {
		super(new BorderLayout());

		// Content
		editor.setEditable(false);
		editor.setBackground(Color.LIGHT_GRAY);
		this.add(editor, BorderLayout.CENTER);

		field.addKeyListener(this);
		this.add(field, BorderLayout.PAGE_END);
	}

	@Override
	public void keyTyped(KeyEvent e) {

	}

	@Override
	public void keyPressed(KeyEvent e) {

	}

	@Override
	public void keyReleased(KeyEvent e) {
		// Wenn Enter gedrückt wird, wird die Eingabe in
		// editor übernommen und field geleert
		if (e.getKeyCode() == KeyEvent.VK_ENTER) {
			editor.setText(editor.getText() + field.getText() + "\n");
			field.setText("");
		}

	}

	public static void main(String[] args) {
		// GUI starten
		setUp();
	}

	public static void setUp() {
		// Frame
		JFrame frame = new JFrame("JShell");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(600, 300);

		JPanel panel = new JShell();
		frame.setContentPane(panel);

		frame.setLocationRelativeTo(null);
		frame.setVisible(true);
	}
}
 
Java API Doc - Hashtable hat gesagt.:
This class implements a hashtable, which maps keys to values.
Erster Satz in der Dok.

Das bedeutet, dass du in die Tabelle Schlüssel-/Wertepaare eintragen kannst:
Java:
Hashtable<Integer, String> table = new Hashtable<Integer, String>();
table.put(0, "zero");
table.put(1, "one");
// ...
String zero = table.get(0);
String one = table.get(1);

Hashtable heißt das Konstrukt deshalb, weil eine Hashfunktion verwendet wird, um die Objekte beim Einfügen an einen bestimmten Ort zu setzen (der sich aus der Hashfunktion ergibt) und beim Suchen wieder die Hashfunktion auf den Schlüssel angewendet wird, um den Wert (das "Ziel"objekt) schnell wieder zu finden. Eine gute Hashfunktion hat eine gute Streuung (=wenige Konflikte = wenige gleiche Objekte, die mit unterschiedlichen Schlüsseln das gleiche Ergebnis in der Hashfunktion haben). Aber keine Angst, um die Hashfunktion brauchst du dir bei gängigen Schlüsseltypen (String, Integer, ...) keine Gedanken zu machen. Die ist schon annähernd gut implementiert 😉

Stell dir ne Bibliothek vor, wo es ein Abholregal gibt, in dem vorbestellte Bücher einsortiert werden. Die Sortierung innerhalb des Regals läuft nach den beiden Endziffern der Ausweisnummer (Hashfunktion). Die Wahrscheinlichkeit, dass jemand mit den gleichen Endziffern im Ausweis auch ein Buch ausgeliehen hat (Konflikt), ist gering genug, dass du mit Hilfe des Buchtitels (Schlüssel) extrem schnell zu deinem Buch kommst.

Im Gegensatz zur "Standardtabelle" muss bei der Hashtable nicht jeder Eintrag mit dem gesuchten Schlüssel verglichen werden, was linearer Laufzeit entsprechen würde - bei sortierten Tabellen wäre es immerhin logarithmische Laufzeit.
Der Vorteil von Hashtables ist in der Tat die Geschwindigkeit. Für eine hinreichend gute Hashfunktion laufen die ganzen Prozesse (Einfügen, Herausnehmen, Löschen) nämlich (theoretisch) in erwarteter konstanter Laufzeit ab (egal wie groß die Tabelle ist).

Du könntest für dein Terminal eine Hashtable nehmen, die von String (=Befehl) auf Command (=auszuführendes Kommando) mappt.


EDIT: Es heißt oben natürlich [c]put[/c], nicht [c]add[/c] 😳
 
Zuletzt bearbeitet:
Frei vom Gewohnheitszentrum meines Hirns in die Tasten.

Java:
public abstract class Command
{
	public Command()
	{
		super();
	}
	public abstract void run(String... args);
}
public class HelloWorldCommand()
{
	public HelloWorldCommand()
	{
		super();
	}
	public void run(String... args)
	{
		System.out.println("Hello World");
	}
	public void toString()
	{
		return("HelloWorld");
	}
}
//....

private Map<String, Command> commandMap;

//...
commandMap = new HashMap<String, Command>();
//...

public void loadCommands()
{
	Command cmd = new HelloWorldCommand();
	commandMap.put(cmd.toString, cmd);
}
public void runCommand(String line)
{
	String[] split = Pattern.compile(" ").split(line, 0);
	Command cmd = commandMap.get(split[0]);
	if(cmd != null)
		cmd.run(split); //Erstes Parameter entfernen?
	else
		System.out.println("Befehl nicht gefunden"); //Zuerst auf lokale Anwendung prüfen?
}

To slow, again. 🙁
 

Neue Themen


Zurück
Oben