Code aus dem c't Projekt Applet eingecheckt
authorfelix <felix@a944a559-bf0e-0410-8ddc-85264b264b6c>
Mon, 12 Feb 2007 19:21:57 +0000 (19:21 +0000)
committerfelix <felix@a944a559-bf0e-0410-8ddc-85264b264b6c>
Mon, 12 Feb 2007 19:21:57 +0000 (19:21 +0000)
git-svn-id: https://www.internetallee.de/svn/bytewurf@2 a944a559-bf0e-0410-8ddc-85264b264b6c

projekte/netzschalter/src/Communication.java [new file with mode: 0644]
projekte/netzschalter/src/GUI.java [new file with mode: 0644]
projekte/netzschalter/src/IOControl.java [new file with mode: 0644]
projekte/netzschalter/src/TimerEvent.java [new file with mode: 0644]

diff --git a/projekte/netzschalter/src/Communication.java b/projekte/netzschalter/src/Communication.java
new file mode 100644 (file)
index 0000000..3fd3a52
--- /dev/null
@@ -0,0 +1,375 @@
+/*\r
+ * File Communication.java\r
+ */\r
+\r
+import java.io.BufferedReader;\r
+//import java.io.BufferedWriter;\r
+import java.io.DataInputStream;\r
+import java.io.DataOutputStream;\r
+import java.io.IOException;\r
+import java.io.InputStreamReader;\r
+import java.io.InterruptedIOException;\r
+//import java.io.OutputStreamWriter;\r
+import java.net.InetAddress;\r
+import java.net.Socket;\r
+import java.net.UnknownHostException;\r
+\r
+/**\r
+ * @author olz\r
+ * \r
+ * This class does the TCP/IP work to operate the XPort Most of the get and set\r
+ * methods herein follow the same pattern: Establish a connection, prepare a\r
+ * command, send this command and disconnect.\r
+ *  \r
+ */\r
+public class Communication {\r
+\r
+    /** connection to XPort */\r
+    protected Socket socket = null;\r
+\r
+    /** dis contains data provided by XPort */\r
+    protected BufferedReader dis = null;\r
+    \r
+    protected DataInputStream dis2 =null;\r
+    \r
+    /** dos contains data sent to XPort */\r
+    protected DataOutputStream dos=null;\r
+    \r
+    /**\r
+     * This method converts the given String ipa_str and the int port into a\r
+     * useable TCP/IP address and then calls a helper method tcpip_connect() to\r
+     * establish a connection to the XPort\r
+     * \r
+     * @param ipa_str\r
+     * @param port\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public void connect(String ipa_str, int port) throws IOException, Exception {\r
+        InetAddress ipa = null;\r
+        try {\r
+            ipa = InetAddress.getByName(ipa_str);\r
+        } catch (UnknownHostException UHEx) {\r
+            throw UHEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        try {\r
+            tcpip_connect(ipa, port);\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * this method will end the current connection to the XPort\r
+     * \r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public synchronized void disconnect() throws IOException, Exception {\r
+        try {\r
+            tcpip_disconnect();\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * uses a TCP/IP connection to send a String to the XPort\r
+     * \r
+     * @param sendString\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public synchronized void send(String sendString) throws IOException,\r
+            Exception {\r
+        System.out.println(sendString);\r
+        try {\r
+            dos.writeBytes(sendString);//, 0, sendString.length());\r
+            // write data to dos as String starting at String[0]\r
+            // and ending at String[String.length()]\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        try {\r
+            dos.flush(); // write dos to XPort\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        return;\r
+    }\r
+\r
+    /**\r
+     * uses a TCP/IP connection to send a String to the XPort\r
+     * \r
+     * @param sendByte\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public synchronized void send(int sendByte[]) throws IOException,\r
+            Exception {\r
+       int dummy;\r
+        try {\r
+               for (int i = 0; i < sendByte.length; i++) {\r
+                       dummy= sendByte[i] & 255;\r
+                dos.write(dummy); // bytewise write data to dos\r
+            }\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        try {\r
+            dos.flush(); // write dos to XPort\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+\r
+        return;\r
+    }\r
+\r
+    /**\r
+     * closes the TCP/IP connection\r
+     * \r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    private void tcpip_disconnect() throws IOException, Exception {\r
+        if (socket.isConnected()) {\r
+            try {\r
+                dis.close(); // close input and output stream\r
+                dos.close(); // as well as the socket\r
+                socket.close();\r
+            } catch (IOException IOEx) {\r
+                throw IOEx;\r
+            } catch (Exception Ex) {\r
+                throw Ex;\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * reads data supplied by the XPort and returns a String\r
+     * \r
+     * @return\r
+     * @throws InterruptedIOException\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public String receiveString() throws InterruptedIOException, IOException,\r
+            Exception {\r
+        String antwort = "";\r
+        int length=255;\r
+        byte[] in = new byte[length];\r
+        \r
+        try {\r
+            dis.ready(); // check if data is available (actually redundant since\r
+            // the calling method from the GUI class already made\r
+            // this sure but better safe than sorry... :-)\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        \r
+        try {\r
+               \r
+            length = readBuffer(in,length); // call helper method to read from dis\r
+            antwort= new String(in,0,length);\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        return antwort;\r
+    }\r
+\r
+    /**\r
+     * this method will read from DataInputStream dis, convert the chars read\r
+     * into ASCII and return its answer as a String\r
+     * \r
+     * @return\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public synchronized int readBuffer(int[] gelesen,int length) throws IOException, Exception {\r
+        int i=0; // init helper variables\r
+        //byte [] gelesen = new byte[length.intValue()];\r
+        \r
+        while ((dis.ready())& (i<length)){  // loop while data available\r
+               if (gelesen!=null)\r
+                       gelesen[i++]=dis2.readUnsignedByte();// read from dis\r
+               else \r
+                       dis2.readUnsignedByte();// read from dis\r
+        }\r
+               \r
+        \r
+        return i;\r
+    }\r
+\r
+    /**\r
+     * this method will read from DataInputStream dis, convert the chars read\r
+     * into ASCII and return its answer as a String\r
+     * \r
+     * @return\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public synchronized int readBuffer(byte[] gelesen,int length) throws IOException, Exception {\r
+        int i=0; // init helper variables\r
+        //byte [] gelesen = new byte[length.intValue()];\r
+        \r
+        while ((dis.ready())& (i<length)){  // loop while data available\r
+               gelesen[i++]=(byte)dis2.readUnsignedByte();// read from dis\r
+\r
+        }\r
+               \r
+        \r
+        return i;\r
+    }\r
+    \r
+    \r
+    /**\r
+     * reads data supplied by the XPort and returns an array of bytes\r
+     * \r
+     * @param length\r
+     * @return\r
+     * @throws InterruptedIOException\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public byte[] receiveByteArray(int length) throws InterruptedIOException,\r
+            IOException, Exception {\r
+        byte[] antwort = { 0, // this method hardly differs from the string\r
+                0, 0, 0, 0 }; // reading one, so same comments apply\r
+        try {\r
+            dis.ready();\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        try {\r
+            antwort = readByteArrayBuffer(length);\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        return antwort;\r
+    }\r
+\r
+    /**\r
+     * this method will read from DataInputStream dis and return its answer as\r
+     * an array of bytes\r
+     * \r
+     * @param length\r
+     * @return\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public synchronized byte[] readByteArrayBuffer(int length)\r
+            throws IOException, Exception {\r
+        /*\r
+         * this method again hardly differs from the string reading one, so same\r
+         * comments apply here as well\r
+         */\r
+\r
+        int lesen = 0;\r
+        byte gelesen[] = new byte[length];\r
+        int i = 0;\r
+        int timeout = 0;\r
+        while (!dis.ready() && timeout < 8) { // wait max 2 seconds for data\r
+            try {\r
+                wait(250);\r
+                timeout++;\r
+            } catch (InterruptedException IntEx) {\r
+            }\r
+        }\r
+        \r
+        if (timeout ==8) throw(new Exception("Timeout"));\r
+        \r
+        while (dis.ready()) {\r
+            while (i < length) {\r
+                try {\r
+                    // --Plymo-- 7.1.2005 "& 0xFF"\r
+                    lesen = (dis.read()) & 0xFF;\r
+                    gelesen[i] = (byte) lesen;\r
+                    i++;\r
+                } catch (IOException IOEx) {\r
+                    throw IOEx;\r
+                } catch (Exception Ex) {\r
+                    throw Ex;\r
+                }\r
+            }\r
+        }\r
+        \r
+        System.out.println("readBytearray Ende");\r
+        return gelesen;\r
+    }\r
+\r
+    /**\r
+     * this class does all the actual TCP/IP connection setup work\r
+     * \r
+     * @param ipa\r
+     * @param port\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public void tcpip_connect(InetAddress ipa, int port) throws IOException,\r
+            Exception {\r
+        try {\r
+            //  really establish a TCP connection (at last...)\r
+            socket = new Socket(ipa.getHostAddress(), port);\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        try { // set up a buffered stream to read from XPort and write to PC\r
+            dis = new BufferedReader(new InputStreamReader(socket\r
+                    .getInputStream()));\r
+            dis2= new DataInputStream(socket.getInputStream());\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        try { // set up a buffered stream to read from PC and write to XPort\r
+               dos=            new DataOutputStream (socket.getOutputStream());\r
+               \r
+               /*            dos = new BufferedWriter(new OutputStreamWriter(socket\r
+                    .getOutputStream()));\r
+*/        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * this method simply returns the value of DataInputStream dis' method\r
+     * ready()\r
+     * \r
+     * @return\r
+     * @throws Exception\r
+     */\r
+    public boolean DataReady() throws Exception {\r
+        try {\r
+            return dis.ready();\r
+        } catch (Exception Ex) {\r
+            return false;\r
+        }\r
+    }\r
+}\r
diff --git a/projekte/netzschalter/src/GUI.java b/projekte/netzschalter/src/GUI.java
new file mode 100644 (file)
index 0000000..0772122
--- /dev/null
@@ -0,0 +1,2230 @@
+/*\r
+ * Created on 14.04.2004\r
+ *\r
+ * To change the template for this generated file go to\r
+ * Window - Preferences - Java - Code Generation - Code and Comments\r
+ */\r
+/**\r
+ * @author olz\r
+ *\r
+ * This class generates the graphical user interface for the communication with the XPort.\r
+ * It also initializes and runs the other methods.\r
+ * \r
+ * 01.01.2005 Plymo \r
+ *    Probleme nach Disconnect und Reconnect - Reader-Thread ist natuerlich nicht mehr\r
+ *    zu verwenden. Es muss ein Neuer erzeugt werden.\r
+ *    java.util.Calender statt des depricated java.util.Date.\r
+ *    Minuten und Sekunden mit fuehrender Null falls einstellig.\r
+ * 26.08.05 Bbe Großer Rewrite, leider noch nicht alle Unschönheiten entfernt \r
+ * TODO\r
+ */\r
+\r
+import java.applet.Applet;\r
+import java.awt.Button;\r
+import java.awt.Checkbox;\r
+import java.awt.Color;\r
+import java.awt.Dimension;\r
+import java.awt.FontMetrics;\r
+import java.awt.Graphics;\r
+import java.awt.Graphics2D;\r
+import java.awt.GridBagConstraints;\r
+import java.awt.GridBagLayout;\r
+import java.awt.Insets;\r
+import java.awt.Label;\r
+import java.awt.Panel;\r
+import java.awt.RenderingHints;\r
+import java.awt.TextArea;\r
+import java.awt.TextField;\r
+import java.awt.event.ActionEvent;\r
+import java.awt.event.ActionListener;\r
+import java.awt.event.ItemEvent;\r
+import java.awt.event.ItemListener;\r
+import java.awt.geom.Line2D;\r
+import java.io.IOException;\r
+import java.util.Calendar;\r
+\r
+/**\r
+ * @author Oliver Zechiel (olz)\r
+ *                     Benjamin Benz (bbe)\r
+ *  \r
+ */\r
+public class GUI extends Applet implements ActionListener, ItemListener{\r
+    static final long serialVersionUID = 1;\r
+\r
+    /** port 10001 is used to directly transmit data from RS232 to Ethernet */\r
+    private static final int bridgePort = 10001;\r
+    \r
+    /** Number of I/O pins available on WiPort */ \r
+    private static final int NUMCPINS = 3;\r
+\r
+    \r
+    /* Number of Relais on B-Module   */\r
+    private static final int NUMRELAIS = 7;\r
+    \r
+    /* Number of bytes in a Command for the B-Module*/\r
+       private static final int CMD_LENGTH = 8;\r
+       \r
+       /* Request the Relais-States */\r
+       private static final int CMD_READRELAIS = 0x81;\r
+       \r
+       /* Command to set relais */\r
+       private static final int CMD_SETRELAIS = 0x80;\r
+\r
+       /* Command to set date */\r
+       private static final int CMD_SETDATE = 0x45;\r
+\r
+       /* Command to set time */\r
+       private static final int CMD_SETTIME = 0x44;\r
+       \r
+       /* Read an Event from B-Module */\r
+       private static final int CMD_GETEVENT =0x46;\r
+       \r
+       /* Read an Event from B-Module */\r
+       private static final int CMD_SETEVENT =0x47;\r
+       \r
+       /* Delete an Event from B-Module */\r
+       private static final int CMD_DELETEEVENT =0x48;\r
+       \r
+       /* Ask B-Module for 64 Samples*/\r
+       private static final int CMD_READADC_64 =0x43;\r
+\r
+    /** this value is just a placeholder to encode XPort specific values */\r
+    private static final int START_CODE = 0x41; /* 'A' */\r
+\r
+    /** this value is just a placeholder to encode XPort specific values */\r
+    private static final int STOP_CODE = 0x42;  /* 'B' */\r
+\r
+\r
+\r
+    \r
+    /**\r
+     * this variable will keep track if a connection to the XPort currently\r
+     * exists\r
+     */\r
+    private boolean isConnected = false;\r
+\r
+    /**\r
+     * This variable will keep track if a connection to the XPort existed before\r
+     * sending a command to the B-module. Its purpose is to check if the\r
+     * connection is to be be ended after the command was sent.\r
+     */\r
+    private boolean wasConnected = false;\r
+\r
+    /** instance of a Communication class object */\r
+    private Communication XPort;\r
+\r
+    /** this TextField serves to send messages to the XPort */\r
+    private TextField eingabeFeld;\r
+\r
+    /** this TextField stores the IP address */\r
+    private TextField IPAdresse;\r
+\r
+    /** this TextField stores the port */\r
+    private TextField PortField;\r
+\r
+    /** this TextArea will display information on the TCP/IP communication etc */\r
+    private TextArea statusFeld;\r
+\r
+    /** this TextArea will show the answers sent by the XPort */\r
+    private TextArea ausgabeFeld;\r
+\r
+    /** clicking on this button initiates the connection setup to the XPort */\r
+    private Button Connect;\r
+\r
+    /** Clicking on this button will allow to toggle the LEDs on / off */\r
+    private Button setCPins;\r
+\r
+    /** this button will terminate the connection to the XPort */\r
+    private Button Disconnect;\r
+\r
+    /** this instance will effectively control the XPort's network connections */\r
+    private IOControl IOControl1;\r
+\r
+    /**\r
+     * this thread will loop endlessly while connected, receiving data from the\r
+     * XPort\r
+     */\r
+    private InputReadThread ReadThread;\r
+\r
+    /**\r
+     * this textfield will display if the I/O pins are set to outgoing or\r
+     * incoming\r
+     */\r
+    private TextArea IODir;\r
+\r
+    /** this button will re-read the XPort's I/O pins' status */\r
+    private Button getCPinDir, setCPinDir, getCPins;\r
+\r
+    /** this textfield will display the LED's status */\r
+//    private TextArea LEDStatus;\r
+\r
+    /** this button will allow to read and set the I/O pins' settings and values */\r
+//    private Button getState;\r
+\r
+    /** this panel will contain the GUI's elements for the A panel */\r
+    private Panel xPortPannel, aPanel;\r
+    \r
+    /** this panel will contain the GUI's elements for the B panel */\r
+    private Panel bPanel, timerPanel;\r
+\r
+    /** this panel will contain the GUI's elements for the Terminal-Mode */\r
+    private Panel terminalPanel;\r
+    \r
+    /* Displays the Oszilloskop Graphic */\r
+    private Oszilloskop oszilloskop;\r
+    \r
+    /** this checkbox will allow toggling its respective LED on and off */\r
+    private Checkbox[] CPins; //1, checkLED2, checkLED3;\r
+\r
+    /** this Buttons control the 7 Relais **/\r
+    private Button[] relais;\r
+    \r
+    /** this Buttons reads the Relais State**/\r
+    private Button getRelais;\r
+\r
+    /** this Buttons reads the 64 Sample Values and displays them in Oszilloskop**/\r
+    private Button getSamples;\r
+\r
+    /** this Buttons reads the Relais State**/\r
+    private Button timerSetDateTime;\r
+\r
+    \r
+    private int relaisValues = 0;\r
+    \r
+    \r
+    private Button timerRead, timerWrite, timerDelete;\r
+    \r
+    /* Event-Number */\r
+    private TextField timerEventNr;\r
+    \r
+    private Label timerEvents;\r
+        \r
+    private TextField timerChannel, timerData;\r
+    private Checkbox timerSpecial;\r
+    \r
+    private TextField timerHour, timerMinute, timerSecond; \r
+    private Checkbox timerHourDontCare, timerMinuteDontCare, timerSecondDontCare; \r
+    \r
+    private TextField timerDay, timerMonth, timerYear, timerWeekday;\r
+    private Checkbox timerDayDontCare, timerMonthDontCare, timerYearDontCare, timerWeekdayDontCare;\r
+    \r
+    \r
+    \r
+    private TimerEvent timerEvent;\r
+    \r
+    /** this checkbox selects, if messages shall be shown as ASCII or Hex*/\r
+    public Checkbox showASCII; \r
+    \r
+    /**\r
+     * this checkbox will allow setting ist respective I/O direction to incoming /\r
+     * outgoing\r
+     */\r
+    private Checkbox[] CPinDir;\r
+\r
+    /** this textfields are used to send commands to the B-Module */\r
+    private TextField StartCodeField, Command, Data, StopCodeField;\r
+\r
+    /** this textfields are used to send commands to the B-Module */\r
+    private TextField adcChannel;\r
+\r
+    /** this checkbox selects, if 50Hz Filter is to use */\r
+    public Checkbox useFilter; \r
+    \r
+    /* \r
+     * Switch from A-Module Control to B-Module-Control\r
+     */\r
+    private Button aPanelToBPanel;\r
+\r
+    /* \r
+     * Switch from B-Module Control to A-Module-Control\r
+     */\r
+    private Button bPanelToTimerPanel;\r
+\r
+    /* \r
+     * Switch from Timer-Module Control to A-Module-Control\r
+     */\r
+    private Button timerPanelToAPanel; \r
+    \r
+    /** this button will send a command to the B-Module as set up in the B panel */\r
+    private Button sendCommand;\r
+\r
+    /** this array of bytes will contain responses from the XPort */\r
+    byte[] controlAntwort = { 0, 0, 0, 0, 0 };\r
+\r
+    \r
+    \r
+\r
+\r
+    /**\r
+     * this method will allow to switch between the XPort's control panel and\r
+     * the B-module's control panel\r
+     */\r
+    private void changePanel(char tab) {\r
+        if ((tab == 'B') || (tab == 'b')) {\r
+            aPanel.setVisible(false); // set A panel to invisible\r
+            bPanel.setVisible(true); // set B panel to visible\r
+            timerPanel.setVisible(false); // set Timer panel to visible\r
+        } else if ((tab == 'A') || (tab == 'a')){\r
+            bPanel.setVisible(false); // set B panel invisible\r
+            aPanel.setVisible(true); // set A panel visible\r
+            timerPanel.setVisible(false); // set Timer panel to visible\r
+        } else if ((tab == 'C') || (tab == 'c')){\r
+            bPanel.setVisible(false); // set B panel invisible\r
+            aPanel.setVisible(false); // set A panel visible\r
+            timerPanel.setVisible(true); // set Timer panel to visible\r
+        }\r
+\r
+        this.doLayout();\r
+        bPanel.doLayout(); // re-arrange the Applet's layout\r
+        aPanel.doLayout(); // re-arrange the Applet's layout\r
+        timerPanel.doLayout(); \r
+\r
+//        this.repaint(); // re-arrange the Applet's layout\r
+        this.doLayout();\r
+    }\r
+\r
+    /************************************************************\r
+     * Construct Timer-Panel\r
+     * *********************************************************/\r
+    private void constructTimerPanel(){\r
+       int row,col;\r
+       GridBagLayout gbl = new GridBagLayout();\r
+       timerPanel.setLayout(gbl);\r
+        \r
+        GridBagConstraints c = new GridBagConstraints();\r
+        // ein paar defaults einstellen;\r
+        c.fill = GridBagConstraints.BOTH;   // wie Komponente Bereich füllen soll\r
+        c.weightx = 90;                     // Breite\r
+        c.weighty = 100;                    // Höhe\r
+        c.insets = new Insets(0,5,10,15);   // Abstände definieren\r
+        \r
+        // Und nun auf zu den Komponenten fürs B-Modul-Panel\r
+        \r
+        // -------------------------------------\r
+        row=0; col=0;\r
+      \r
+        Label label = new Label("Timer-Modul");\r
+         c.gridx = col++;    c.gridy = row;   c.gridwidth = 2;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        timerPanel.add(label);\r
+        col++;\r
+        \r
+        timerPanelToAPanel = new Button();\r
+        timerPanelToAPanel.setLabel("Switch to A-module control");\r
+        timerPanelToAPanel.addActionListener(this);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 3;    c.gridheight = 1;\r
+        gbl.setConstraints(timerPanelToAPanel, c);\r
+        timerPanel.add(timerPanelToAPanel);\r
+        \r
+        c.fill = GridBagConstraints.NONE;\r
+        \r
+        // -------------------------------------\r
+        row++; col=0;\r
+\r
+        label = new Label("Event");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        timerPanel.add(label);\r
+        \r
+        timerEventNr = new TextField(2);\r
+        timerEventNr.setText("0");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(timerEventNr, c);\r
+        timerPanel.add(timerEventNr);\r
+        \r
+        timerEvents = new Label("of ?? Events");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(timerEvents, c);\r
+        timerPanel.add(timerEvents);\r
+        \r
+        \r
+        timerRead = new Button();\r
+        timerRead.setLabel("Read Event");\r
+        timerRead.addActionListener(this);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(timerRead, c);\r
+        timerPanel.add(timerRead);\r
+\r
+        timerWrite = new Button();\r
+        timerWrite.setLabel("Write Event");\r
+        timerWrite.addActionListener(this);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(timerWrite, c);\r
+        timerPanel.add(timerWrite);\r
+\r
+        timerDelete = new Button("Delete Event");\r
+        timerDelete.addActionListener(this);\r
+        c.gridx = col++;    c.gridy = row;  \r
+        gbl.setConstraints(timerDelete, c);\r
+        timerPanel.add(timerDelete);\r
+\r
+        timerSetDateTime = new Button("Set Time");\r
+        timerSetDateTime.addActionListener(this);\r
+        c.gridx = col++;    c.gridy = row;  \r
+        gbl.setConstraints(timerSetDateTime, c);\r
+        timerPanel.add(timerSetDateTime);\r
+\r
+        \r
+        \r
+//      -------------------------------------\r
+        row++; col=0;\r
+        \r
+        timerSpecial = new Checkbox("Special Event");\r
+        c.gridx = col++;   c.gridy = row;    c.gridwidth = 2;         \r
+        gbl.setConstraints(timerSpecial, c);\r
+        timerPanel.add(timerSpecial);\r
+        col++;\r
+\r
+        \r
+        label = new Label("Channel-Mask");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        timerPanel.add(label);\r
+        \r
+        timerChannel = new TextField(2);\r
+        timerChannel.setText("0");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(timerChannel, c);\r
+        timerPanel.add(timerChannel);\r
+        \r
+        label = new Label("Data");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        timerPanel.add(label);\r
+        \r
+        timerData = new TextField(2);\r
+        timerData.setText("255");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(timerData, c);\r
+        timerPanel.add(timerData);\r
+\r
+        //col+=2;\r
+        \r
+        label = new Label("Weekday");\r
+        c.gridx = col++;   \r
+        gbl.setConstraints(label, c);\r
+        timerPanel.add(label);\r
+        \r
+        timerWeekdayDontCare = new Checkbox();\r
+        c.gridx = col++;               \r
+        gbl.setConstraints(timerWeekdayDontCare, c);\r
+        timerPanel.add(timerWeekdayDontCare);\r
+        timerWeekdayDontCare.addItemListener(this);\r
+        \r
+        timerWeekday = new TextField(2);\r
+        timerWeekday.setText("00");\r
+        timerWeekday.setEditable(false);\r
+        c.gridx = col++;\r
+        gbl.setConstraints(timerWeekday, c);\r
+        timerPanel.add(timerWeekday);\r
+\r
+        \r
+//      -------------------------------------\r
+        row++; col=0; c.gridy = row;\r
+               \r
+        label = new Label("Hour");\r
+        c.gridx = col++;   \r
+        gbl.setConstraints(label, c);\r
+        timerPanel.add(label);\r
+        \r
+        timerHourDontCare = new Checkbox();\r
+        c.gridx = col++;               \r
+        gbl.setConstraints(timerHourDontCare, c);\r
+        timerPanel.add(timerHourDontCare);\r
+        timerHourDontCare.addItemListener(this);\r
+        \r
+        timerHour = new TextField(2);\r
+        timerHour.setText("00");\r
+        timerHour.setEditable(false);\r
+        c.gridx = col++;\r
+        gbl.setConstraints(timerHour, c);\r
+        timerPanel.add(timerHour);\r
+                \r
+        label = new Label("Minute");\r
+        c.gridx = col++;\r
+        gbl.setConstraints(label, c);\r
+        timerPanel.add(label);\r
+        \r
+        timerMinuteDontCare = new Checkbox();\r
+        c.gridx = col++;\r
+        gbl.setConstraints(timerMinuteDontCare, c);\r
+        timerPanel.add(timerMinuteDontCare);\r
+        timerMinuteDontCare.addItemListener(this);\r
+        \r
+        timerMinute = new TextField(2);\r
+        timerMinute.setEditable(false);\r
+        timerMinute.setText("00");\r
+        c.gridx = col++;\r
+        gbl.setConstraints(timerMinute, c);\r
+        timerPanel.add(timerMinute);        \r
+        \r
+        label = new Label("Second");\r
+        c.gridx = col++;\r
+        gbl.setConstraints(label, c);\r
+        timerPanel.add(label);\r
+\r
+        timerSecondDontCare = new Checkbox();\r
+        c.gridx = col++;\r
+        gbl.setConstraints(timerSecondDontCare, c);\r
+        timerPanel.add(timerSecondDontCare);\r
+        timerSecondDontCare.addItemListener(this);\r
+        \r
+        timerSecond = new TextField(2);\r
+        timerSecond.setEditable(false);\r
+        timerSecond.setText("00");\r
+        c.gridx = col++;\r
+        gbl.setConstraints(timerSecond, c);\r
+        timerPanel.add(timerSecond);    \r
+        \r
+        //      -------------------------------------\r
+        row++; col=0; c.gridy = row;\r
+\r
+        label = new Label("Day");\r
+        c.gridx = col++;\r
+        gbl.setConstraints(label, c);\r
+        timerPanel.add(label);\r
+        \r
+        timerDayDontCare = new Checkbox();\r
+        c.gridx = col++;\r
+        gbl.setConstraints(timerDayDontCare, c);\r
+        timerPanel.add(timerDayDontCare);\r
+        timerDayDontCare.addItemListener(this);       \r
+        \r
+        timerDay = new TextField(2);\r
+        timerDay.setText("01");\r
+        timerDay.setEditable(false);\r
+        c.gridx = col++;\r
+        gbl.setConstraints(timerDay, c);\r
+        timerPanel.add(timerDay);\r
+\r
+        \r
+        label = new Label("Month");\r
+        c.gridx = col++;\r
+        gbl.setConstraints(label, c);\r
+        timerPanel.add(label);\r
+        \r
+        timerMonthDontCare = new Checkbox();\r
+        c.gridx = col++;\r
+        gbl.setConstraints(timerMonthDontCare, c);\r
+        timerPanel.add(timerMonthDontCare);\r
+        timerMonthDontCare.addItemListener(this);\r
+        \r
+        timerMonth = new TextField(2);\r
+        timerMonth.setText("01");\r
+        timerMonth.setEditable(false);\r
+        c.gridx = col++;\r
+        gbl.setConstraints(timerMonth, c);\r
+        timerPanel.add(timerMonth);        \r
+\r
+        label = new Label("Year");\r
+        c.gridx = col++;\r
+        gbl.setConstraints(label, c);\r
+        timerPanel.add(label);\r
+\r
+        timerYearDontCare = new Checkbox();\r
+        c.gridx = col++;\r
+        gbl.setConstraints(timerYearDontCare, c);\r
+        timerPanel.add(timerYearDontCare);\r
+        timerYearDontCare.addItemListener(this);\r
+        \r
+        timerYear = new TextField(4);\r
+        timerYear.setText("2005");\r
+        timerYear.setEditable(false);\r
+        c.gridx = col++;\r
+        gbl.setConstraints(timerYear, c);\r
+        timerPanel.add(timerYear);          \r
+    }\r
+    \r
+    \r
+    \r
+    /************************************************************\r
+     * Construct B-Panel\r
+     * *********************************************************/\r
+    private void constructBPanel(){\r
+       int row,col;\r
+       GridBagLayout gbl = new GridBagLayout();\r
+        bPanel.setLayout(gbl);\r
+        \r
+        GridBagConstraints c = new GridBagConstraints();\r
+        // ein paar defaults einstellen;\r
+        c.fill = GridBagConstraints.BOTH;   // wie Komponente Bereich füllen soll\r
+        c.weightx = 90;                     // Breite\r
+        c.weighty = 100;                    // Höhe\r
+        c.insets = new Insets(0,5,10,15);   // Abstände definieren\r
+        \r
+        // Und nun auf zu den Komponenten fürs B-Modul-Panel\r
+        \r
+        // -------------------------------------\r
+        row=0; col=0;\r
+      \r
+        Label label = new Label("B-Modul");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 2;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        bPanel.add(label);\r
+        col++;\r
+        \r
+        bPanelToTimerPanel = new Button();\r
+        bPanelToTimerPanel.setLabel("Switch to Timer-control");\r
+        bPanelToTimerPanel.addActionListener(this);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 3;    c.gridheight = 1;\r
+        gbl.setConstraints(bPanelToTimerPanel, c);\r
+        bPanel.add(bPanelToTimerPanel);\r
+        \r
+\r
+        oszilloskop = new Oszilloskop();\r
+        c.gridx = 5;    c.gridy = row;   c.gridwidth = 4;    c.gridheight = 4;\r
+        gbl.setConstraints(oszilloskop, c);\r
+        bPanel.add(oszilloskop);\r
+\r
+        // -------------------------------------\r
+        row++; col=0;        \r
+        \r
+        relais = new Button[8];\r
+        \r
+        relais[6] = new Button("Aux");\r
+        relais[6].addActionListener(this);\r
+        relais[6].setEnabled(false); // buttons are not allowed until 1st showRelais()\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(relais[6], c);\r
+        bPanel.add(relais[6]);\r
+        \r
+        int i=1;\r
+       relais[i] = new Button("Rel "+ (i+1));\r
+        relais[i].addActionListener(this);\r
+        relais[i].setEnabled(false); // buttons are not allowed until 1st showRelais()\r
+        c.gridx = col++;    c.gridy = row;  \r
+        gbl.setConstraints(relais[i], c);\r
+        bPanel.add(relais[i]);\r
+        \r
+        i=0;\r
+       relais[i] = new Button("Rel "+ (i+1));\r
+        relais[i].addActionListener(this);\r
+        relais[i].setEnabled(false); // buttons are not allowed until 1st showRelais()\r
+        c.gridx = col++;    c.gridy = row;  \r
+        gbl.setConstraints(relais[i], c);\r
+        bPanel.add(relais[i]);\r
+        \r
+        label = new Label("PWR");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        bPanel.add(label);\r
+        row++; col=0;  \r
+        \r
+        for (i = NUMRELAIS-2; i>1; i--) {\r
+               relais[i] = new Button("Rel "+ (i+1));\r
+            relais[i].addActionListener(this);\r
+            relais[i].setEnabled(false); // buttons are not allowed until 1st showRelais()\r
+            c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+            gbl.setConstraints(relais[i], c);\r
+            bPanel.add(relais[i]);\r
+        }\r
+                \r
+        getRelais = new Button("Read Relais");\r
+        getRelais.addActionListener(this);\r
+        c.gridx = 4;    c.gridy = row-1;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(getRelais, c);\r
+        bPanel.add(getRelais);\r
+       \r
+        // -------------------------------------\r
+        row++; col=0;\r
+\r
+        label = new Label("Start");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        bPanel.add(label);\r
+                \r
+        label = new Label("Cmd");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        bPanel.add(label);\r
+        \r
+        label = new Label("Data");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        bPanel.add(label);\r
+        \r
+        label = new Label("Stop");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        bPanel.add(label);\r
+\r
+        // -------------------------------------\r
+        row++; col=0;\r
+\r
+        StartCodeField = new TextField(1);\r
+        StartCodeField.addActionListener(this);\r
+        StartCodeField.setText(Integer.toHexString(START_CODE));\r
+        StartCodeField.setEditable(false);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(StartCodeField, c);\r
+        bPanel.add(StartCodeField);\r
+\r
+        Command = new TextField(1);\r
+        Command.addActionListener(this);\r
+        Command.setText("80");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(Command, c);\r
+        bPanel.add(Command);\r
+\r
+        Data = new TextField(1);\r
+        Data.addActionListener(this);\r
+        Data.setText("30");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(Data, c);\r
+        bPanel.add(Data);\r
+\r
+        StopCodeField = new TextField(1);\r
+        StopCodeField.addActionListener(this);\r
+        StopCodeField.setText(Integer.toHexString(STOP_CODE));\r
+        StopCodeField.setEditable(false);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(StopCodeField, c);\r
+        bPanel.add(StopCodeField);\r
+\r
+        sendCommand = new Button();\r
+        sendCommand.setLabel("send command");\r
+        sendCommand.addActionListener(this);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(sendCommand, c);\r
+        bPanel.add(sendCommand);\r
+                        \r
+        label = new Label("Channel");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        c.fill = GridBagConstraints.NONE;\r
+        gbl.setConstraints(label, c);\r
+        bPanel.add(label);\r
+        \r
+        adcChannel = new TextField(2);\r
+        adcChannel.setText("0");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        c.fill = GridBagConstraints.NONE;\r
+        gbl.setConstraints(adcChannel, c);\r
+        bPanel.add(adcChannel);\r
+\r
+        useFilter = new Checkbox("Filter?", false);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        c.fill = GridBagConstraints.BOTH;\r
+        gbl.setConstraints(useFilter, c);\r
+        bPanel.add(useFilter);\r
+\r
+        \r
+        getSamples = new Button("Sample");\r
+        getSamples.addActionListener(this);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(getSamples, c);\r
+        bPanel.add(getSamples);\r
+\r
+    }\r
+    \r
+    \r
+/*\r
+ *  Construct Connection Panel\r
+ */\r
+    private void constructXPortPanel(){\r
+        GridBagLayout gbl = new GridBagLayout();\r
+        xPortPannel.setLayout(gbl);\r
+        \r
+        GridBagConstraints c = new GridBagConstraints();\r
+        // ein paar defaults einstellen;\r
+        c.fill = GridBagConstraints.BOTH;   // wie Komponente Bereich füllen soll\r
+        c.weightx = 90;                     // Breite\r
+        c.weighty = 120;                    // Höhe\r
+        c.insets = new Insets(0,5,10,15);   // Abstände definieren\r
+        \r
+        Label label = new Label("IP-Adresse");\r
+        c.gridx = 0;    c.gridy = 0;   c.gridwidth = 2;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        xPortPannel.add(label);\r
+\r
+        IPAdresse = new TextField(5);\r
+        c.gridx = 0;    c.gridy = 1;   c.gridwidth = 2;    c.gridheight = 1;\r
+        gbl.setConstraints(IPAdresse, c);\r
+        xPortPannel.add(IPAdresse);\r
+\r
+        label = new Label("Port");\r
+        c.gridx = 2;    c.gridy = 0;   c.gridwidth = 2;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        xPortPannel.add(label);\r
+\r
+        PortField = new TextField(5);\r
+        PortField.setText(Integer.toString(bridgePort));\r
+        c.gridx = 2;    c.gridy = 1;   c.gridwidth = 2;    c.gridheight = 1;\r
+        gbl.setConstraints(PortField, c);\r
+        xPortPannel.add(PortField);\r
+        \r
+        \r
+        \r
+        Connect = new Button();\r
+        Connect.setLabel("Connect to XPort");\r
+        Connect.addActionListener(this);\r
+        c.gridx = 0;    c.gridy = 2;   c.gridwidth = 2;    c.gridheight = 1;\r
+        gbl.setConstraints(Connect, c);\r
+        xPortPannel.add(Connect);\r
+\r
+        Disconnect = new Button();\r
+        Disconnect.setLabel("Disconnect");\r
+        Disconnect.addActionListener(this);\r
+        c.gridx = 2;    c.gridy = 2;   c.gridwidth = 2;    c.gridheight = 1;\r
+        gbl.setConstraints(Disconnect, c);\r
+        xPortPannel.add(Disconnect);\r
+\r
+    }   \r
+    /* \r
+     * setzt das I/O Panel zusammen\r
+     */\r
+    private void constructAPanel(){\r
+       int col, row;\r
+       \r
+        GridBagLayout gbl = new GridBagLayout();\r
+        aPanel.setLayout(gbl);\r
+\r
+        GridBagConstraints c = new GridBagConstraints();\r
+        // ein paar defaults einstellen;\r
+        c.fill = GridBagConstraints.BOTH;   // wie Komponente Bereich füllen soll\r
+        c.weightx = 90;                     // Breite\r
+        c.weighty = 100;                    // Höhe\r
+        c.insets = new Insets(0,5,10,15);   // Abstände definieren\r
+        \r
+        col=0; row=0;\r
+        \r
+        Label label = new Label("XPort I/O Pins");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        aPanel.add(label);\r
+\r
+        aPanelToBPanel = new Button();\r
+        aPanelToBPanel.setLabel("Switch to B-module control");\r
+        aPanelToBPanel.addActionListener(this);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 4;    c.gridheight = 1;\r
+        gbl.setConstraints(aPanelToBPanel, c);\r
+        aPanel.add(aPanelToBPanel);\r
+\r
+        \r
+        // -------------------------------------\r
+        row++; col=0;\r
+        \r
+        label = new Label("Value");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        aPanel.add(label);\r
+\r
+       setCPins = new Button();\r
+        setCPins.setLabel("Set");\r
+        setCPins.addActionListener(this);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(setCPins, c);\r
+        aPanel.add(setCPins);\r
+        \r
+        \r
+        CPins = new Checkbox[NUMCPINS];\r
+        for (int i = 0; i < NUMCPINS; i++) {\r
+            CPins[i] = new Checkbox("CP" + (i + 1), false);\r
+            c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+            gbl.setConstraints(CPins[i], c);\r
+            aPanel.add(CPins[i]);\r
+        }\r
+        \r
+        getCPins = new Button();\r
+        getCPins.setLabel("Read");\r
+        getCPins.addActionListener(this);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(getCPins, c);\r
+        aPanel.add(getCPins);\r
+\r
+        // -------------------------------------\r
+        row++; col=0;\r
+        \r
+        label = new Label("Direction");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        aPanel.add(label);\r
+        \r
+        setCPinDir = new Button();\r
+        setCPinDir.setLabel("Set");\r
+        setCPinDir.addActionListener(this);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(setCPinDir, c);\r
+        aPanel.add(setCPinDir);\r
+        \r
+        CPinDir = new Checkbox[NUMCPINS];\r
+        for (int i = 0; i < NUMCPINS; i++) {\r
+            CPinDir[i] = new Checkbox("CP" + (i + 1), false);\r
+            c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+            gbl.setConstraints(CPinDir[i], c);\r
+            aPanel.add(CPinDir[i]);\r
+        }        \r
+\r
+        getCPinDir = new Button();\r
+        getCPinDir.setLabel("Read");\r
+        getCPinDir.addActionListener(this);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(getCPinDir, c);\r
+        aPanel.add(getCPinDir);\r
+\r
+        \r
+    }\r
+    \r
+    \r
+    /* \r
+     * setzt das Terminal Panel zusammen\r
+     */\r
+    private void constructTerminalPanel(){\r
+       int col, row;\r
+       \r
+        GridBagLayout gbl = new GridBagLayout();\r
+        terminalPanel.setLayout(gbl);\r
+\r
+        GridBagConstraints c = new GridBagConstraints();\r
+        // ein paar defaults einstellen;\r
+        c.fill = GridBagConstraints.BOTH;   // wie Komponente Bereich füllen soll\r
+        c.weightx = 90;                     // Breite\r
+        c.weighty = 100;                    // Höhe\r
+        c.insets = new Insets(0,5,10,15);   // Abstände definieren\r
+        \r
+        col=0; row=0;\r
+        \r
+\r
+        Label label = new Label("Data to COM");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        terminalPanel.add(label);\r
+\r
+        eingabeFeld = new TextField(12);\r
+        eingabeFeld.addActionListener(this);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 4;    c.gridheight = 1;\r
+        gbl.setConstraints(eingabeFeld, c);\r
+        terminalPanel.add(eingabeFeld);\r
+\r
+        // -------------------------------------\r
+        row++; col=0;\r
+\r
+        label = new Label("Output from COM");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        terminalPanel.add(label);\r
+\r
+        showASCII = new Checkbox("Decode Readable Chars?", false);\r
+        c.gridx = 4;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(showASCII, c);\r
+        terminalPanel.add(showASCII);\r
+       \r
+               \r
+        // -------------------------------------\r
+        row++; col=0;\r
\r
+        ausgabeFeld = new TextArea(10, 50);\r
+        ausgabeFeld.setText("");\r
+        ausgabeFeld.setEditable(false);        \r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 5;    c.gridheight = 1;\r
+        gbl.setConstraints(ausgabeFeld, c);\r
+        terminalPanel.add(ausgabeFeld);\r
+    }\r
+    \r
+    \r
+    /**\r
+     * This method will display all the GUI's elements on the Applet and preset\r
+     * them with a number of values. It does not perform any actions other than\r
+     * that. Since it's name is init() and we've got an Applet here, it's\r
+     * automatically run by the JRE.\r
+     */\r
+    public void init() {\r
+       int col, row;\r
+       \r
+        GridBagLayout gbl = new GridBagLayout();\r
+        this.setLayout(gbl);\r
+\r
+        GridBagConstraints c = new GridBagConstraints();\r
+        // ein paar defaults einstellen;\r
+        c.fill = GridBagConstraints.BOTH;   // wie Komponente Bereich füllen soll\r
+        c.weightx = 90;                     // Breite\r
+        c.weighty = 120;                    // Höhe\r
+        c.insets = new Insets(0,5,10,15);   // Abstände definieren\r
+        \r
+       // Zur Verinfachung kommt jede Funktionsgruppe in ihr eigenes Panel\r
+\r
+        // -------------------------------------\r
+        col=0; row=0;\r
+      \r
+        Label label = new Label("c't-Netz-Schalter");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        this.add(label);\r
+        \r
+        // -------------------------------------\r
+        row++; col=0;\r
+                \r
+       // Dieses Panel kümmert sich um den Verbindungsaufbau zum XPort\r
+       xPortPannel = new Panel(); \r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(xPortPannel, c);\r
+        this.add(xPortPannel);\r
+        constructXPortPanel();\r
+        xPortPannel.setBackground(new Color(200,200,200));\r
+        \r
+        // -------------------------------------\r
+        row++; col=0;\r
+\r
+        // Dieses Panel enthält die Steuerung der I/O-Pins des XPports\r
+        aPanel = new Panel();\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(aPanel, c);\r
+        this.add(aPanel);\r
+        constructAPanel();\r
+        aPanel.setBackground(new Color(200,200,200));\r
+        aPanel.setVisible(false); // since we start with the B panel, we hide\r
+           // the A panel from the user\r
+        \r
+        // -------------------------------------\r
+        row++; col=0;\r
+\r
+        // Alles zur Steuerung des B-Moduls\r
+        bPanel = new Panel();\r
+        c.gridx = col;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(bPanel, c);\r
+        this.add(bPanel);\r
+        constructBPanel();\r
+        bPanel.setBackground(new Color(200,200,200));\r
+        bPanel.setVisible(false); // since we start with the A panel, we hide\r
+                                                         // the B panel from the user\r
+        \r
+        // Timer-Modul\r
+        timerPanel = new Panel();\r
+        c.gridx = col;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+         \r
+        gbl.setConstraints(timerPanel, c);\r
+        this.add(timerPanel);\r
+        constructTimerPanel();\r
+        timerPanel.setBackground(new Color(200,200,200));\r
+     //   timerPanel.setVisible(false); // since we start with the A panel, we hide\r
+                                                         // the B panel from the user\r
+        \r
+        // -------------------------------------\r
+        row++; col=0;\r
+\r
+        terminalPanel = new Panel();\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(terminalPanel, c);       \r
+        this.add(terminalPanel);\r
+        constructTerminalPanel();\r
+        terminalPanel.setBackground(new Color(200,200,200));\r
+        \r
+        // -------------------------------------\r
+        row++; col=0;\r
+      \r
+        label = new Label("Status");\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(label, c);\r
+        this.add(label);\r
+        \r
+\r
+        \r
+        // -------------------------------------\r
+        row++; col=0;\r
+        \r
+        statusFeld = new TextArea(8, 30);\r
+        statusFeld.setEditable(false);\r
+        statusFeld.setText("");\r
+        statusFeld.setForeground(Color.red);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(statusFeld, c);\r
+        this.add(statusFeld);\r
+\r
+\r
+\r
+ /*      ChangeTab = new Button();\r
+        ChangeTab.setLabel("Switch to B-module control");\r
+        ChangeTab.addActionListener(this);\r
+        c.gridx = col++;    c.gridy = row;   c.gridwidth = 1;    c.gridheight = 1;\r
+        gbl.setConstraints(ChangeTab, c);\r
+        this.add(ChangeTab);\r
+ */       \r
+        IOControl1 = new IOControl();\r
+        \r
+\r
+\r
+        \r
+        this.setSize(1024, 768);\r
+        this.doLayout();\r
+    }\r
+\r
+    /**\r
+     * This method is responsible for some additional initialisations and\r
+     * presetting values. Basically, it could be integrated into init() without\r
+     * any major trouble.\r
+     */\r
+    public void start() {\r
+\r
+        try { // intercept problems with wrong or invalid IP addresses and ports\r
+            // that's why we're using a try statement here\r
+            // this.getCodeBase() will return the Applet's IP, including\r
+            // "http://".\r
+            // However, we only want the pure IP address, so we use substring()\r
+            // to\r
+            // extract the numbers.\r
+            IPAdresse.setText(this.getCodeBase().toString().substring(7,\r
+                    this.getCodeBase().toString().length() - 1));\r
+            IPAdresse.setText("192.168.123.200");            \r
+            append(statusFeld,"Current IP = " + IPAdresse.getText()); // display ip address\r
+        } catch (NullPointerException NPEx) {\r
+            System.err.println("NullPointerException occured");\r
+            PortField.setText("0"); // default port for serial interface control\r
+        }\r
+        // create a new instance of a Communication object to allow control of\r
+        // the XPort\r
+        XPort = new Communication();\r
+        append(statusFeld,"Applet initialised, ready to connect...");\r
+        Disconnect.setEnabled(false); // keep the user from using the\r
+        // "Disconnect" button while\r
+        // not connected\r
+        ReadThread = new InputReadThread(); // initialise a thread and start\r
+        // waiting for data from the XPort\r
+    }\r
+\r
+    /**\r
+     * This method will just test if the value entered in the field PortField is\r
+     * a number or not.\r
+     * \r
+     * @return\r
+     */\r
+    private boolean port_auswert() {\r
+        try {\r
+            Integer.parseInt(PortField.getText());\r
+        } catch (NumberFormatException NFEx) {\r
+            ausgabeFeld\r
+                    .append("Entered port has invalid format - please correct!\n");\r
+            return false;\r
+        }\r
+        return true;\r
+    }\r
+\r
+    /**\r
+     * This method will establish a connection to the XPort via the entered IP\r
+     * address and port. Its second purpose is to enable and disable GUI\r
+     * elements which are needed respectively not needed while a connection is\r
+     * established.\r
+     */\r
+    private void connect() {\r
+        append(statusFeld,"Trying to connect...");\r
+        if (!port_auswert()) { // if no valid port is stated, stop immediately\r
+            append(statusFeld,"Invalid port!");\r
+            return;\r
+        } else\r
+            // well, let's see if the IP address is valid...\r
+            // if it is, start a connection!\r
+            try {\r
+                int port = Integer.parseInt(PortField.getText());\r
+                append(statusFeld,"Connecting to " + IPAdresse.getText()\r
+                        + " at port " + port);\r
+                // call the "real" connection method\r
+                XPort.connect(IPAdresse.getText(), port);\r
+                \r
+                Connect.setEnabled(false); // allow user only to use button\r
+                                           // "Disconnect"\r
+                Disconnect.setEnabled(true);\r
+                IPAdresse.setEditable(false);\r
+                PortField.setEditable(false);\r
+                // display some status info\r
+                append(statusFeld,"Connection successfully established.");\r
+                append(statusFeld,"Setting up reading loop.");\r
+\r
+                wasConnected = true;\r
+                isConnected = true;\r
+\r
+                ReadThread = new InputReadThread(); // initialise a thread and start\r
+                ReadThread.gui=this;\r
+                ReadThread.start();\r
+                \r
+                getCPinDir();\r
+\r
+                return;\r
+            }\r
+            // If any error occurs, display it and stop connecting.\r
+            catch (IOException IOEx) {\r
+                append(statusFeld,"I/O error while connecting: " + IOEx);\r
+            } catch (Exception Ex) {\r
+                append(statusFeld,"Error while connecting: " + Ex);\r
+                Ex.printStackTrace();\r
+            }\r
+    }\r
+\r
+    /**\r
+     * Will call LEDauswert() to check which LEDs are to be toggled and sends\r
+     * this value to the XPort.\r
+     */\r
+    private void setCPins() {\r
+        int pin, bitValue;\r
+        LockButtons();\r
+        try {\r
+            controlAntwort = IOControl1.toggle(IPAdresse.getText(), LEDauswert());\r
+        } catch (IOException IOEx) {\r
+            append(statusFeld,"I/O error while toggling LEDs: " + IOEx);\r
+        } catch (Exception Ex) {\r
+            append(statusFeld,"Error while toggling LEDs: " + Ex);\r
+        }\r
+        \r
+        for (pin = 0, bitValue = 1; pin < NUMCPINS; pin++) {\r
+            if ((controlAntwort[pin/8] & bitValue) != 0) { // compare if bit is set\r
+               CPins[pin].setState(true); // Pin is high\r
+            } else {\r
+               CPins[pin].setState(false); // Pin is Low\r
+            }\r
+            bitValue= (bitValue <<1) % 256;\r
+        }\r
+  \r
+        UnlockButtons();\r
+    }\r
+\r
+    /**\r
+     * Allows toggling the XPort's I/O directions between incoming and outgoing.\r
+     * This method itself only sends the checkboxes' values to the XPort's\r
+     * respective method, toggleDirection().\r
+     *  \r
+     */\r
+    private void setCPinDir() {\r
+        int pin, bitValue;\r
+        LockButtons();\r
+        try {\r
+            controlAntwort = IOControl1.toggleDirection(IPAdresse.getText(),\r
+                    IOauswert());\r
+        } catch (IOException IOEx) {\r
+            append(statusFeld,"I/O error while toggling I/O directions: " + IOEx);\r
+        } catch (Exception Ex) {\r
+            append(statusFeld,"Error while toggling I/O directions: " + Ex);\r
+        }\r
+        for (pin = 0, bitValue = 1; pin < NUMCPINS; pin++) {\r
+            if ((controlAntwort[pin/8] & bitValue) != 0) { // compare if bit is set\r
+               CPinDir[pin].setState(true); // Pin is an Output\r
+                CPins[pin].setEnabled(true); // Changes to PIN allowed\r
+            } else {\r
+               CPinDir[pin].setState(false); // Pin is an Input\r
+                CPins[pin].setEnabled(false); // Changes to PIN not allowed\r
+            }\r
+            bitValue= (bitValue <<1) % 256;\r
+        }\r
+\r
+        getCPinDir();\r
+    }\r
+\r
+    /**\r
+     * Will ask the XPort how which I/O pins are availbale to user\r
+     */\r
+    private void getCPinFunctions() {\r
+       int pin, bitValue;\r
+        LockButtons();\r
+        try {\r
+            controlAntwort = IOControl1.getFunc(IPAdresse.getText());\r
+        } catch (IOException IOEx) {\r
+            append(statusFeld,"I/O error while getting I/O functions: " + IOEx);\r
+        } catch (Exception Ex) {\r
+            append(statusFeld,"Error while getting I/O functions: " + Ex);\r
+        }\r
+\r
+        for (pin = 0, bitValue = 1; pin < NUMCPINS; pin++) {\r
+            if ((controlAntwort[pin/8] & bitValue) != 0) { // compare if bit is set\r
+               CPinDir[pin].setEnabled(true); // Pin is available\r
+                CPins[pin].setEnabled(true); // Changes to PIN allowed\r
+            } else {\r
+               CPinDir[pin].setEnabled(false); // Pin is not available\r
+                CPins[pin].setEnabled(false); // Changes to PIN not allowed\r
+            }\r
+            bitValue= (bitValue <<1) % 256;\r
+        }\r
+        UnlockButtons();\r
+    }\r
+\r
+    /**\r
+     * reads the XPort's I/O directions and displays them on an output field.\r
+     * There is no need to read more than bits 0 to 2 from byte 0 since the\r
+     * XPort does not have more than three I/O pins.\r
+     */\r
+    private void getCPinDir() {\r
+        int pin, bitValue;\r
+        \r
+        LockButtons();\r
+        try {\r
+            controlAntwort = IOControl1.getDir(IPAdresse.getText());\r
+        } catch (IOException IOEx) {\r
+            append(statusFeld,"I/O error while getting I/O directions: " + IOEx);\r
+        } catch (Exception Ex) {\r
+            append(statusFeld,"Error while getting I/O directions: " + Ex);\r
+        }\r
+\r
+        for (pin = 0, bitValue = 1; pin < NUMCPINS; pin++) {\r
+            if ((controlAntwort[pin/8] & bitValue) != 0) { // compare if bit is set\r
+               CPinDir[pin].setState(true); // Pin is an Output\r
+                CPins[pin].setEnabled(true); // Changes to PIN allowed\r
+            } else {\r
+               CPinDir[pin].setState(false); // Pin is an Input\r
+                CPins[pin].setEnabled(false); // Changes to PIN not allowed\r
+            }\r
+            bitValue= (bitValue <<1) % 256;\r
+        }\r
+        UnlockButtons();\r
+    }\r
+\r
+    /**\r
+     * reads the XPort's I/O pin's current state and displays them.\r
+     */\r
+    private void getCPins() {\r
+       int pin, bitValue;\r
+       \r
+       LockButtons();\r
+        try {\r
+            controlAntwort = IOControl1.getCurrentState(IPAdresse.getText());\r
+        } catch (IOException IOEx) {\r
+            append(statusFeld,"I/O error while getting current states: " + IOEx);\r
+        } catch (Exception Ex) {\r
+            append(statusFeld,"Error while getting current states: " + Ex);\r
+        }\r
+\r
+        for (pin = 0, bitValue = 1; pin < NUMCPINS; pin++) {\r
+            if ((controlAntwort[pin/8] & bitValue) != 0) { // compare if bit is set\r
+               CPins[pin].setState(true); // Pin is high\r
+            } else {\r
+               CPins[pin].setState(false); // Pin is Low\r
+            }\r
+            bitValue= (bitValue <<1) % 256;\r
+        }\r
+\r
+        \r
+        UnlockButtons();\r
+    }\r
+\r
+    /* \r
+     * Sends the System Date & Time to B-Modul \r
+     */\r
+    private void timerSetDateTime(){\r
+       Calendar cal = Calendar.getInstance();\r
+  \r
+               append(statusFeld,"Setting Date in c't-Netzschalter to: "+cal.getTime());\r
+               \r
+               int[] date = {\r
+                       (int)cal.get(Calendar.DAY_OF_MONTH), \r
+                       (int)cal.get(Calendar.MONTH)+1,\r
+                       (int)(cal.get(Calendar.YEAR) >> 8), \r
+                       (int)(cal.get(Calendar.YEAR) & 255),\r
+                               (int)(cal.get(Calendar.DAY_OF_WEEK))};\r
+\r
+               int[] time = {\r
+                       (int)cal.get(Calendar.HOUR_OF_DAY), \r
+                       (int)cal.get(Calendar.MINUTE),\r
+                       (int)cal.get(Calendar.SECOND)};\r
+               \r
+               \r
+               try {                   \r
+                       transmitCommand(CMD_SETDATE, date);\r
+                       transmitCommand(CMD_SETTIME, time);\r
+        } catch (IOException IOEx) {\r
+            append(statusFeld,"I/O error while setting Date and Time: " + IOEx);\r
+        } catch (Exception Ex) {\r
+            append(statusFeld,"Error while setting Date and Time: " + Ex);\r
+        }      \r
+    }\r
+\r
+    /* Read an Event from B-Module */\r
+    private void timerRead(){\r
+       int[] data={0};\r
+       int[] answer= new int[CMD_LENGTH];\r
+       int[] eventData= new int[TimerEvent.SIZE]; \r
+                       \r
+       data[0]=(int) Integer.valueOf("000000"+timerEventNr.getText(), 16).intValue() ;\r
+               try {                   \r
+                       transmitCommand(CMD_GETEVENT, data, answer, eventData );\r
+                       \r
+                       timerEvents.setText("of "+answer[2]+" Events");\r
+                       \r
+                       timerEvent= new TimerEvent(eventData);\r
+                       append(statusFeld,timerEvent.toString());\r
+                       \r
+                       timerChannel.setText(""+timerEvent.getChannel());\r
+                       timerData.setText(""+timerEvent.getData()); \r
+                       \r
+                       timerSpecial.setState(timerEvent.getSpecial());\r
+                       \r
+                       timerDay.setText(""+timerEvent.getDay());\r
+                       if (timerEvent.getDay() != TimerEvent.DONTCARE){\r
+                               timerDay.setEditable(true);\r
+                               timerDayDontCare.setState(true);\r
+                       } else {\r
+                               timerDay.setEditable(false);\r
+                               timerDayDontCare.setState(false);\r
+                       }\r
+                       \r
+                       timerMonth.setText(""+timerEvent.getMonth());                   \r
+                       if (timerEvent.getMonth() != TimerEvent.DONTCARE){\r
+                               timerMonth.setEditable(true);\r
+                               timerMonthDontCare.setState(true);\r
+                       } else {\r
+                               timerMonth.setEditable(false);\r
+                               timerMonthDontCare.setState(false);\r
+                       }\r
+\r
+                       \r
+                       timerYear.setText(""+timerEvent.getYear());\r
+                       if (timerEvent.getYear() != TimerEvent.DONTCARE){\r
+                               timerYear.setEditable(true);\r
+                               timerYearDontCare.setState(true);\r
+                       } else {\r
+                               timerYear.setEditable(false);\r
+                               timerYearDontCare.setState(false);\r
+                       }\r
+                       \r
+                       timerHour.setText(""+timerEvent.getHour());             \r
+                       if (timerEvent.getHour() != TimerEvent.DONTCARE){\r
+                               timerHour.setEditable(true);\r
+                               timerHourDontCare.setState(true);\r
+                       } else {\r
+                               timerHour.setEditable(false);\r
+                               timerHourDontCare.setState(false);\r
+                       }\r
+                       \r
+                       timerMinute.setText(""+timerEvent.getMinute());                 \r
+                       if (timerEvent.getMinute() != TimerEvent.DONTCARE){\r
+                               timerMinute.setEditable(true);\r
+                               timerMinuteDontCare.setState(true);\r
+                       } else {\r
+                               timerMinute.setEditable(false);\r
+                               timerMinuteDontCare.setState(false);\r
+                       }\r
+                       \r
+               timerSecond.setText(""+timerEvent.getSecond());\r
+                       if (timerEvent.getSecond() != TimerEvent.DONTCARE){\r
+                               timerSecond.setEditable(true);\r
+                               timerSecondDontCare.setState(true);\r
+                       } else {\r
+                               timerSecond.setEditable(false);\r
+                               timerSecondDontCare.setState(false);\r
+                       }\r
+                       \r
+               timerWeekday.setText(""+timerEvent.getWeekday());\r
+                       if (timerEvent.getWeekday() != TimerEvent.DONTCARE){\r
+                               timerWeekday.setEditable(true);\r
+                               timerWeekdayDontCare.setState(true);\r
+                       } else {\r
+                               timerWeekday.setEditable(false);\r
+                               timerWeekdayDontCare.setState(false);\r
+                       }\r
+                       \r
+                       \r
+        } catch (IOException IOEx) {\r
+            append(statusFeld,"I/O error while reading Event: " + IOEx);\r
+        } catch (Exception Ex) {\r
+            append(statusFeld,"Error while reading Event: " + Ex);\r
+        }      \r
+    }\r
+    \r
+    /* Writean Event to B-Module */\r
+    private void timerWrite(){\r
+       int[] answer = new int[CMD_LENGTH];\r
+       timerEvent= new TimerEvent();\r
+       \r
+       // First load all values from GUI to TimerEvent\r
+       timerEvent= new TimerEvent();\r
+       \r
+               timerEvent.setChannel( Integer.valueOf(timerChannel.getText()).intValue() );\r
+               timerEvent.setData( Integer.valueOf(timerData.getText()).intValue() );\r
+               timerEvent.setSpecial(timerSpecial.getState());\r
+               \r
+               if (timerDayDontCare.getState()== true)\r
+                       timerEvent.setDay  ( Integer.valueOf(timerDay.getText()).intValue() );\r
+               else \r
+                       timerEvent.setDay  (TimerEvent.DONTCARE);\r
+               \r
+               if (timerMonthDontCare.getState()== true)\r
+                       timerEvent.setMonth( Integer.valueOf(timerMonth.getText()).intValue() );\r
+               else \r
+                       timerEvent.setMonth  (TimerEvent.DONTCARE);\r
+\r
+               if (timerYearDontCare.getState()== true)\r
+                       timerEvent.setYear ( Integer.valueOf(timerYear.getText()).intValue() );\r
+               else \r
+                       timerEvent.setYear(TimerEvent.DONTCARE);\r
+\r
+               if (timerHourDontCare.getState()== true)\r
+                       timerEvent.setHour ( Integer.valueOf(timerHour.getText()).intValue() );\r
+               else \r
+                       timerEvent.setHour(TimerEvent.DONTCARE);\r
+\r
+               if (timerMinuteDontCare.getState()== true)\r
+                       timerEvent.setMinute( Integer.valueOf(timerMinute.getText()).intValue() );\r
+               else \r
+                       timerEvent.setMinute(TimerEvent.DONTCARE);\r
+\r
+               if (timerSecondDontCare.getState()== true)\r
+                       timerEvent.setSecond ( Integer.valueOf(timerSecond.getText()).intValue() );\r
+               else \r
+                       timerEvent.setSecond(TimerEvent.DONTCARE);\r
+\r
+               if (timerWeekdayDontCare.getState()== true)\r
+                       timerEvent.setWeekday ( Integer.valueOf(timerWeekday.getText()).intValue() );\r
+               else \r
+                       timerEvent.setWeekday(TimerEvent.DONTCARE);\r
+               \r
+               \r
+       int[] data={0};\r
+                       \r
+       data[0]=(int) Integer.valueOf("000000"+timerEventNr.getText(), 16).intValue() ;\r
+               try {                   \r
+                       transmitCommand(CMD_SETEVENT, data, answer, null, timerEvent.getSerial());                      \r
+                       \r
+        } catch (IOException IOEx) {\r
+            append(statusFeld,"I/O error while writing Event: " + IOEx);\r
+        } catch (Exception Ex) {\r
+            append(statusFeld,"Error while writing Event: " + Ex);\r
+        }      \r
+        \r
+        timerEvents.setText("of "+answer[2]+" Events");\r
+       \r
+       \r
+    }\r
+\r
+    /*\r
+     * Deletes a timerEvent\r
+     */\r
+    private void timerDelete(){\r
+               int[] data={0};\r
+       int[] answer= new int[CMD_LENGTH];\r
+                       \r
+       data[0]=(int) Integer.valueOf("000000"+timerEventNr.getText(), 16).intValue() ;\r
+               try {                   \r
+                       transmitCommand(CMD_DELETEEVENT, data, answer);\r
+                       \r
+                       timerEvents.setText("of "+answer[2]+" Events");\r
+\r
+                       if ((data[0] == answer[2])& (data[0]>0)){\r
+                               data[0]--;\r
+                               timerEventNr.setText(""+data[0]);\r
+                       }\r
+                       timerRead();\r
+                       \r
+        } catch (IOException IOEx) {\r
+            append(statusFeld,"I/O error while deleting Event: " + IOEx);\r
+        } catch (Exception Ex) {\r
+            append(statusFeld,"Error while deleting Event: " + Ex);\r
+        }      \r
+    }\r
+    \r
+    /**\r
+     * will end the connection to the XPort and re-enable the GUI elements faded\r
+     * out while the connection existed.\r
+     *  \r
+     */\r
+    private void disconnect() {\r
+        append(statusFeld,"Trying to disconnect...");\r
+        try {\r
+            XPort.disconnect(); // end connection and stop reading thread.\r
+            ReadThread.interrupt();\r
+            isConnected = false; // update connection flags\r
+            wasConnected = false;\r
+        } catch (IOException IOEx) {\r
+            append(statusFeld,"I/O error during disconnect: " + IOEx);\r
+        } catch (Exception Ex) {\r
+            append(statusFeld,"General error during disconnect: " + Ex);\r
+        }\r
+\r
+        Connect.setEnabled(true); // re-activate GUI elements\r
+        Disconnect.setEnabled(false); // and re-allow user to change IP address\r
+        IPAdresse.setEditable(true); // and port\r
+        PortField.setEditable(true);\r
+\r
+        append(statusFeld,"Connection closed.");\r
+    }\r
+\r
+    /**\r
+     * This method reads the input field after hitting enter and sends its\r
+     * content to the XPort. The string read is also displayed on the output\r
+     * textfield, preceded by >>.\r
+     */\r
+    private void sendText() {\r
+        try {\r
+            String sendString = eingabeFeld.getText();\r
+            XPort.send(sendString);\r
+            append(ausgabeFeld,"\n>> " + sendString);\r
+        } catch (IOException IOEx) {\r
+            append(statusFeld,"I/O error while reading: " + IOEx);\r
+        } catch (Exception Ex) {\r
+            append(statusFeld,"Error while reading: " + Ex);\r
+        }\r
+        eingabeFeld.setText("");\r
+        eingabeFeld.requestFocus();\r
+    }\r
+\r
+    /**\r
+     * Overrides ActionListener's actionPerformed(). To keep this method halfway\r
+     * simple and not too complex, it only calls other methods to do the actual\r
+     * work.\r
+     */\r
+    public void actionPerformed(ActionEvent e) throws NullPointerException {\r
+        if (e.getActionCommand() == Connect.getLabel()) { // Buttion "Connect"\r
+                                                          // was clicked\r
+            connect();\r
+            return;\r
+        }\r
+        if (e.getActionCommand() == Disconnect.getLabel()) {\r
+            // user wants to end the connection to the XPort\r
+            disconnect();\r
+            return;\r
+        }\r
+        \r
+        if (e.getActionCommand() == aPanelToBPanel.getLabel()) {\r
+            // switch from A panel to B panel and vice versa\r
+            changePanel('B');\r
+            return;\r
+        }\r
+        if (e.getActionCommand() == bPanelToTimerPanel.getLabel()) {\r
+            // switch from A panel to B panel and vice versa\r
+            changePanel('C');\r
+            return;\r
+        }\r
+        if (e.getActionCommand() == timerPanelToAPanel.getLabel()) {\r
+            // switch from A panel to B panel and vice versa\r
+            changePanel('A');\r
+            return;\r
+        }\r
+\r
+        \r
+        if (e.getActionCommand() == setCPins.getLabel()) {\r
+            // user wants to toggle some LEDs\r
+            setCPins();\r
+            return;\r
+        }\r
+        \r
+        if (e.getActionCommand() == getCPins.getLabel()) {\r
+            // user wants to know how many pins are available\r
+            getCPins();\r
+            return;\r
+        }\r
+        if (e.getActionCommand() == setCPinDir.getLabel()) {\r
+            // user wants to change I/O directions\r
+            setCPinDir();\r
+            return;\r
+        }\r
+\r
+        if (e.getActionCommand() == getCPinDir.getLabel()) {\r
+            // user wants to get the I/O directions updated\r
+               getCPinFunctions();\r
+            getCPinDir();\r
+            return;\r
+        }\r
+        if (e.getActionCommand() == sendCommand.getLabel()) {\r
+            // user wants to send a command to the B-Module\r
+            sendCommand();\r
+            return;\r
+        }\r
+\r
+        if (e.getSource() == eingabeFeld) {\r
+            // user wants to send some command to the XPort\r
+            sendText();\r
+        }\r
+        \r
+       if (e.getActionCommand() == getRelais.getLabel()) {\r
+               bReadRelais();\r
+       }\r
+\r
+       if (e.getActionCommand() == getSamples.getLabel()) {\r
+               bReadSamples();\r
+       }\r
+       \r
+       if (e.getActionCommand() == timerSetDateTime.getLabel()) {\r
+               timerSetDateTime();\r
+       }\r
+       \r
+       if (e.getActionCommand() == timerRead.getLabel()) {\r
+               timerRead();\r
+       }\r
+       \r
+       if (e.getActionCommand() == timerWrite.getLabel()) {\r
+               timerWrite();\r
+       }       \r
+       \r
+       if (e.getActionCommand() == timerDelete.getLabel()) {\r
+               timerDelete();\r
+       }       \r
+       \r
+       \r
+       for (int i=0; i< NUMRELAIS; i++){\r
+               if (e.getActionCommand() == relais[i].getLabel()) {\r
+                       switchRelais(i);\r
+               }\r
+        }\r
+    }\r
+\r
+    /*\r
+     * Displays the values of relaisValues\r
+     */\r
+    private void showRelais(){\r
+       for (int i=0; i< NUMRELAIS; i++){\r
+               if ((relaisValues & (1<<i)) > 0)\r
+                       relais[i].setBackground(Color.yellow);\r
+               else\r
+                       relais[i].setBackground(Color.gray);\r
+               relais[i].setEnabled(true); // buttons are allowed after 1st update\r
+       }\r
+    }\r
+\r
+    /* \r
+     * Reads 64 AD-Samples from B-Module\r
+     */\r
+    synchronized private void bReadSamples(){\r
+        int[] data = new int[1];\r
+        int[] dataAntwort = new int[64*7];\r
+        int[] answer = new int[CMD_LENGTH];\r
+        \r
+        data[0]=(int) Integer.valueOf("000000"+adcChannel.getText(), 16).intValue() ;\r
+        \r
+        if (useFilter.getState())\r
+               data[0]+=0x80;  // Wenn der Filter verwendet werden soll, dann Bit 7 setzen\r
+        \r
+        try {\r
+               transmitCommand(CMD_READADC_64,data,answer,dataAntwort);\r
+        } catch (IOException IOEx) {\r
+               append(statusFeld,"I/O error while reading Samples: " + IOEx);\r
+           } catch (Exception Ex) {\r
+               append(statusFeld,"Error while  reading Samples: " + Ex);\r
+           }        \r
+        \r
+           byte[] byteData= new byte[dataAntwort.length];\r
+           for (int i=0; i<dataAntwort.length; i++)\r
+               byteData[i]=(byte)(dataAntwort[i]);\r
+           \r
+       int[] samples = new int[64];\r
+       for (int i=0; i< 64; i++){                      \r
+               samples[i]=new Integer(new String(byteData,i*7,6)).intValue();                  \r
+       }       \r
+\r
+       int min, max;\r
+       if ((data[0] & 0x80) > 0){ // 50 Hz Filter an?\r
+               max= 11000;                     min= -max;\r
+       } else {\r
+               max= 1024;                      min= 0;\r
+       }\r
+       oszilloskop.setData(samples,min,max);\r
+    }\r
+    \r
+    \r
+    /*\r
+     * Reads the current State of the Relais\r
+     */\r
+    synchronized private void bReadRelais(){\r
+        int[] antwort = new int[CMD_LENGTH];\r
+        \r
+        try{\r
+               transmitCommand(CMD_READRELAIS,null,antwort);\r
+        } catch (IOException IOEx) {\r
+            append(statusFeld,"I/O error while Reading Relais: " + IOEx);\r
+        } catch (Exception Ex) {\r
+            append(statusFeld,"Error while Reading Relais: " + Ex);\r
+        }\r
+        \r
+        relaisValues =antwort[2];\r
+               \r
+        showRelais();\r
+            \r
+    }\r
+    \r
+    \r
+    /**\r
+     * Toggles one of the Relais\r
+        * @param i The Relais\r
+        */\r
+       synchronized private void switchRelais(int channel) {\r
+        int[] data = { 0};\r
+        int[] answer = new int[CMD_LENGTH];\r
+                \r
+        \r
+        // First ask for State of Relais\r
+        try { \r
+               transmitCommand(CMD_READRELAIS,data,answer);\r
+               \r
+               data[0]=answer[2];\r
+               \r
+               // alle anderen Relais lassen, wie sie waren\r
+               data[0] &=  (~(1 << channel));\r
+               \r
+               // den einen Kanal Invertieren und dann dazupacken\r
+               data[0] += (~relaisValues) & (1 << channel);\r
+               \r
+               transmitCommand(CMD_SETRELAIS,data,answer);\r
+        \r
+            relaisValues=answer[2];\r
+            \r
+        } catch (IOException IOEx) {\r
+            append(statusFeld,"I/O error while switching Relais: " + IOEx);\r
+        } catch (Exception Ex) {\r
+            append(statusFeld,"Error while switching Relais: " + Ex);\r
+        }\r
+        \r
+        showRelais();\r
+               \r
+       }\r
+\r
+\r
+\r
+       /**\r
+     * Will lock the GUI's buttons during execution of a command to keep the\r
+     * user from doing stupid things.\r
+     */\r
+\r
+    private void LockButtons() {\r
+        setCPins.setEnabled(false);\r
+        getCPins.setEnabled(false);\r
+\r
+        setCPinDir.setEnabled(false);\r
+        getCPinDir.setEnabled(false);\r
+//      getState.setEnabled(false);\r
+        return;\r
+    }\r
+\r
+    /** After execution of a command, re-enables the GUI's buttons */\r
+    private void UnlockButtons() {\r
+        setCPins.setEnabled(true);\r
+        getCPins.setEnabled(true);\r
+\r
+        getCPinDir.setEnabled(true);\r
+        setCPinDir.setEnabled(true);\r
+//      getState.setEnabled(true);\r
+        return;\r
+    }\r
+\r
+    /**\r
+     * Will determine which LEDs are to be set. Just a helper method for\r
+     * toggleLED().\r
+     */\r
+    private int LEDauswert() {\r
+        int activeLEDs = 0;\r
+        int bitv = 1;\r
+        for (int i = 0; i < NUMCPINS; i++) {\r
+            if (CPins[i].getState()) {\r
+                activeLEDs |= bitv;\r
+            }\r
+            bitv <<= 1;\r
+        }\r
+        return activeLEDs;\r
+    }\r
+\r
+    /**\r
+     * Will determine which I/O directions are to be changed. Another helper\r
+     * method.\r
+     * \r
+     * @return\r
+     */\r
+    private int IOauswert() {\r
+        int activePins = 0;\r
+        int bitv = 1;\r
+        for (int i = 0; i < NUMCPINS; i++) {\r
+            if (CPinDir[i].getState()) {\r
+                activePins |= bitv;\r
+            }\r
+            bitv <<= 1;\r
+        }\r
+        return activePins;\r
+    }\r
+\r
+    private void transmitCommand(int command, int[] data) throws Exception{\r
+       transmitCommand(command, data, null);\r
+    }\r
+    \r
+    private void transmitCommand(int command, int[] data, int[] answer) throws Exception{\r
+       transmitCommand(command,data,answer,null);\r
+    }\r
+           \r
+    /* Transmit data and expects retour data before the regular answer of B-Module\r
+     * length of retour-data is spefified by retour.length\r
+     */\r
+    private void transmitCommand(int command, int[] data, int[] answer, int[] retour) throws Exception{\r
+       transmitCommand(command,data,answer,retour,null);\r
+    }    \r
+    \r
+    /* Transmit data and expects retour data before the regular answer of B-Module\r
+     * length of retour-data is spefified by retour.length\r
+     * length of data to xport is specified by payload.length \r
+     */\r
+    private void transmitCommand(int command, int[] data, int[] answer, int[] retour, int[] payload) throws Exception{\r
+        int[] fullCommand = new int [CMD_LENGTH];\r
+        int length;\r
+        \r
+        if (data!=null)\r
+               length=data.length;\r
+        else \r
+               length=0;\r
+        \r
+        // construct Command\r
+        fullCommand[0]= START_CODE;            fullCommand[CMD_LENGTH-1]=STOP_CODE;\r
+        fullCommand[1]= command; \r
+        for (int i=2; i<CMD_LENGTH-1; i++ )\r
+               if (i-2 < length)\r
+                       fullCommand[i]=data[i-2];\r
+               else \r
+                       fullCommand[i]=0;\r
+        \r
+        // only connect to bridging port if not yet connected because the\r
+        // XPort only allows one connection to one port at a time\r
+        if (!isConnected\r
+                & (Integer.parseInt(PortField.getText()) == bridgePort)) {\r
+            connect();\r
+            wasConnected = false; // note that there was no connection\r
+                                                 // in the first place, so that we need to disconnect\r
+                                                 // after the command is sent.\r
+        }\r
+\r
+        ReadThread.pause_on();         // Turn off Read-Thread\r
+        \r
+        XPort.send(fullCommand);       // send data\r
+\r
+\r
+        /* Do we have to receive data before receiving the answer frame? */\r
+        if (payload != null){ \r
+               XPort.send(payload);\r
+        }      \r
+\r
+        //      Wait for answer\r
+        int timeout=0;\r
+        while ((!XPort.DataReady()) & (timeout<20) ){\r
+               try {\r
+                       Thread.sleep(100);\r
+               } catch (InterruptedException ex){}\r
+               timeout++;\r
+        }\r
+                \r
+        /* Do we have to receive data before receiving the answer frame? */\r
+        if (retour != null) {\r
+               length=XPort.readBuffer(retour,retour.length);\r
+               if (length != retour.length) \r
+                       throw (new Exception("Not enough Data received"));\r
+               \r
+            //      Wait for answer\r
+            timeout=0;\r
+            while ((!XPort.DataReady()) & (timeout<20) ){\r
+               try {\r
+                       Thread.sleep(100);\r
+               } catch (InterruptedException ex){}\r
+               timeout++;\r
+            }\r
+        }\r
+        \r
+        \r
+        if (answer==null)\r
+               answer = new int[CMD_LENGTH];\r
+        \r
+       length=XPort.readBuffer(answer,CMD_LENGTH);\r
+       \r
+        ReadThread.pause_off();        // Turn on Read-Thread\r
+\r
+       \r
+       if ((answer[0] != START_CODE) |(answer[1] != command)\r
+                       |(answer[CMD_LENGTH-1] != STOP_CODE)|(length !=CMD_LENGTH)){\r
+               throw(new Exception("No correct answer from B-Module"));\r
+       }\r
+        \r
+       \r
+        // check wasConnected if we need to close the connection \r
+        if (wasConnected == false) {\r
+            try {\r
+                disconnect();\r
+            } catch (Exception ex) {\r
+                append(statusFeld,"Error while trying to disconnect: " + ex);\r
+                throw(ex);\r
+            }\r
+        }                \r
+    }\r
+    \r
+    \r
+    \r
+    /**\r
+     * will evaluate the B panel's GUI elements, create a command from them and\r
+     * send this command to the B-Module via the XPort's TCP/IP connection. An\r
+     * already existing connection to port 10001 is used if available. If not\r
+     * connected to port 10001 yet, this method will establish a connection to\r
+     * that port, send the command and close the conenction to 10001.\r
+     *  \r
+     */\r
+    private void sendCommand() {\r
+        // These calls will convert the values typed into the B panel's\r
+        // textfields\r
+        // into hex bytes and put them into an array of bytes.\r
+\r
+        int command = (int) Integer.valueOf("000000"+Command.getText(), 16).intValue();\r
+        \r
+        String dataText=Data.getText();\r
+        \r
+        //int data = (int) Integer.valueOf("000000"+Data.getText(), 16).intValue() ;\r
+        int[] fullCommand = new int [CMD_LENGTH];\r
+        fullCommand[0]= START_CODE;\r
+        fullCommand[1]= command; \r
+        \r
+        String dummy;\r
+        \r
+        for (int i=2; i<CMD_LENGTH-1; i++ ){\r
+               try {\r
+                       dummy="000000"+dataText.charAt((i-2)*2)+dataText.charAt((i-2)*2+1);\r
+                       fullCommand[i]= (int) Integer.valueOf(dummy,16).intValue();\r
+               } catch (StringIndexOutOfBoundsException ex){   }\r
+               \r
+        }        \r
+        \r
+        fullCommand[CMD_LENGTH-1]=STOP_CODE;\r
+        \r
+        if (!isConnected\r
+                & (Integer.parseInt(PortField.getText()) == bridgePort)) {\r
+            // only connect to bridging port if not yet connected because the\r
+            // XPort only allows one connection to one port at a time\r
+            connect();\r
+            wasConnected = false; // note that there was no connection to port\r
+                                  // 10001\r
+            // in the first place, so that we need to disconnect\r
+            // after the command is sent.\r
+        }\r
+        try { // send data\r
+            XPort.send(fullCommand);\r
+        } catch (IOException IOEx) {\r
+            append(statusFeld,"I/O error while reading: " + IOEx);\r
+        } catch (Exception Ex) {\r
+            append(statusFeld,"Error while reading: " + Ex);\r
+        }\r
+        // check wasConnected if we need to close the connection to port 10001\r
+        // and\r
+        // disconnect if neccessary.\r
+        if (wasConnected == false) {\r
+            try {\r
+                disconnect();\r
+            } catch (Exception Ex) {\r
+                append(statusFeld,"Error while trying to disconnect: " + Ex);\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Prints the current time, its parameter string and \n to the output\r
+     * textfield.\r
+     */\r
+    private void append(TextArea textArea, String output) {\r
+        /*Date*/ Calendar now = Calendar.getInstance();//.getTime();\r
+        String b = "" + now.get(Calendar.HOUR_OF_DAY);//   now.getHours();\r
+        if (b.length() == 1)\r
+            b = "0" + b;\r
+        textArea.append("[" + b);\r
+        b = "" + now.get(Calendar.MINUTE);   //getMinutes();\r
+        if (b.length() == 1)\r
+            b = "0" + b;\r
+        textArea.append(":" + b);\r
+        b = "" + now.get(Calendar.SECOND); //getSeconds();\r
+        if (b.length() == 1)\r
+            b = "0" + b;\r
+        textArea.append(":" + b + "] " + output + "\n");\r
+    }\r
+\r
+    /**\r
+     * This Thread will loop while a connection to the XPort exists. It will\r
+     * wait for data to read and display it on the Applet's textfield. Numbers\r
+     * and ASCII chars will be displayed as such, whereas non-readable ASCII\r
+     * chars will show up as bytes in a (0xbyte) form.\r
+     */\r
+    private class InputReadThread extends Thread {\r
+       GUI gui = null;\r
+       private boolean pause = false;\r
+       /*\r
+        * Schaltet den ReadThread solange ab, bis ein continue kommt\r
+        */\r
+       public void pause_on(){\r
+               pause=true;\r
+       }\r
+       \r
+       /*\r
+        * Schaltet den ReadThread wieder an\r
+        */\r
+       synchronized public void pause_off(){\r
+               pause=false;\r
+       }       \r
+\r
+       synchronized private String parseString(int[] s, int length){\r
+               String gelesen= "";\r
+               \r
+               for (int i=0; i< length; i++){\r
+                       if (gui.showASCII.getState()){ //Try to convert Message to Ascii\r
+                           // scan for printable ASCII characters and add them to gelesen\r
+                           switch (s[i]) {\r
+                               case 0x0a: gelesen += "\n"; // add Line Feed\r
+                                       break;\r
+                               case 0x20: gelesen += " "; // add Blank\r
+                                               break;\r
+                               case 0x0d: gelesen += "\r"; // add Carriage Return\r
+                                       break;\r
+                               case 0x09: gelesen += "\t"; // add Tab\r
+                                       break;\r
+                               case 0x00:  // ignore 0\r
+                                               break;  \r
+                               default :\r
+                                       if (s[i] > 0x20 && s[i] < 0x7e)  // add readable chars\r
+                                           gelesen += new Character((char) s[i]).toString();\r
+                                 //  else // add non-readable chars as bytes in brackets\r
+                                 //    gelesen += " (0x" + Integer.toHexString(s[i])+ ") "; \r
+                                    \r
+                              }\r
+                       } else  // Show message as Hex\r
+                               gelesen += " (0x" + Integer.toHexString(s[i])+ ") ";\r
+               } \r
+               return gelesen;\r
+       }\r
+       \r
+       \r
+       \r
+        public void run() {\r
+               int length=512;\r
+               int[] gelesen= new int[length];\r
+               \r
+               try { // since we need to handle some possible exceptions,\r
+\r
+                       while (!isInterrupted()) { // run while needed\r
+       \r
+\r
+                               if (!pause){\r
+                                       // check if data is available\r
+                                                   \r
+                           if (! XPort.DataReady()) { // wait while no data\r
+                               sleep(10);\r
+                           } else { \r
+                               // receive data, \r
+                               length=XPort.readBuffer(gelesen,length);\r
+                               // display it \r
+                               append(ausgabeFeld,parseString(gelesen,length));\r
+                               // clear the input field\r
+                               eingabeFeld.setText("");\r
+                           }\r
+                       }\r
+\r
+                       }\r
+               \r
+               } catch (InterruptedException iEx){\r
+//                     append(statusFeld,"Read-Loop, Interrupted:  " + iEx);\r
+               } catch (Exception ex) {\r
+                   append(statusFeld,"Error in Read-Loop, Dying:  " + ex);\r
+               }\r
+        }\r
+    }\r
+\r
+    \r
+    private class Oszilloskop extends Panel{\r
+\r
+       private int[] data= null;\r
+       private int min=0;\r
+       private int max=0;\r
+       private int maxAmplitude=0;\r
+       \r
+       public Dimension getMinimumSize(){\r
+               return new Dimension(200,100);  \r
+        }\r
+       \r
+       public void paint(Graphics g) {\r
+            Graphics2D g2 = (Graphics2D) g;\r
+            g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);\r
+            Dimension d = getSize();\r
+            FontMetrics fontMetrics = g2.getFontMetrics();\r
+            int gridWidth = d.width / 6;\r
+            int gridHeight = d.height / 2;\r
+\r
+            int x,y;\r
+//            fontMetrics = pickFont(g2, "Filled and Stroked GeneralPath",\r
+ //                                  gridWidth);\r
+            setBackground(Color.black);\r
+            \r
+            Color fg3D = Color.white;\r
+\r
+            g2.setPaint(fg3D);\r
+            g2.drawRect(0, 0, d.width - 1, d.height - 1);\r
+            //g2.drawRect(3, 3, d.width - 7, d.height - 7);\r
+\r
+            \r
+            if (data!= null){\r
+                       // factor zum Skalieren\r
+                       float yscale= (float)(d.height-2)/ (float)maxAmplitude;\r
+                       int offset= (int)(-(min *yscale)+2); \r
+                               \r
+                       float xscale= (float)d.width/(float)data.length;\r
+                       \r
+                   // Beschriftung und Achsen\r
+                       g2.setPaint(Color.yellow);\r
+\r
+                   String label = new Integer(min).toString();\r
+                   g2.drawString(label, d.width-fontMetrics.stringWidth(label), d.height-2 );\r
+                   \r
+                   label=new Integer(max).toString();\r
+                   g2.drawString(label, d.width-fontMetrics.stringWidth(label),fontMetrics.getHeight());\r
+\r
+                   if (min <0){\r
+                           y=d.height-offset;\r
+                           label = "0";\r
+                           g2.drawString(label, d.width-fontMetrics.stringWidth(label), y +fontMetrics.getHeight()/2);\r
+                   \r
+                       g2.draw(new Line2D.Double(1, y,d.width-2-fontMetrics.stringWidth("0"),y));\r
+                   }\r
+                   // Horizontal Line all 8 samples\r
+                   for (int i=8; i<64; i+=8){\r
+                           g2.draw(new Line2D.Double(i*xscale, 1,i*xscale,d.height-2));                        \r
+                   }\r
+\r
+                       x=0;\r
+                       y=d.height-((int)(data[0]*yscale)+offset);\r
+                       int oldx,oldy;\r
+\r
+                   \r
+                       // Daten\r
+                       g2.setPaint(Color.green);\r
+                       for (int i=1; i< data.length-1; i++){\r
+                       oldx=x; oldy=y;\r
+                       x=(int)(i*xscale); y=d.height-((int)(data[i]*yscale)+offset);\r
+                       g2.draw(new Line2D.Double(oldx, oldy,x,y));\r
+                   }\r
+                                   \r
+            }                  \r
+            g2.setPaint(Color.black);\r
+           \r
+       }\r
+               /**\r
+                * @param data The data to set.\r
+                */\r
+               public void setData(int[] data,int min, int max) {\r
+                       this.data = new int[data.length];\r
+                       this.min=min;\r
+                       this.max=max;\r
+                       \r
+                       for (int i=0; i<data.length; i++){\r
+                               this.data[i] = data[i];\r
+//                             if (min> this.data[i]) min=this.data[i];\r
+//                             if (max< this.data[i]) max=this.data[i];\r
+                       }\r
+                       maxAmplitude=max-min;\r
+                       \r
+                       repaint();\r
+               }\r
+    }\r
+\r
+       /* (non-Javadoc)\r
+        * @see java.awt.event.ItemListener#itemStateChanged(java.awt.event.ItemEvent)\r
+        */\r
+       public void itemStateChanged(ItemEvent event) {\r
+               if (timerHourDontCare.getState()== true) timerHour.setEditable(true);\r
+                 else  timerHour.setEditable(false);\r
+                       \r
+               if (timerMinuteDontCare.getState()== true) timerMinute.setEditable(true);\r
+                 else  timerMinute.setEditable(false);\r
+               \r
+               if (timerSecondDontCare.getState()== true) timerSecond.setEditable(true);\r
+                 else  timerSecond.setEditable(false);\r
+\r
+               if (timerDayDontCare.getState()== true) timerDay.setEditable(true);\r
+                 else  timerDay.setEditable(false);\r
+                       \r
+               if (timerMonthDontCare.getState()== true) timerMonth.setEditable(true);\r
+                 else  timerMonth.setEditable(false);\r
+               \r
+               if (timerYearDontCare.getState()== true) timerYear.setEditable(true);\r
+                 else  timerYear.setEditable(false);\r
+\r
+               if (timerWeekdayDontCare.getState()== true) timerWeekday.setEditable(true);\r
+                 else  timerWeekday.setEditable(false);\r
+       }\r
+               \r
+}\r
+    \r
+    \r
+\r
diff --git a/projekte/netzschalter/src/IOControl.java b/projekte/netzschalter/src/IOControl.java
new file mode 100644 (file)
index 0000000..0f2fba2
--- /dev/null
@@ -0,0 +1,294 @@
+/*\r
+ * File IOControl.java\r
+ */\r
+\r
+import java.io.IOException;\r
+\r
+/**\r
+ * @author olz\r
+ * \r
+ * TODO To change the template for this generated type comment go to Window -\r
+ * Preferences - Java - Code Generation - Code and Comments\r
+ */\r
+/**\r
+ * This class will be responsible for all sorts of I/O and LED controls.\r
+ * \r
+ * @author olz\r
+ * \r
+ * TODO To change the template for this generated type comment go to Window -\r
+ * Preferences - Java - Code Generation - Code and Comments\r
+ */\r
+public class IOControl {\r
+\r
+    /**\r
+     * this static byte contains a value to select all the XPort's LEDs( decimal\r
+     * 7 = bin 00000111; Bits 0 to 2 are set\r
+     */\r
+    private static final byte maxLEDLo = (byte) 0xFF; // new for WiPort, really\r
+                                                      // 7;\r
+\r
+    private static final byte maxLEDHi = 0x07; // noch! :) 7;\r
+\r
+    /**\r
+     * this static int states the port on which the XPort's I/O settings are\r
+     * changed\r
+     */\r
+    private static final int IOPort = 0x77f0;\r
+\r
+    /** this static int states the length of an XPort's answer in bytes */\r
+    private static final int cmdLength = 5; // was 9 = Wrong! --plymo-- 26.12.2004\r
+\r
+    // XPort Commands fixed as bytes\r
+    /** this static byte is set to the value of GetFunction \r
+     * Checks which Pins are availbale to user and not used for RTS and Co.\r
+     * */\r
+    private static final byte cmdGetFunc = 0x10;\r
+\r
+    /** this static byte is set to the value of GetDirections */\r
+    private static final byte cmdGetDir = 0x11;\r
+\r
+    /** this static byte is set to the value of Get Active Levels */\r
+    private static final byte cmdGetActLvl = 0x12;\r
+\r
+    /** this static byte is set to the value of Get Current State */\r
+    private static final byte cmdGetCurrState = 0x13;\r
+\r
+    /** this static byte is set to the value of Set Direction */\r
+    private static final byte cmdSetDir = 0x19;\r
+\r
+    /** this static byte is set to the value of Set Active Level */\r
+    private static final byte cmdsetActLvl = 0x1a;\r
+\r
+    /** this static byte is set to the value of Set Current State */\r
+    private static final byte cmdSetCurrState = 0x1b;\r
+\r
+    /** initialisation of variable antwort, which will return the XPort's antwort */\r
+    byte[] antwort = { 0, 0, 0, 0, 0 };\r
+\r
+    /**\r
+     * initialisation of variable antwort_null, which be used to reset antwort.\r
+     * In case of errors, antwort will remain 0,0,0,0,0 so that error handling\r
+     * is possible\r
+     */\r
+    byte[] antwort_null = { 0, 0, 0, 0, 0 };\r
+\r
+    /** this instance will control the XPort for this class */\r
+    private Communication XPort1;\r
+\r
+    /**\r
+     * this method will read out and return the current states of the I/O pins\r
+     * \r
+     * @param ipa\r
+     * @return\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public byte[] getActiveLevel(String ipa) throws IOException, Exception {\r
+\r
+        int[] command = { cmdGetActLvl, 0, 0, 0, 0, // no parameters needed\r
+                0, 0, 0, 0 };\r
+        antwort = antwort_null;\r
+        try {\r
+            antwort = sendCommand(ipa, IOPort, command, cmdLength);\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        return antwort;\r
+    }\r
+\r
+    /**\r
+     * this method will switch the I/O pins' directions according to the\r
+     * parameter\r
+     * \r
+     * @param ipa\r
+     * @param NumLed\r
+     * @return\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public byte[] toggleDirection(String ipa, int NumLed) throws IOException,\r
+            Exception {\r
+\r
+        int[] command = { cmdSetDir, maxLEDLo, maxLEDHi, 0, 0,\r
+                (byte) (NumLed & maxLEDLo), (byte) ((NumLed >> 8) & maxLEDHi), 0, 0 };\r
+\r
+        antwort = antwort_null;\r
+        try {\r
+            antwort = sendCommand(ipa, IOPort, command, cmdLength);\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        return antwort;\r
+    }\r
+\r
+    /**\r
+     * will read out and return the I/O pins' current states\r
+     * \r
+     * @param ipa\r
+     * @return\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public byte[] getCurrentState(String ipa) throws IOException, Exception {\r
+        int[] command = { cmdGetCurrState, 0, 0, 0, 0, // no parameters needed\r
+                0, 0, 0, 0 };\r
+        antwort = antwort_null;\r
+        try {\r
+            antwort = sendCommand(ipa, IOPort, command, cmdLength);\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        return antwort;\r
+\r
+    }\r
+\r
+    /**\r
+     * will establish a connection according to the parameters ipa and port\r
+     * \r
+     * @param ipa\r
+     * @param port\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public void connectLED(String ipa, int port) throws IOException, Exception {\r
+        XPort1 = new Communication(); // preparing a new connection\r
+        try {\r
+            XPort1.connect(ipa, port);\r
+            // connecting to new XPort instance on LED switching port\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * will toggle LEDs on and off acccording to its parameter's value\r
+     * \r
+     * @param ipa - IPAddress\r
+     * @param NumLed - Bit-Coded which LED to turn ON or OFF \r
+     * @return - antwort array ob 5 bytes\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public byte[] toggle(String ipa, int NumLed) throws IOException, Exception {\r
+\r
+        byte ValueLedLo = 0;\r
+        byte ValueLedHi = 0;\r
+        ValueLedLo = (byte) NumLed;\r
+        ValueLedHi = (byte) (NumLed >> 8);\r
+        System.out.println("Toggle Anfang");\r
+        int[] command = { cmdSetCurrState, maxLEDLo, maxLEDHi, 0, 0, // maxLED\r
+                                                                      // sets\r
+                                                                      // all\r
+                                                                      // LEDs\r
+                                                                      // ready\r
+                                                                      // for\r
+                                                                      // change\r
+                ValueLedLo, ValueLedHi, 0, 0 }; // toggles the LEDs on / off\r
+                                                // according to the value\r
+        antwort = antwort_null;\r
+        try {\r
+            antwort = sendCommand(ipa, IOPort, command, cmdLength);\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        return antwort;\r
+    }\r
+\r
+    /**\r
+     * will connect to the XPort located at the IP ipa and the port port, then\r
+     * send a command as given in command[], end the connection and return the\r
+     * answer\r
+     * \r
+     * @param ipa\r
+     * @param port\r
+     * @param command\r
+     * @param length\r
+     * @return\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public byte[] sendCommand(String ipa, int port, int[] command, int length)\r
+            throws IOException, Exception {\r
+        connectLED(ipa, port);\r
+        try {\r
+            XPort1.send(command);\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        try {\r
+            antwort = (XPort1.receiveByteArray(length));\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        try {\r
+            XPort1.disconnect();\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+\r
+        return antwort;\r
+    }\r
+\r
+    /**\r
+     * will receive the number of I/O pins available on the XPort\r
+     * \r
+     * @param ipa\r
+     * @return\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public byte[] getFunc(String ipa) throws IOException, Exception {\r
+\r
+        int[] command = { cmdGetFunc, 0, 0, 0, 0, // no paramters needed\r
+                0, 0, 0, 0 };\r
+        antwort = antwort_null;\r
+        try {\r
+            antwort = sendCommand(ipa, IOPort, command, cmdLength);\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        return antwort;\r
+\r
+    }\r
+\r
+    /**\r
+     * reads the I/O pins' directions from the XPort and returns them\r
+     * \r
+     * @param ipa\r
+     * @return\r
+     * @throws IOException\r
+     * @throws Exception\r
+     */\r
+    public byte[] getDir(String ipa) throws IOException, Exception {\r
+\r
+        //System.out.println("ToggleOn Anfang");\r
+        int[] command = { cmdGetDir, 0, 0, 0, 0, 0, 0, 0, 0 };\r
+        antwort = antwort_null;\r
+        try {\r
+            antwort = sendCommand(ipa, IOPort, command, cmdLength);\r
+        } catch (IOException IOEx) {\r
+            throw IOEx;\r
+        } catch (Exception Ex) {\r
+            throw Ex;\r
+        }\r
+        return antwort;\r
+    }\r
+}\r
diff --git a/projekte/netzschalter/src/TimerEvent.java b/projekte/netzschalter/src/TimerEvent.java
new file mode 100644 (file)
index 0000000..565359a
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * Created on 04.10.2005
+ *
+ * TODO To change the template for this generated file go to
+ * Window - Preferences - Java - Code Style - Code Templates
+ */
+
+/**
+ * @author bbe
+ *
+ * Container for an Event
+ */
+
+public class TimerEvent {
+       
+       private int special;            // Special Event oder nicht?
+       private int channel;            // Maske für die betroffenen Kanäle
+       private int data;                       // Werte für die betroffenen Kanäle
+       
+       private int second;             // Zeitpunkt des Ereignisses
+       private int minute;             // wird ein Feld nicht benutzt, steht es 
+       private int hour;                       // auf DONTCARE
+       private int day;
+       private int month;
+       private int year;               // Achtung das Jahr 255 bedeutet DONTCARE
+       private int weekday;
+       
+       public static int DONTCARE      = 255;
+       public static int SIZE = 10;
+       
+       /**
+        * 
+        */
+       public TimerEvent() {
+               super();
+       }
+       /* Create an Event from serial Data */
+       public TimerEvent(int[] newData){
+               super();
+               timerFromSerial(newData);
+       }
+       
+       /* Initializes an event from a serial data Stream */
+       public void timerFromSerial(int[] newData){
+               int i=0;
+               
+               second= newData[i++];
+               minute= newData[i++]; 
+               hour=   newData[i++];
+               day=    newData[i++];
+               month=  newData[i++];
+               year=   newData[i++] +  newData[i++]*256;
+               weekday=newData[i++];
+               
+               special= (newData[i]>>7) & 1;
+               channel=  newData[i++] & 0x7F;
+               data=  newData[i++];
+
+       }
+       
+       public String toString(){
+               String str = "";
+               
+               if (day==DONTCARE) str+="XX."; else str+=day+".";
+               if (month==DONTCARE) str+="XX."; else str+=month+".";
+               if (year==DONTCARE) str+="XXXX "; else str+=year+" ";
+
+               str+=weekday+" ";
+               
+               if (hour==DONTCARE) str+="XX:"; else str+=day+":";
+               if (minute==DONTCARE) str+="XX:"; else str+=minute+":";
+               if (second==DONTCARE) str+="XXXX "; else str+=second+" ";
+
+               str+="Type: "+special+" Ch: "+channel+" Value: "+data;
+               return str;
+       }
+       
+       public int[] getSerial(){
+               int[] serial = new int[SIZE];
+               
+               int i=0;
+                               
+               serial[i++]= second;            // Zeitpunkt des Ereignisses
+               serial[i++]= minute;            // wird ein Feld nicht benutzt, steht es 
+               serial[i++]= hour;                      // auf DONTCARE
+               serial[i++]= day;
+               serial[i++]= month;
+               serial[i++]= year & 0xFF;               // Achtung das Jahr 255 bedeutet DONTCARE
+               serial[i++]= (year /256) &0xFF;         // Achtung das Jahr 255 bedeutet DONTCARE
+               
+               serial[i++]=weekday;
+               
+               serial[i++]= (channel & 0x7F) | ((special << 7) & 0x80);                // Maske für die betroffenen Kanäle
+               serial[i++]= data;                      // Werte für die betroffenen Kanäle
+
+               
+               return serial;
+       }
+       /**
+        * @return Returns the channel.
+        */
+       public int getChannel() {
+               return channel;
+       }
+       /**
+        * @param channel The channel to set.
+        */
+       public void setChannel(int channel) {
+               this.channel = channel;
+       }
+       /**
+        * @return Returns the data.
+        */
+       public int getData() {
+               return data;
+       }
+       /**
+        * @param data The data to set.
+        */
+       public void setData(int data) {
+               this.data = data;
+       }
+       /**
+        * @return Returns the day.
+        */
+       public int getDay() {
+               return day;
+       }
+       /**
+        * @param day The day to set.
+        */
+       public void setDay(int day) {
+               this.day = day;
+       }
+       /**
+        * @return Returns the hour.
+        */
+       public int getHour() {
+               return hour;
+       }
+       /**
+        * @param hour The hour to set.
+        */
+       public void setHour(int hour) {
+               this.hour = hour;
+       }
+       /**
+        * @return Returns the minute.
+        */
+       public int getMinute() {
+               return minute;
+       }
+       /**
+        * @param minute The minute to set.
+        */
+       public void setMinute(int minute) {
+               this.minute = minute;
+       }
+       /**
+        * @return Returns the month.
+        */
+       public int getMonth() {
+               return month;
+       }
+       /**
+        * @param month The month to set.
+        */
+       public void setMonth(int month) {
+               this.month = month;
+       }
+       /**
+        * @return Returns the second.
+        */
+       public int getSecond() {
+               return second;
+       }
+       /**
+        * @param second The second to set.
+        */
+       public void setSecond(int second) {
+               this.second = second;
+       }
+       /**
+        * @return Returns the year.
+        */
+       public int getYear() {
+               return year;
+       }
+       /**
+        * @param year The year to set.
+        */
+       public void setYear(int year) {
+               this.year = year;
+       }
+       /**
+        * @return Returns the weekday.
+        */
+       public int getWeekday() {
+               return weekday;
+       }
+       /**
+        * @param weekday The weekday to set.
+        */
+       public void setWeekday(int weekday) {
+               this.weekday = weekday;
+       }
+       /**
+        * @return Returns the special.
+        */
+       public boolean getSpecial() {
+               if (special==0) 
+                       return false;
+               else
+                       return true;
+       }
+       /**
+        * @param special The special to set.
+        */
+       public void setSpecial(boolean special) {
+               if (special==true)
+                       this.special = 1;
+               else 
+                       this.special = 0;
+       }
+}