Probleme mit awt.List in Chatprogramm

Status
Nicht offen für weitere Antworten.

badmaxx

Mitglied
ich konnt mich nicht entscheiden ob ichs hier oder in Netzwerkprogrammierung posten soll ich hoff mal es passt hier.

Ich hab 2 probleme mit der List die die Username der User die sich im Chat befinden anzeigen soll.
1. Wenn sich ein Client verbindet ist alles in Ordnung, kommt allerdings ein weiterer in den Chat "klaut" dieser sich die List mit den Usernamen, d.h. es kann immer nur der als letztes connectete Client die Liste sehen.
2. wenn der User seinen Namen ändert werden auch alle andere Namen geändert.
Beispiel: es sind User 1 und User 2 im Chat, User 2 ändert seinen Namen auf 3 und 1 heisst plötzlich auch 3.

Hier der meiner Meinung nach relevante Quelltext

Java:
import java.net.*;
import java.io.*;
import java.util.*;
import java.awt.*;
import java.awt.List;
import javax.swing.*;


public class chatserver implements Runnable
{
  public final static int PORT = 9996; //used Port

  public ServerSocket listen;

  private Vector connections;
  private static List users = new List();   //List with members of the chat
  Thread connect;


  public chatserver()
  {
    try
    {
      listen = new ServerSocket(PORT);
    }
    catch (IOException e)
    {
      System.err.println("Fehler beim Erzeugen der Sockets:" + e);
      System.exit(1);
    }


    connections = new Vector();
    connect = new Thread(this);
    connect.start();
    System.out.println("Server erfolgreich gestartet");
  }


  public void run()
  {
    try
    {
      while (true)
      {
        try
        {
          Socket client = listen.accept();

          connection c = new connection(this, client);
          connections.addElement(c);

        }
        catch (SocketException e)
        {
          System.out.println(e.toString());
          System.out.println("test");
        }


      }
    }
    catch (IOException e)
    {
      System.err.println("Fehler beim Warten auf Verbindungen:" + e);
      System.exit(1);
    }


  }

  public static void main(String[] args)
  {
    new chatserver();
  }

  public void msgToAll(String strMessage)
  {
    int i;
    connection client;

    for (i = 0; i < connections.size(); i++)
    {
      client = (connection) connections.elementAt(i);
      client.out.println(strMessage);
    }
  }

  public static List getUsers()
  {
    return users;
  }

  public static void removeUsers(String name)
  {
    users.remove(name);
  }

  public static void setUsers(String name)
  {
    users.add(name);
  }
}

Java:
import java.applet.*;
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;

/**
 * Created by IntelliJ IDEA.
 * User: mwi
 * Date: 26.05.2009
 * Time: 12:55:55
 * Todo Benutzeranzeige
 * todo spammschutz
 * todo adminbereich
 */
public class chatclient extends Applet implements Runnable
{
  public final static int PORT = 9996; //Verwendeter Port
  Socket socket;
  BufferedReader inputStream;
  PrintStream outputStram;
  TextField inputField;
  JTabbedPane pane;
  Label useronline;
  JPanel left;
  JPanel bottom;
  JButton send;
  JTextArea outputArea;
  JScrollPane spMsg;
  JScrollPane spUserlist;
  List users;
  Thread thread;
  String username = "tesdt";


  public void init()
  {

    inputField = new TextField();
    outputArea = new JTextArea();
    spMsg = new JScrollPane(outputArea);
    spUserlist = new JScrollPane(users);
    pane = new JTabbedPane();
    left = new JPanel();
    bottom = new JPanel();
    send = new JButton();
    send.setText("Senden");


    useronline = new Label();
    useronline.setText("User online");
    outputArea.setLayout(new BorderLayout());
    outputArea.setFont(new Font("Dialog", Font.PLAIN, 12));
    outputArea.setLineWrap(true);
    outputArea.setWrapStyleWord(true);
    spMsg.setViewportView(outputArea);
    outputArea.setCaretPosition(outputArea.getText().length());
    spUserlist.setViewportView(users);





    this.setLayout(new BorderLayout());
    left.setLayout(new BorderLayout());
    bottom.setLayout(new BorderLayout());

    this.add("West", left);
    this.add("Center", pane);
    this.add("South", bottom);


    pane.add(spMsg);
    pane.setTitleAt(0, "Hauptchat");

    left.add("North", useronline);
    useronline.setAlignment(Label.CENTER);
    chatserver.setUsers(username);
    users = chatserver.getUsers();
    left.setSize(500, 40);
    left.add("Center", users);

    bottom.add("Center", inputField);
    bottom.add("East", send);

    this.setBackground(Color.LIGHT_GRAY);
    this.setForeground(Color.black);
    inputField.setBackground(Color.white);
    outputArea.setBackground(Color.white);

    send.addMouseListener(new MouseAdapter()
    {
      public void mouseClicked(MouseEvent e)
      {
        String line = inputField.getText();

        if (line != null)
        {
          outputStram.println(line);
          inputField.setText("");
        }
      }
    });

     
  }


  public void start()
  {
    try
    {
      socket = new Socket(this.getCodeBase().getHost(), PORT);
      inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      outputStram = new PrintStream(socket.getOutputStream());

    }
    catch (IOException e)
    {
      this.showStatus(e.toString());
      say("Verbinung zum Server fehlgeschlagen");
      System.exit(1);
    }

    say("Verbindung zum Server hergestellt");

    if (thread == null)
    {
      thread = new Thread(this);
      thread.setPriority(Thread.MIN_PRIORITY);
      thread.start();


    }
  }

  public void stop()
  {
    try
    {
      chatserver.removeUsers(username);
      socket.close();
    }
    catch (IOException e)
    {
      this.showStatus(e.toString());
    }


    if ((thread != null) && thread.isAlive())
    {
      thread.interrupt();
      thread = null;
    }
  }

  public void run()
  {
    String line;

    try
    {
      while (true)
      {
        outputArea.setCaretPosition(outputArea.getText().length());
        users = chatserver.getUsers();
        line = inputStream.readLine();
        if (line != null)
        {
          if (line.startsWith("/nick"))
          {
            String newname = new String(line.substring(6));
            if (newname.length() < 20)
            {
              users.remove(username);
              chatserver.setUsers(newname);
              username = newname;
            }
            else
            {
              say("Username zu lang kann nicht geändert werden");
            }
          }
          else if(line.startsWith("/quit"))
          {
            chatserver.removeUsers(username);
            socket.close();
          }
          else
          {
            outputArea.append(username + ": " + line + '\n');
          }
        }
      }
    }
    catch (IOException e)
    {
      say("Verbindung zum Server abgebrochen");
    }
  }


  public boolean action(Event e, Object what)
  {
    if (e.target == inputField)
    {
      String strInput = e.arg.toString();
      outputStram.println(strInput);
      inputField.setText("");
      return true;
    }
    return false;
  }

  public void say(String msg)
  {
    outputArea.append("****" + msg + "****\n");
  }


}


Steh grad wirklich aufm schlauch und versuch das Problem schon seit ca 4 Stunden zu lösen.

Hoff jemand von euch hat eine Idee.

Danke im Voraus!
Gruß Maxi
 
Zuletzt bearbeitet:
Hi,

in deinem Quellcode ist nirgends ein Objekt der Klasse JList drin. Hast du da vll. doch etwas vergessen?

EDIT: Noch etwas fällt mir da auf. Dein Chat-Server hat java.util.*, java.awt.* und java.awt.List importiert. "users" ist eine Instanz vom Typ "List"... Welche List denn genau? java.awt.List oder java.util.List?

Lg
sayang
 
Zuletzt bearbeitet:
Hmm... so ganz verstanden habe ich deine Vorgehensweise immernoch nicht.
Eine awt.List ist ein grafisches UI-Element. Nun frage ich mich, was dies im Server sucht, der doch offenbar nur auf Console arbeitet.
Außerdem. Wenn ein User seinen Namen ändert, tut er das ja in seinem Chat-Client. Dieser sollte dem Server dann mitteilen, dass sein Name nun anders lautet. Der Server wiederum sendet diese Änderung an alle verbundenen Clients, damit die das in ihrer GUI ändern können.
Davon finde ich allerdings nichts in deinem Code. Vielleicht hast du das ja rausgelassen...

Ich würde im Server die Liste der User mit java.util.List verarbeiten. Diese Liste wird vom Client geholt oder vom Server an die Clients verteilt wenn sich etwas daran ändert.
Der Client selbst nutzt die java.util.List um seine java.awt.List mit Elementen zu versorgen.

Ich glaube, dein Ansatz hier geht schon in die ganz falsche Richtung.

Lg
sayang
 
Ich hab deshalb eine awt.list gewählt da ich mir dann nur immer die liste vom server holen kann und diese einfach einbinden kann.

hier die zeilen die den namen ändern

Java:
if (line.startsWith("/nick"))
          {
            String newname = new String(line.substring(6));
            if (newname.length() < 20)
            {
              users.remove(username);
              chatserver.setUsers(newname);
              username = newname;
            }
            else
            {
              say("Username zu lang kann nicht geändert werden");
            }



Java:
public static List getUsers()
  {
    return users;
  }
 
  public static void removeUsers(String name)
  {
    users.remove(name);
  }
 
  public static void setUsers(String name)
  {
    users.add(name);
  }
 
Ich würde mal sagen Dein Konzept ist falsch. Dein Server sollte die Daten in einer logischen AufListung vom Typ Collection speichern.
Die java.awt.List ist eine graphische Komponente die eine Auflistung darstellen kann und hat damit nichts auf dem Server verloren. Aus diesem Grund wird die Liste auch nur auf dem letzten Client angezeigt, denn eine graphische Komponte kann nur einmal angezeigt werden. Deine Clients benötigen jeder ein java.awt.List-Objekt exklusiv für sich in dem Sie dann die Auflistung darstellen.

Übrigens man sollte entweder swing oder awt Komponenten verwenden. Mischen kann zu Darstellungsproblemen führen.
 
ok danke schonmal kannst du mir des mit der collection bissl genauer erklären hab bis jetz noch nie damit gearbeitet.
 
Was ich meine ist, dass Dein Server die Client-User in Form eines Feldes z.B. String[], Vectors, oder einer ArrayList speichern sollte. Und diese Liste sendet der Server nach jeder Aktualisierung an die Clients. Diese besitzen eine graphische Komponente z.B. JList zur Darstellung. Nach dem Empfang der aktualisierten Usernamen, fügt jeder Client dann diese Namen in seine JList ein.
Alternative könntest Du auch ein DefaultListModel auf dem Server halten und dieses dann nach dem Aktualisieren an die Clients schicken.
 
Mal 'ne Zwischenfrage:
Woher kommt in der Klasse chatclient (Klassennamen schreibt man im Übrigen gross) die Variable chatserver? Die ist weder deklariert noch initialisiert. Hast Du die Klasse mal kompliliert?
 
Java:
import java.applet.*;
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.*;

/**
 * Created by IntelliJ IDEA.
 * User: mwi
 * Date: 26.05.2009
 * Time: 12:55:55
 * Todo Benutzeranzeige
 * todo spammschutz
 * todo adminbereich
 */
public class Chatclient extends Applet implements Runnable
{
  public final static int PORT = 9996; //Verwendeter Port

  Socket socket;
  BufferedReader inputStream;
  PrintStream outputStram;
  TextField inputField;
  JTabbedPane pane;
  JLabel useronline;
  JPanel left;
  JPanel bottom;
  JButton send;
  JTextArea outputArea;
  JScrollPane spMsg;
  JScrollPane spUserlist;
  JList users = new JList();
  Thread thread;
  public static String username;


  public void init() throws SecurityException
  {

    inputField = new TextField();
    outputArea = new JTextArea();
    spMsg = new JScrollPane(outputArea);
    spUserlist = new JScrollPane(users);
    pane = new JTabbedPane();
    left = new JPanel();
    bottom = new JPanel();
    send = new JButton();
    send.setText("Senden");
    username = JOptionPane.showInputDialog(this, "Gib deinen Benutzernamen an");


    useronline = new JLabel();
    useronline.setText("User online");
    outputArea.setLayout(new BorderLayout());
    outputArea.setFont(new Font("Dialog", Font.PLAIN, 12));
    outputArea.setLineWrap(true);
    outputArea.setWrapStyleWord(true);
    spMsg.setViewportView(outputArea);
    outputArea.setCaretPosition(outputArea.getText().length());
    spUserlist.setViewportView(users);


    this.setLayout(new BorderLayout());
    left.setLayout(new BorderLayout());
    bottom.setLayout(new BorderLayout());

    this.add("West", left);
    this.add("Center", pane);
    this.add("South", bottom);


    pane.add(spMsg);
    pane.setTitleAt(0, "Hauptchat");

    left.add("North", useronline);
    useronline.setVerticalAlignment(SwingConstants.CENTER);
    Chatserver.setUsers(username);
    //users = new JList(Chatserver.getUsers().toArray());
    left.setSize(500, 40);
    left.add("Center", users);

    bottom.add("Center", inputField);
    bottom.add("East", send);

    this.setBackground(Color.LIGHT_GRAY);
    this.setForeground(Color.black);
    inputField.setBackground(Color.white);
    outputArea.setBackground(Color.white);
    inputField.requestFocus();

    send.addMouseListener(new MouseAdapter()
    {
      public void mouseClicked(MouseEvent e)
      {
        String line = inputField.getText();

        if (line != null)
        {
          outputStram.println(line);
          inputField.setText("");
        }
      }
    });


  }


  public void start()
  {
    try
    {
      socket = new Socket(this.getCodeBase().getHost(), PORT);
      inputStream = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      outputStram = new PrintStream(socket.getOutputStream());

    }
    catch (IOException e)
    {
      this.showStatus(e.toString());
      say("Verbinung zum Server fehlgeschlagen");
      System.exit(1);
    }

    say("Verbindung zum Server hergestellt");

    if (thread == null)
    {
      thread = new Thread(this);
      thread.setPriority(Thread.MIN_PRIORITY);
      thread.start();


    }
  }

  public void stop()
  {
    try
    {
      Chatserver.removeUsers(username);
      socket.close();
    }
    catch (IOException e)
    {
      this.showStatus(e.toString());
    }


    if ((thread != null) && thread.isAlive())
    {
      thread.interrupt();
      thread = null;
    }
  }

  public void run()
  {
    String line;

    try
    {
      while (true)
      {
        outputArea.setCaretPosition(outputArea.getText().length());

        line = inputStream.readLine();
        if (line != null)
        {
          if (line.startsWith("/nick"))
          {
            String newname = new String(line.substring(6));
            if (newname.length() < 20)
            {
              Chatserver.removeUsers(username);
              Chatserver.setUsers(newname);
              outputArea.setText(outputArea.getText().replace(username, newname));
              username = newname;
            }
            else
            {
              say("Username zu lang kann nicht geändert werden");
            }
          }
          else if (line.startsWith("/quit"))
          {
            Chatserver.removeUsers(username);
            socket.close();
          }
          else if (line.startsWith("/time"))
          {
            SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
            String time = "Es ist jetzt: " + sdf.format(new Date());
            say(time);
          }
          else
          {
            outputArea.append(username + ": " + line + '\n');
          }
        }
      }
    }
    catch (IOException e)
    {
      say("Verbindung zum Server abgebrochen");
    }
  }


  public boolean action(Event e, Object what)
  {
    if (e.target == inputField)
    {
      String strInput = e.arg.toString();
      outputStram.println(strInput);
      inputField.setText("");
      return true;
    }
    return false;
  }

  public void say(String msg)
  {
    outputArea.append("****" + msg + "****\n");

  }

  public static String getUsername()
  {
    return username;
  }
}

Java:
import java.net.*;
import java.io.*;
import java.util.*;


public class Chatserver implements Runnable
{
  public final static int PORT = 9996; //used Port

  public ServerSocket listen;

  private Vector connections;
  public static ArrayList users = new ArrayList(); // = new Collection();   //List with members of the chat
  Thread connect;


  public Chatserver()
  {
    try
    {
      listen = new ServerSocket(PORT);
    }
    catch (IOException e)
    {
      System.err.println("Fehler beim Erzeugen der Sockets:" + e);
      System.exit(1);
    }


    connections = new Vector();
    connect = new Thread(this);
    connect.start();
    System.out.println("Server erfolgreich gestartet");
  }


  public void run()
  {
    try
    {
      while (true)
      {
        try
        {
          Socket client = listen.accept();

          String username = Chatclient.getUsername();
          connection c = new connection(this, client);
          connections.addElement(c);
        
        }
        catch (SocketException e)
        {
          System.out.println(e.toString());
          System.out.println("test");
        }


      }
    }
    catch (IOException e)
    {
      System.err.println("Fehler beim Warten auf Verbindungen:" + e);
      System.exit(1);
    }


  }

  public static void main(String[] args)
  {
    new Chatserver();
  }

  public void msgToAll(String strMessage)
  {
    int i;
    connection client;

    for (i = 0; i < connections.size(); i++)
    {
      client = (connection) connections.elementAt(i);
      client.out.println(strMessage);
    }
  }

  public static ArrayList getUsers()
  {
    return users;
  }

  public static void removeUsers(String name)
  {
    users.remove(name);
  }

  public static void setUsers(String name)
  {
    users.add(name);
  }
}

so des sin jetz mal die zwei klassen so wie se im moment sin des heist da sin mit sicherhiet n paar fehler drin
 
Java:
public class Chatclient extends Applet implements Runnable {
...
      Chatserver.setUsers(username);
...
      Chatserver.removeUsers(username);
...
}
Ich bin jetzt auch nicht der Socket/ServerSocket Experte. Aber das wird Dir nichts nützen, da das Socket und der Server in einer unterschiedlichen VM laufen.
Das Socket kennt das Server-Objekt nicht. Die beiden können nur über die In- und Outputstreams kommunizieren.

Lass mich aber gerne eines besseren belehren.
 
stimmt daran hab ich gar nich gedacht!
mal schaun vllt schaut ja mal einer der netzwerkspezialisten im thread vorbei!
ich werd die tage mal bissl suchen aber jetz is dann (in na halben stunde) wochenende und da wird erstmal nix programmiert!
 
Hab hier mal schnell ein kurzes Bsp mit Server und Client die per Text kommunizieren zusammengefrikelt. Die Nutzerliste wird hier als Zeichenkette übergeben. Ist zwar nicht ganz sauber, verdeutlicht aber hoffentlich was ich meine...
Java:
import java.net.*;
import java.io.*;
import java.util.*;

public class DemoServer {
	private ArrayList outStreams;
	private ArrayList clientUsers;
	
	public DemoServer(){
		outStreams = new ArrayList();
		clientUsers = new ArrayList();
		try {
			ServerSocket serverSocket = new ServerSocket(5555);
			while (true) {
				Socket socket = serverSocket.accept();
				outStreams.add(new PrintWriter(socket.getOutputStream()));
				new Thread(new ClientHandler(socket)).start();
			}
		}
		catch (Exception exc) {exc.printStackTrace();}
	}
	
	private void send(String s) {
		for (int i=0; i<outStreams.size(); i++) {
			PrintWriter writer = (PrintWriter) outStreams.get(i);
			writer.println(s);
			writer.flush();
		}
	}
	
	private void addUser(String name) {
		this.clientUsers.add(name);
		StringBuffer text = new StringBuffer();
		text.append("<user>");
		
		for (int i=0; i<this.clientUsers.size(); i++) {
			text.append(this.clientUsers.get(i) +"\t");
		}
		this.send(text.toString());
	}
	
	private class ClientHandler implements Runnable {
		private BufferedReader reader;
		private String user = "unkown";
		
		public ClientHandler(Socket socket) {
			try {
				reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			}
			catch (Exception exc) {exc.printStackTrace();}
		}
		
		public void run() {
			String in;
			try {
				while ((in=reader.readLine())!=null)
					if (in.startsWith("<user>")) {
						user = in.substring(6);
						addUser(user);
					}
					else if (in.trim().length()>0)
						send(user + ": " + in);
			}
			catch (Exception exc) {exc.printStackTrace();}
		}
	}
	
	public static void main(String[] args) {
		new DemoServer();
	}
}
Java:
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;

import javax.swing.*;

public class DemoClient extends JFrame{
	private JTextField textField;
	private JTextArea textArea;
	private JScrollPane scrollPane;
	private DefaultListModel model;
	
	private Socket socket;
	private PrintWriter writer;
	private BufferedReader reader;
	
	public DemoClient() {
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setBounds(20, 20, 400, 200);
		this.getContentPane().add(textField = new JTextField(), BorderLayout.NORTH);
		this.getContentPane().add(scrollPane = new JScrollPane(textArea = new JTextArea(), 
				JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
				JScrollPane.HORIZONTAL_SCROLLBAR_NEVER)
				, BorderLayout.CENTER);
		this.getContentPane().add(new JList(model = new DefaultListModel()), BorderLayout.EAST);
		
		textArea.setEditable(false);
		textArea.setLineWrap(false);
		textArea.setWrapStyleWord(false);
		textField.addKeyListener(new KeyAdapter(){
			public void keyPressed(KeyEvent evt) {
				if (evt.getKeyCode()==KeyEvent.VK_ENTER) {
					send(textField.getText());
					textField.setText("");
				}
			}
		});
		try {
			socket = new Socket("127.0.0.1", 5555);
			this.setTitle("Test Client " + socket.getLocalPort());
			writer = new PrintWriter(socket.getOutputStream());
			reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			this.send("<user>"+ this.getTitle());
			Thread t = new Thread(new StreamReader());
			t.start();
		}
		catch (Exception exc) {exc.printStackTrace();}
	}
	
	private void send(String s) {
		if (s.trim().length()>0) {
			writer.println(s);
			writer.flush();
		}
	}
	
	public void refreshList(String[] list) {
		model.clear();
		for (int i=0; i<list.length; i++) {
			model.addElement(list[i]);
		}
	}
	
	
	private class StreamReader implements Runnable {
		String in;
		
		public void run() {
			try {
				while ((in=reader.readLine())!=null) {
					if (in.startsWith("<user>")) {
						refreshList(in.substring(6).split("\t"));
					}
					else {
						textArea.append(in +"\n");
						scrollPane.getVerticalScrollBar().setValue(textArea.getHeight());
					}
				}
			}
			catch (Exception exc) {exc.printStackTrace();}
		}
	}
	
	public static void main(String[] args) {
		new DemoClient().setVisible(true);
	}
}
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben