package client; import java.awt.EventQueue; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; import utils.Message; import javax.swing.JTextField; import javax.swing.JButton; import javax.swing.JTextArea; import java.awt.Color; import java.awt.event.ActionListener; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.net.SocketException; import java.util.Scanner; import java.awt.event.ActionEvent; /** * Hauptklasse des Clients * * @version 0.1.3 * @author berdan */ public class Client1 extends JFrame { /** * Hier werden Objekte und Variablen deklariert, damit diese in allen * Methoden genutzt werden können. */ private static JPanel contentPane; JTextField txtMessage; private static JTextField txtUsername; public static String currentText = " "; public static int i = 0; public static Object tosend = new Message("Leer", "Leer"); public static Client1 t1; public static Socket socket; public static ObjectInputStream obinstr; public static ObjectOutputStream oboust; public static boolean verbunden = false; public static JTextArea textArea = new JTextArea(); public static int anzahlVersuche = 0; //Ist gleich die AN public static int anzahlRekursionen = 0; public static Message temp = new Message("leer", "leer"); /** * In der main Methode wird das GUI erstellt und die start() Methode * aufgerufen. * * @param args * @throws InterruptedException */ public static void main(String[] args) throws InterruptedException { t1 = new Client1(); EventQueue.invokeLater(new Runnable() { public void run() { try { Client1 frame = new Client1(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); try { start(); } catch (ClassNotFoundException | IOException e) { e.printStackTrace(); } } /** * In der Methode Client1() wird das GUI und die Befehle die durch einen * Click des Button's ausgelöst werden festgelegt (Konstruktur) */ public Client1() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setBounds(100, 100, 450, 300); contentPane = new JPanel(); contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); setContentPane(contentPane); contentPane.setLayout(null); txtMessage = new JTextField(); txtMessage.setText("Message"); txtMessage.setBounds(20, 230, 218, 20); contentPane.add(txtMessage); txtMessage.setColumns(10); txtUsername = new JTextField(); txtUsername.setText("Username"); txtUsername.setBounds(20, 11, 86, 20); contentPane.add(txtUsername); txtUsername.setColumns(10); /** * Der Button "Send" nimmt die aktuelle Nachricht, welche im Textfeld * "message" geschrieben wurde und schreibt diese als ein Message-Objekt * in den Output-Stream an den Server, falls die Socket bereits * verbunden ist. * * Falls die Nachricht "exit" sein sollte, wird die GUI beendet. */ JButton btnSend = new JButton("Send"); btnSend.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { if (verbunden) { String themessage = txtMessage.getText(); String theusername = txtUsername.getText(); tosend = new Message(theusername, themessage); i = 1; temp = new Message(theusername, themessage); System.out.println("Button pressed"); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); try { oboust.writeObject(tosend); oboust.flush(); } catch (IOException e) { e.printStackTrace(); } catch (Exception k) { print("KEINE VERBINDUNG"); } if (temp.getMessage().equals("exit")) { System.exit(0); } txtMessage.setText(""); } } }); btnSend.setBounds(264, 229, 79, 23); contentPane.add(btnSend); /** * Hier wird die textArea, auf welcher der Text ausgegeben wird * initialisiert */ textArea = new JTextArea(currentText); textArea.setLineWrap(true); textArea.setForeground(Color.BLACK); textArea.setBackground(Color.LIGHT_GRAY); textArea.setBounds(20, 42, 323, 176); contentPane.add(textArea); /** * Der Start Button sorgt sorgt dafür, dass der Username festgesetzt * wird, wodurch er nicht veränderlich ist. Außerdem wird die globale * Variabel j von 0 auf 1 gestzt, wodurch die start-Methode weiß, dass * sie eine Verbindung aufbauen soll. */ JButton btnStart = new JButton("Start"); btnStart.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { txtUsername.setEditable(false); txtUsername.setEnabled(false); verbunden = true; } }); btnStart.setBounds(116, 10, 89, 23); contentPane.add(btnStart); } /** * In der Print-Methode wird der neue Text (also eine neue Nachricht) auf * die textArea abgebildet. * * @param neuerText */ public static void print(String neuerText) { currentText = neuerText + "\n" + currentText; textArea.setText(currentText); } /** * Die start-Methode wartet, bis die Variable verbunden durch Klicken des * Start Buttons auf true gesetzt wird, erst dann beginnt die eigentliche * Methode. * * Es wird dann eine Verbindung zum Socket über den Port 1236 aufgebaut. * Sollte dies nicht Möglich sein, wird die Fehlermeldung in der GUI * ausgegeben, sodass der Nutzer weiß, dass keine Vebrindung möglich ist. * * Es wird im Sekundentakt nach einer neuen Verbindung gesucht. * * @throws IOException * @throws ClassNotFoundException * @throws InterruptedException */ public static void start() throws IOException, ClassNotFoundException, InterruptedException { while (!verbunden) { Thread.sleep(100); } txtUsername.setEnabled(false); Scanner scan = new Scanner(System.in); try { socket = new Socket("localhost", 1236); oboust = new ObjectOutputStream(socket.getOutputStream()); obinstr = new ObjectInputStream(socket.getInputStream()); print("VERBINDUNG HERGESTELLT"); } catch (Exception KeineSocket) { print("SERVER ANTWORTET NICHT"); try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } anzahlRekursionen++; if (anzahlRekursionen == 10) { print("KEINE ANTWORT, CLIENT WIRD BEENDET"); Thread.sleep(10000); System.exit(0); } start(); System.exit(0); } Object erhalten = null; Message message = new Message("leer", "leer"); /** * Die While Schleife ist der Listener, dieser wartet auf Nachrichten * aus dem Server und gibt diese dann aus. * * Im Falle eines Verindungsabbruches versucht er es 5 mal im Abstand * von 2 Sekunden nochmal eine Nachricht zu senden und ruft dann wieder * die start() Methode auf. wodurch die Verbindung nochmal neu * hergestellt wird. * * Die While-Schleife wird abgebrochen, sobald die Nachricht, welche der * Benutzer über das GUI sendet "exit" lautet. * */ while (!temp.getMessage().equals("exit")) { try { //System.out.println("hile4"); System.out.println("Nachricht erhalten"); erhalten = obinstr.readObject(); //Bleibt hier stehen, bis ein neues Object reinkommt message = (Message) erhalten; System.out.println("[" + message.getUsername() + "] " + message.getMessage()); String Ausgeben = message.getTime() + " [" + message.getUsername() + "] " + message.getMessage(); print(Ausgeben); //System.out.println("[CLIENT] NACHRICHT ERHALTEN"); oboust.flush(); } catch (SocketException h) { System.out.println(h); print("VERBINDUNGSABBRUCH"); anzahlVersuche++; Thread.sleep(2000); if (anzahlVersuche == 5) { anzahlVersuche = 0; anzahlRekursionen++; if (anzahlRekursionen == 10) { print("KEINE ANTWORT, CLIENT WIRD BEENDET"); Thread.sleep(10000); System.exit(0); } start(); System.exit(0); } } catch (Exception f) { Thread.sleep(1000); } } /** * Nach dem Abbruch der While Schleife, was nur bei der Nachricht exit * passiert, schließt der Client den ObjectOutputstream, * Objectinputstream und den Socket und beendet dann das Programm */ oboust.close(); obinstr.close(); socket.close(); System.exit(0); } }