/*
** This file is part of Filius, a network construction and simulation software.
**
** Originally created at the University of Siegen, Institute "Didactics of
** Informatics and E-Learning" by a students' project group:
** members (2006-2007):
** André Asschoff, Johannes Bade, Carsten Dittich, Thomas Gerding,
** Nadja Haßler, Ernst Johannes Klebert, Michell Weyer
** supervisors:
** Stefan Freischlad (maintainer until 2009), Peer Stechert
** Project is maintained since 2010 by Christian Eibl <filius@c.fameibl.de>
** and Stefan Freischlad
** Filius is free software: you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation, either version 2 of the License, or
** (at your option) version 3.
**
** Filius is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied
** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
** PURPOSE. See the GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Filius. If not, see <http://www.gnu.org/licenses/>.
*/
package filius.gui.anwendungssicht;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowEvent;
import java.util.Observable;
import java.util.StringTokenizer;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.event.InternalFrameEvent;
import filius.Main;
import filius.software.lokal.Terminal;
import filius.software.system.Dateisystem;
import java.util.ArrayList;
/**
* Applikationsfenster fuer ein Terminal
*
* @author Johannes Bade & Thomas Gerding
*
*/
public class GUIApplicationTerminalWindow extends GUIApplicationWindow {
/**
*
*/
private static final long serialVersionUID = 1L;
private JTextArea terminalField;
private JPanel backPanel;
private JTextField inputField;
private JLabel inputLabel;
private JScrollPane tpPane;
private boolean jobRunning;
private String enteredCommand;
private String[] enteredParameters;
private boolean multipleObserverEvents;
ArrayList<String> terminalCommandList = new ArrayList<String>(); // für pfeil-nach-oben-holt-letzten-befehl-wieder
int terminalCommandListStep = -1;
public GUIApplicationTerminalWindow(GUIDesktopPanel desktop, String appName){
super(desktop, appName);
this.setMaximizable(false);
this.setResizable(false);
jobRunning = false;
multipleObserverEvents = false;
terminalField = new JTextArea("");
terminalField.setEditable(false);
terminalField.setCaretColor(new Color(222,222,222));
terminalField.setForeground(new Color(222,222,222));
terminalField.setBackground(new Color(0,0,0));
terminalField.setFont(new Font("Courier New",Font.PLAIN,11));
terminalField.setFocusable(false);
terminalField.setBorder(null);
tpPane = new JScrollPane(terminalField); // make textfield scrollable
tpPane.setBorder(null);
tpPane.setBackground(new Color(0,0,0));
tpPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER); // do not show vert. scrollbar
tpPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); // do not show hor. scrollbar
inputField = new JTextField("");
inputField.setEditable(true);
inputField.setBackground(new Color(0,0,0));
inputField.setForeground(new Color(222,222,222));
inputField.setCaretColor(new Color(222,222,222));
inputField.setBorder(null);
inputField.setFont(new Font("Courier New",Font.PLAIN,11));
inputField.addKeyListener(new KeyListener() {
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER) {
terminalCommandListStep = -1; // lass uns doch besser wieder von unten/vorne beginnen
if(!(inputField.getText().isEmpty() || inputField.getText().replaceAll(" ", "").isEmpty())) { // only process non-empty input
//Main.debug.println("DEBUG: "+getClass()+", keyPressed ('"+inputField.getText()+" + ENTER') event started");
terminalField.append("\n"+inputLabel.getText()+inputField.getText()+"\n");
StringTokenizer tk = new StringTokenizer(inputField.getText(), " ");
/* Erstes Token enthaelt den Befehl*/
enteredCommand = tk.nextToken();
/* restliche Tokens werden in String Array geschrieben.
* Array wird sicherheitshalber mit mindestens 3 leeren Strings gefüllt! */
enteredParameters = new String[3+tk.countTokens()];
for (int i =0; i< 3+tk.countTokens(); i++)
{
enteredParameters[i] = new String();
}
int iti = 0;
while (tk.hasMoreTokens())
{
enteredParameters[iti] =tk.nextToken();
iti++;
}
if (enteredCommand.equals("exit"))
{
doDefaultCloseAction();
}
else if (enteredCommand.equals("reset")) {
terminalField.setText( "" );
for (int i=0; i<15; i++) { terminalField.append(" \n"); } // padding with new lines for bottom alignment of new output
terminalField.append( "================================================================\n" );
terminalField.append(messages.getString("sw_terminal_msg25")
+ "================================================================"
+ "\n");
}
else
{
inputLabel.setVisible(false);
jobRunning = true;
terminalCommandList.add(inputField.getText());
((Terminal) holeAnwendung()).terminalEingabeAuswerten(enteredCommand,enteredParameters);
}
}
else { terminalField.append("\n"); }
//Main.debug.println("DEBUG: "+getClass()+", keyPressed ('"+inputField.getText()+" + ENTER') event finished");
inputField.setText("");
}
if (e.getKeyCode() == KeyEvent.VK_C && e.getModifiers() == 2) { // [strg] + [c]
System.out.println("INTERRUPT");
((Terminal) holeAnwendung()).setInterrupt(true);
}
if (e.getKeyCode() == KeyEvent.VK_UP || e.getKeyCode() == KeyEvent.VK_DOWN) { // 38 arrow-up / 40 arrow-down
if (e.getKeyCode() == KeyEvent.VK_UP) {
terminalCommandListStep++;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
terminalCommandListStep--;
}
if (terminalCommandListStep < -1) {
terminalCommandListStep = -1;
}
if (terminalCommandListStep >= terminalCommandList.size()) {
terminalCommandListStep = terminalCommandList.size() - 1;
}
try {
if (terminalCommandListStep != -1) {
inputField.setText(terminalCommandList.get(terminalCommandList.size() - 1 - terminalCommandListStep));
}
else if (terminalCommandListStep == -1) {
inputField.setText("");
}
}
catch (IndexOutOfBoundsException eis) {
}
}
}
public void keyReleased(KeyEvent arg0) {
}
public void keyTyped(KeyEvent arg0) {
}
});
inputLabel = new JLabel(">");
inputLabel.setBackground(new Color(0,0,0));
inputLabel.setForeground(new Color(222,222,222));
inputLabel.setFont(new Font("Courier New",Font.PLAIN,11));
Box terminalBox = Box.createHorizontalBox();
terminalBox.setBackground(new Color(0,0,0));
terminalBox.add(tpPane); // terminalField embedded in ScrollPane
terminalBox.setBorder(BorderFactory.createEmptyBorder(5,5,1,5));
Box inputBox = Box.createHorizontalBox();
inputBox.setBackground(new Color(0,0,0));
inputBox.add(inputLabel);
inputBox.add(Box.createHorizontalStrut(1));
inputBox.add(inputField);
inputBox.setBorder(BorderFactory.createEmptyBorder(0,5,5,5));
backPanel = new JPanel(new BorderLayout());
backPanel.setBackground(new Color(0,0,0));
backPanel.add(terminalBox, BorderLayout.CENTER);
backPanel.add(inputBox, BorderLayout.SOUTH);
this.getContentPane().add(backPanel);
terminalField.setText( "" );
for (int i=0; i<12; i++) { terminalField.append(" \n"); } // padding with new lines for bottom alignment of new output
terminalField.append( "================================================================\n" );
terminalField.append(messages.getString("sw_terminal_msg25"));
terminalField.append( "================================================================\n\n" );
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
this.tpPane.getVerticalScrollBar().setValue(this.tpPane.getVerticalScrollBar().getMaximum());
pack();
inputField.requestFocus();
this.inputLabel.setText("root "+Dateisystem.absoluterPfad(((Terminal)holeAnwendung()).getAktuellerOrdner())+"> ");
}
public void setMultipleObserverEvents(boolean flag) {
}
public void windowActivated(WindowEvent e) {
}
public void windowClosing(WindowEvent e) {
}
public void windowDeactivated(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) {
}
public void windowIconified(WindowEvent e) {
}
public void windowOpened(WindowEvent e) {
}
public void internalFrameActivated(InternalFrameEvent e) {
}
public void internalFrameClosed(InternalFrameEvent e) {
}
public void internalFrameClosing(InternalFrameEvent e) {
}
public void internalFrameDeactivated(InternalFrameEvent e) {
}
public void internalFrameDeiconified(InternalFrameEvent e) {
}
public void internalFrameIconified(InternalFrameEvent e) {
}
public void internalFrameOpened(InternalFrameEvent e) {
}
public void update(Observable arg0, Object arg1) {
Main.debug.println("INVOKED ("+this.hashCode()+") "+getClass()+" (GUIApplicationTerminalWindow), update("+arg0+","+arg1+")");
if (arg1 == null) return;
if (jobRunning) {
if (arg1 instanceof Boolean) {
multipleObserverEvents=((Boolean) arg1).booleanValue();
}
else { // expect String
this.terminalField.append(arg1.toString());
try {
// mini delay to let the terminalField reliably update its new height
Thread.sleep(200);
} catch (InterruptedException e) {}
this.tpPane.repaint();
this.tpPane.getVerticalScrollBar().setValue(this.tpPane.getVerticalScrollBar().getMaximum());
if (!multipleObserverEvents) { // is this observer call expected to be the last one for the current command, i.e., multipleOverserverEvents=false?
this.inputLabel.setText("root "+Dateisystem.absoluterPfad(((Terminal)holeAnwendung()).getAktuellerOrdner())+"> ");
this.inputLabel.setVisible(true);
jobRunning=false;
}
}
}
}
}