1

When I send a message to the server, it retrieves it 100% of the time, but my client only displays every other message. It really makes no sense to me.. I used to use JTextAreas, but I decided to switch to JTextPanes, and yeah, not going so well.

In my ClientFrame.java, I have displayMessage(String message), which is being called in my Client's run(). Since I've had problems before with not posting enough of my code, I'ma post EVERYTHING i have.. Main classes used are ClientFrame, Client, Server (for the sendGlobalMesssage(String message), and User for my server-thread.

Client.java

import java.io.IOException;

import javax.swing.text.BadLocationException;


public class Client extends Stream implements Runnable {
    public boolean running = false;
    private Thread clientThread;

    ClientFrame frame;
    public Client() {
        super("localhost", 43594);

        frame = new ClientFrame(500, 500);
        start();
    }

    public synchronized void start() {
        if(running) return;
        running = true;

        clientThread = new Thread(this);
        clientThread.start();
    }
    public synchronized void stop() {
        if(!running) return;
        running = false;

        clientThread.interrupt();
        try {
            clientThread.join();
        } catch (InterruptedException e) {e.printStackTrace();}
    }

    public static void sendMessage(String message) {
        try{
            out.writeObject(message);
            out.flush();
        }catch(IOException e) { }
    }

    public void run() {
        try{
        setupStream();

        while(running) {
            if(recieveData() != null) {
                frame.displayMessage(recieveData());
            }
        }
        }catch(IOException | BadLocationException | ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            try{
            out.close();
            in.close();
            socket.close();
            clientThread.join();
            }catch(IOException | InterruptedException e) { e.printStackTrace(); }
        }
    }
    public static void main(String[] args) {
        new Client();
    }
}

Client's Stream.java

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;


public class Stream {

    Socket socket;
    static ObjectOutputStream out;
    static ObjectInputStream in;
    String data;

    public Stream(String host, int port) {
        try {
            socket = new Socket(host, port);
        } catch (IOException e) { 
            e.printStackTrace();
        }
    }

    protected void setupStream() throws IOException {
        out = new ObjectOutputStream(socket.getOutputStream());
        out.flush();
        in = new ObjectInputStream(socket.getInputStream());
    }

    public synchronized String recieveData() throws IOException, ClassNotFoundException {
        return (String) in.readObject();
    }

}

ClientFrame.java

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;


public class ClientFrame extends Frame {

    private JPanel mainpanel;

    public ClientFrame(int width, int height) {
        super(width, height);

        mainpanel = new JPanel();
        addContentToPanel();
        setListeners();

        add(mainpanel);
        pack();
        setLocationRelativeTo(null);
        setVisible(true);
    }

    private void addContentToPanel() {
        mainpanel.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();

        setGbc(0, 0, width, height-460, gbc);
        mainpanel.add(topPanel(), gbc);
        setGbc(0, 1, 0, 0, gbc);
        mainpanel.add(chatPanel(), gbc);

    }


    JTextField userfield;
    JPasswordField passfield;
    JPanel topPanel() {
        JPanel panel = new JPanel();
            panel.setLayout(null);

            JLabel label = new JLabel("Username: ");
                label.setBounds(15, 1, 65, 30);
            userfield = new JTextField();
                userfield.setBounds(85, 7, 160, 20);
                panel.add(label);
                panel.add(userfield);

            label = new JLabel("Password: ");
                label.setBounds(255, 1, 65, 30);
            passfield = new JPasswordField();
                passfield.setBounds(325, 7, 160, 20);
                panel.add(label);
                panel.add(passfield);

        return panel;
    }


    JTextPane toptextpane;
    JTextPane bottomtextpane;
    JScrollPane topscrollpane;
    JScrollPane bottomscrollpane;
    JPanel chatPanel() {
        JPanel chatpanel = new JPanel();
            chatpanel.setPreferredSize(new Dimension(width, height - 40));
            chatpanel.setLayout(null);

            toptextpane = new JTextPane();
                toptextpane.setEditable(false);
            topscrollpane = new JScrollPane(toptextpane);
                topscrollpane.setBounds(5, 0, width - 10, height - 200);
                chatpanel.add(topscrollpane);

            bottomtextpane = new JTextPane();
            bottomscrollpane = new JScrollPane(bottomtextpane);
                bottomscrollpane.setBounds(5, 305, width - 10, height - 350);
                chatpanel.add(bottomscrollpane);


        return chatpanel;   
    }

    Document doc;
    public void displayMessage(String message) throws BadLocationException {
        Document doc = toptextpane.getDocument();
        try
        {
            System.out.println("works");
            doc.insertString(0, message +"\n", null );
        }
        catch(Exception e) { System.out.println(e); }

    }

    private void setListeners() {
        bottomtextpane.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                if(e.getKeyCode() == KeyEvent.VK_ENTER) {
                    Client.sendMessage(bottomtextpane.getText());
                    bottomtextpane.setText("");
                    e.consume();
                }
            }
        });
    }
}

Server.java

package Server;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;

public class Server {
    public static int maxConnections = 10;

    private ServerSocket serverSocket;

    static User[] user = new User[maxConnections];

    public static void sendGlobalMessage(String message) {
        for(int i = 0; i < 9; i++) {
            if(user[i] != null) {
                try {
                    user[i].out.writeObject(message);
                    user[i].out.flush();
                    System.out.println(message);
                }catch(IOException e) { }
            }
        }
    }

    public static HashMap<String, User> users = new HashMap<String, User>();


    Thread acceptConnections = new Thread(new Runnable() {
        public void run() {
            while(User.users <= maxConnections) {
                try{
                    System.out.println("[System] Waiting for connections.. ("+User.users+" users online)");

                    for(int i = 0; i < 9; i++) {
                        if(user[i] == null) {
                            user[i] = new User(serverSocket.accept());
                            user[i].ID = i;
                            System.out.println("--- Someone has joined! ---");
                            user[i].start();
                            User.users++;
                            break ;
                        } 
                    }
                }catch(IOException e) { }
            }
        }
    });
    Thread scannerThread;
    Scanner scanner;

    public Server() { 
        scannerThread = new Thread(new Runnable() {
            public void run() {
                scanner = new Scanner(System.in);
                String input;
                while((input = scanner.nextLine()) != null) {
                    switch(input.toLowerCase()) {
                    case "checkuser":

                    }
                }
            }
        });

        try{
            scannerThread.start();
            serverSocket = new ServerSocket(43594);
        }catch(IOException e) { }

    }

    public static void main(String args[]) throws Exception {
        Server server = new Server();

        server.acceptConnections.start();
    }
}

User.java

package Server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;

public class User extends Thread {
    public static int users = 0;
    public int ID;
    public String username;
    boolean online = false;

    public static ArrayList<String> usernames = new ArrayList<String>();

    Socket socket;

    ObjectOutputStream out;
    ObjectInputStream in;
    String input;

    public User(Socket socket) {
        this.socket = socket;

    }

    public String decode(String input) {
        String[] split = input.split(" ");

        if(input.startsWith("::")) {
            try {
                switch(split[0].substring(2, split[0].length()).toLowerCase()) {
                case "setname": 
                case "changename":
                case "newname":
                    if(usernames.contains(split[1].toLowerCase())) {
                        out.writeUTF("This name is already taken! Please choose a different one.");
                        out.flush();
                        return null;
                    }
                    if(username == null) {
                        username = split[1].substring(0, 1).toUpperCase() + split[1].substring(1, split[1].length());
                        Server.users.put(split[1].toLowerCase(), Server.user[ID]);
                        usernames.add(split[1].toLowerCase());
                    } else {
                        usernames.remove(username.toLowerCase());
                        username = split[1].substring(0, 1).toUpperCase() + split[1].substring(1, split[1].length());
                        usernames.add(split[1].toLowerCase());
                    }
                        return null;
                case "rank+":
                    return null;
                case "[sm]=":
                    return null;
                }
            }catch(IOException e) { }
        }
        return input;
    }

    String timeStamp;
    public void run() {
        try {

            out = new ObjectOutputStream(socket.getOutputStream());
            out.flush();
            in = new ObjectInputStream(socket.getInputStream());

            while((input = (String) in.readObject()) != null) {
                input = decode(input);

                if(input != null) {
                    if(username != null) {
                        timeStamp = new SimpleDateFormat("[h:mm:ss] ").format(Calendar.getInstance().getTime());
                        Server.sendGlobalMessage(timeStamp + username +": "+input);
                    } else {
                        timeStamp = new SimpleDateFormat("[h:mm:ss] ").format(Calendar.getInstance().getTime());
                        Server.sendGlobalMessage(timeStamp + "Guest "+ID+": "+input);
                    }
                }
            }

        }catch(IOException | ClassNotFoundException e) { try{
            out.close();
            in.close();
            socket.close();
        } catch(IOException e2) { e.printStackTrace(); } } finally { 

        }

    }

}

Also, something that would be MUCH appreciated (if you can), show me a more proper way to close my streams, both server AND client-sided. Thanks :)

4

0 回答 0