带有保存日志的ServerGUI - JAVA

时间:2015-03-12 21:24:58

标签: java swing logging client server

所以我试图做的是带有客户端的服务器。服务器启动服务器的位置,客户端打开聊天室,在那里他可以写任何他想要的东西。

所以我有两个问题,我无法让它发挥作用。

  1. 第一个问题是我无法将其自动保存为.txt。我总是要在最后写.txt来保存
  2. 当我将其保存为.txt时。它将所有内容保存在一行中。所以看起来不太好看。
  3. The problem

    我希望它如何 How I want it to be.

    是的。我会尽力帮助让它按照我的意愿运作。

    问候

    Thrillofit

    CODE

    ServerGUI

        package Server;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.io.*;
    
    /*
     * The server as a GUI
     */
    public class ServerGUI extends JFrame implements ActionListener, WindowListener {
    
        private static final long serialVersionUID = 1L;
        // the stop and start buttons
        private JButton stopStart, saveLog;
        // JTextArea for the chat room and the events
        private JTextArea chat;
        // private JTextArea event;
        // The port number
        private JTextField tfPortNumber;
        // my server
        private Server server;
    
        // server constructor that receive the port to listen to for connection as
        // parameter
        ServerGUI(int port) {
            super("Chat Server");
            server = null;
            // in the NorthPanel the PortNumber the Start and Stop buttons
            JPanel north = new JPanel();
            north.add(new JLabel("Port number: "));
            tfPortNumber = new JTextField("" + port);
            north.add(tfPortNumber);
            // to stop or start the server, we start with "Start"
            stopStart = new JButton("Start");
            stopStart.addActionListener(this);
            saveLog = new JButton("Save log");
            saveLog.addActionListener(this);
            north.add(stopStart);
            north.add(saveLog);
            add(north, BorderLayout.NORTH);
            // the event and chat room
            JPanel center = new JPanel(new GridLayout());
            chat = new JTextArea(120, 20);
            chat.setEditable(false);
            chat.setWrapStyleWord(true);
            chat.setLineWrap(true);
            appendRoom(null, "Chat room and Events log for server.\n");
            center.add(new JScrollPane(chat));
            // event = new JTextArea(80,80);
            // event.setEditable(false);
            // appendEvent("Events log.\n");
            // center.add(new JScrollPane(event));
            add(center);
            // need to be informed when the user click the close button on the frame
            addWindowListener(this);
            setSize(450, 600);
            setVisible(true);
        }
    
        public void writeLog() throws IOException {
            String saveText = chat.getText();   
            JFileChooser chooser = new JFileChooser();
    //      chooser.setCurrentDirectory(new File("./"));
            int actionDialog = chooser.showSaveDialog(this);
            if (actionDialog == JFileChooser.APPROVE_OPTION) {
                File fileName = new File(chooser.getSelectedFile() + "");
                if (fileName == null)
                    return;
                if (fileName.exists()) {
                    actionDialog = JOptionPane.showConfirmDialog(this,
                            "Replace existing file?");
                    if (actionDialog == JOptionPane.NO_OPTION)
                        return;
                }
                try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(
                        new FileOutputStream(fileName), "ISO-8859-1"))) {
                    bw.write(saveText);
    //              bw.newLine();
                    bw.flush(); 
                }
            }
        }
    
    
        // append message to the two JTextArea
        // position at the end
        void appendRoom(String chatStr, String eventStr) {
            chat.append(chatStr);
            chat.append(eventStr);
    //      chat.setCaretPosition(chat.getText().length() - 1);
        }
    
        // void appendEvent(String str) {
        // event.append(str);
        // event.setCaretPosition(chat.getText().length() - 1);
        //
        // }
    
        // start or stop where clicked
        public void actionPerformed(ActionEvent e) {
            // if running we have to stop
            if (e.getSource() == saveLog) {
                try {
                    writeLog();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            } else if (e.getSource() == stopStart) {
                if (server != null) {
                    server.stop();
                    server = null;
                    tfPortNumber.setEditable(true);
                    stopStart.setText("Start");
                    return;
                }
                // OK start the server
                int port;
                try {
                    port = Integer.parseInt(tfPortNumber.getText().trim());
                } catch (Exception er) {
                    appendRoom(null, "Invalid port number");
                    return;
                }
                // ceate a new Server
                server = new Server(port, this);
                // and start it as a thread
                new ServerRunning().start();
                stopStart.setText("Stop");
                tfPortNumber.setEditable(false);
            }
        }
        /*
         * A thread to run the Server
         */
        class ServerRunning extends Thread {
            public void run() {
                server.start(); // should execute until if fails
                // the server failed
                stopStart.setText("Start");
                tfPortNumber.setEditable(true);
                appendRoom(null, "Server closed\n");
                server = null;
            }
        }
    
        // entry point to start the Server
        public static void main(String[] arg) {
            // start server default port 1500
            new ServerGUI(1500);
        }
    
        /*
         * If the user click the X button to close the application I need to close
         * the connection with the server to free the port
         */
        public void windowClosing(WindowEvent e) {
            // if my Server exist
            if (server != null) {
                try {
                    server.stop(); // ask the server to close the conection
                } catch (Exception eClose) {
                }
                server = null;
            }
            // dispose the frame
            dispose();
            System.exit(0);
        }
    
        // I can ignore the other WindowListener method
        public void windowClosed(WindowEvent e) {
        }
    
        public void windowOpened(WindowEvent e) {
        }
    
        public void windowIconified(WindowEvent e) {
        }
    
        public void windowDeiconified(WindowEvent e) {
        }
    
        public void windowActivated(WindowEvent e) {
        }
    
        public void windowDeactivated(WindowEvent e) {
        }
    
    //  /*
    //   * A thread to run the Server
    //   */
    //  class ServerRunning extends Thread {
    //      public void run() {
    //          server.start(); // should execute until if fails
    //          // the server failed
    //          stopStart.setText("Start");
    //          tfPortNumber.setEditable(true);
    //          appendRoom(null, "Server closed\n");
    //          server = null;
    //      }
    //  }
    }
    

    我认为它是唯一需要此代码的代码。如果没有,请告诉我。

    更新1:

    ClientGUI.java

     package Server;
    import javax.swing.*;
    
    
    /*
     * The Client with its GUI
     */
    public class ClientGUI extends JFrame implements ActionListener {
    
        private static final long serialVersionUID = 1L;
    
        private JLabel lblusername;
    
        private JTextField textfieldusername, textfieldserver, textfieldportnumber;
    
        private JButton btnlogin, btnlogout, btnonline;
    
        private JTextArea textareamessage;
    
        private boolean connected;
    
        private Client client;
    
        private int defaultPort;
        private String defaultHost;
    
    
        ClientGUI(String host, int port) {
    
            super("Chat Client");
            defaultPort = port;
            defaultHost = host;
    
    
            JPanel northPanel = new JPanel(new GridLayout(2,2));
            JPanel serverAndPort = new JPanel(new GridLayout(1,2, 2, 2));
            JLabel lblserveraddress = new JLabel("Server Address:  ");
            JLabel lblchat = new JLabel("                #BallIsLife");
            JLabel lblportnumber = new JLabel("Port Number:  ");
    
            textfieldserver = new JTextField(host);
            textfieldserver.setHorizontalAlignment(SwingConstants.LEFT);
            textfieldserver.setFont(new Font("Tahoma", Font.PLAIN, 20));
            textfieldportnumber = new JTextField("" + port);
            textfieldportnumber.setFont(new Font("Tahoma", Font.PLAIN, 20));
            textfieldportnumber.setHorizontalAlignment(SwingConstants.LEFT);
    
            lblserveraddress.setFont(new Font("Tahoma", Font.PLAIN, 19));
            serverAndPort.add(lblserveraddress);
            serverAndPort.add(textfieldserver);
            serverAndPort.add(lblchat);
            serverAndPort.add(lblportnumber);
            serverAndPort.add(textfieldportnumber);
            lblchat.setForeground(Color.RED);
            lblportnumber.setFont(new Font("Tahoma", Font.PLAIN, 19));
            northPanel.add(serverAndPort);
            getContentPane().add(northPanel, BorderLayout.NORTH);
    
            JPanel panelbtn = new JPanel();
            northPanel.add(panelbtn);
    
    
            btnlogin = new JButton("Login");
            panelbtn.add(btnlogin);
            btnlogin.setFont(new Font("Tahoma", Font.PLAIN, 17));
            btnlogin.addActionListener(this);
    
            btnonline = new JButton("Online");
            panelbtn.add(btnonline);
            btnonline.setFont(new Font("Tahoma", Font.PLAIN, 17));
    
            btnonline.addActionListener(this);
            btnonline.setEnabled(false);        
    
            btnlogout = new JButton("Logout");
            panelbtn.add(btnlogout);
            btnlogout.setFont(new Font("Tahoma", Font.PLAIN, 17));
            btnlogout.addActionListener(this);
            btnlogout.setEnabled(false);        
    
            JButton btnPicture = new JButton("Picture");
            btnPicture.setFont(new Font("Tahoma", Font.PLAIN, 17));
            btnPicture.setEnabled(false);
            panelbtn.add(btnPicture);
    
    
            textareamessage = new JTextArea("Welcome to the #BallIsLife Chat room.\n");
            textareamessage.setFont(new Font("Monospaced", Font.PLAIN, 15));
    
            textareamessage.setLineWrap(true);
            textareamessage.setEditable(false);
    
            JPanel centerPanel = new JPanel(new GridLayout(1,1));
            JScrollPane scrollPane = new JScrollPane(textareamessage);
            centerPanel.add(scrollPane);
            getContentPane().add(centerPanel, BorderLayout.CENTER);
    
    
            JPanel southPanel = new JPanel();
            getContentPane().add(southPanel, BorderLayout.SOUTH);
    
            lblusername = new JLabel("Enter your username", SwingConstants.CENTER);
            lblusername.setFont(new Font("Tahoma", Font.PLAIN, 15));
            southPanel.add(lblusername);
    
            textfieldusername = new JTextField("Write your username here.");
            textfieldusername.setFont(new Font("Tahoma", Font.PLAIN, 14));
            textfieldusername.setColumns(50);
    
            southPanel.add(textfieldusername);
    
    
            setDefaultCloseOperation(EXIT_ON_CLOSE);
            setSize(823, 665);
            setVisible(true);
    
        }
    
    //Logiken
    
        void append(String str) {
            textareamessage.append(str);
            textareamessage.setCaretPosition(textareamessage.getText().length() - 1);
        }
    
    
        void connectionFailed() {
            btnlogin.setEnabled(true);
            btnlogout.setEnabled(false);
            btnonline.setEnabled(false);
            lblusername.setText("Enter your username");
            textfieldusername.setText("Write your username here");
    
            textfieldportnumber.setText("" + defaultPort);
            textfieldserver.setText(defaultHost);
    
            textfieldserver.setEditable(false);
            textfieldportnumber.setEditable(false);
    
            textfieldusername.removeActionListener(this);
            connected = false;
        }
    
        //
    
        public void actionPerformed(ActionEvent e) {
            Object button = e.getSource();
    
            if(button == btnlogout) {
                client.sendMessage(new ChatMessage(ChatMessage.LOGOUT, "")); //Ändra till Chatmessage klass
                btnlogin.setText("Login");
                return;
            }
    
            if(button == btnonline) {
                client.sendMessage(new ChatMessage(ChatMessage.WHOISIN, ""));   //Ändra till Chatmessage klass          
                return;
            }
    
    
            if(connected) {
    
                client.sendMessage(new ChatMessage(ChatMessage.MESSAGE, textfieldusername.getText())); //Ändra till Chatmessage klass       
                textfieldusername.setText("");
                return;
            }
    
    
            if(button == btnlogin) {
    
                String username = textfieldusername.getText();
    
                if(username.length() == 0)
                    return;
    
                String server = textfieldserver.getText();
                if(server.length() == 0)
                    return;
    
                String portNumber = textfieldportnumber.getText();
                if(portNumber.length() == 0)
                    return;
    
    
                int port = 0;
                try {
                    port = Integer.parseInt(portNumber);
                }
                catch(Exception en) {
                    return;  
                }
    
    
                client = new Client(server, port, username, this);
    
                if(!client.start()) 
                    return;
    
                }
    
                connected = true;
    
                textfieldusername.setText("");
                btnlogin.setText("Send message");
    
    
                btnlogin.setEnabled(true);
    
                btnlogout.setEnabled(true);
                btnonline.setEnabled(true);
    
                textfieldserver.setEditable(false);
                textfieldportnumber.setEditable(false);
    
                textfieldusername.addActionListener(this);
            }
    
    
    
        // to start the whole thing the server
        public static void main(String[] args) {
            new ClientGUI("localhost", 1500);
        }
    
    }
    

    Server.java

        package Server;
    
    import java.io.*;
    import java.net.*;
    import java.text.SimpleDateFormat;
    import java.util.*;
    
    /*
     * The server that can be run both as a console application or a GUI
     */
    public class Server {
        // a unique ID for each connection
        private static int uniqueId;
        // an ArrayList to keep the list of the Client
        private ArrayList<ClientThread> al;
        // if I am in a GUI
        private ServerGUI sg;
        // to display time
        private SimpleDateFormat sdf;
        // the port number to listen for connection
        private int port;
        // the boolean that will be turned of to stop the server
        private boolean keepGoing;
    
    
        /*
         *  server constructor that receive the port to listen to for connection as parameter
         *  in console
         */
        public Server(int port) {
            this(port, null);
        }
    
        public Server(int port, ServerGUI sg) {
            // GUI or not
            this.sg = sg;
            // the port
            this.port = port;
            // to display hh:mm:ss
            sdf = new SimpleDateFormat("HH:mm:ss");
            // ArrayList for the Client list
            al = new ArrayList<ClientThread>();
        }
    
        public void start() {
            keepGoing = true;
            /* create socket server and wait for connection requests */
            try 
            {
                // the socket used by the server
                ServerSocket serverSocket = new ServerSocket(port);
    
                // infinite loop to wait for connections
                while(keepGoing) 
                {
                    // format message saying we are waiting
                    display("Server waiting for Clients on port " + port + ".");
    
                    Socket socket = serverSocket.accept();      // accept connection
                    // if I was asked to stop
                    if(!keepGoing)
                        break;
                    ClientThread t = new ClientThread(socket);  // make a thread of it
                    al.add(t);                                  // save it in the ArrayList
                    t.start();
                }
                // I was asked to stop
                try {
                    serverSocket.close();
                    for(int i = 0; i < al.size(); ++i) {
                        ClientThread tc = al.get(i);
                        try {
                        tc.sInput.close();
                        tc.sOutput.close();
                        tc.socket.close();
                        }
                        catch(IOException ioE) {
                            // not much I can do
                        }
                    }
                }
                catch(Exception e) {
                    display("Exception closing the server and clients: " + e);
                }
            }
            // something went bad
            catch (IOException e) {
                String msg = sdf.format(new Date()) + " Exception on new ServerSocket: " + e + "\n";
                display(msg);
            }
        }       
        /*
         * For the GUI to stop the server
         */
        protected void stop() {
            keepGoing = false;
            // connect to myself as Client to exit statement 
            // Socket socket = serverSocket.accept();
            try {
                new Socket("localhost", port);
            }
            catch(Exception e) {
                // nothing I can really do
            }
        }
        /*
         * Display an event (not a message) to the console or the GUI
         */
        private void display(String msg) {
            String time = sdf.format(new Date()) + " " + msg;
            if(sg == null)
                System.out.println(time);
            else
                sg.appendRoom(null,time + "\n");
        }
        /*
         *  to broadcast a message to all Clients
         */
        private synchronized void broadcast(String message) {
            // add HH:mm:ss and \n to the message
            String time = sdf.format(new Date());
            String messageLf = time + " " + message + "\n";
            // display message on console or GUI
            if(sg == null)
                System.out.print(messageLf);
            else
                sg.appendRoom(messageLf,null);     // append in the room window
    
            // we loop in reverse order in case we would have to remove a Client
            // because it has disconnected
            for(int i = al.size(); --i >= 0;) {
                ClientThread ct = al.get(i);
                // try to write to the Client if it fails remove it from the list
                if(!ct.writeMsg(messageLf)) {
                    al.remove(i);
                    display("Disconnected Client " + ct.username + " removed from list.");
                }
            }
        }
    
        // for a client who logoff using the LOGOUT message
        synchronized void remove(int id) {
            // scan the array list until we found the Id
            for(int i = 0; i < al.size(); ++i) {
                ClientThread ct = al.get(i);
                // found it
                if(ct.id == id) {
                    al.remove(i);
                    return;
                }
            }
        }
    
        /*
         *  To run as a console application just open a console window and: 
         * > java Server
         * > java Server portNumber
         * If the port number is not specified 1500 is used
         */ 
        public static void main(String[] args) {
            // start server on port 1500 unless a PortNumber is specified 
            int portNumber = 1500;
            switch(args.length) {
                case 1:
                    try {
                        portNumber = Integer.parseInt(args[0]);
                    }
                    catch(Exception e) {
                        System.out.println("Invalid port number.");
                        System.out.println("Usage is: > java Server [portNumber]");
                        return;
                    }
                case 0:
                    break;
                default:
                    System.out.println("Usage is: > java Server [portNumber]");
                    return;
    
            }
            // create a server object and start it
            Server server = new Server(portNumber);
            server.start();
        }
    
        /** One instance of this thread will run for each client */
        class ClientThread extends Thread {
            // the socket where to listen/talk
            Socket socket;
            ObjectInputStream sInput;
            ObjectOutputStream sOutput;
            // my unique id (easier for deconnection)
            int id;
            // the Username of the Client
            String username;
            // the only type of message a will receive
            ChatMessage cm;
            // the date I connect
            String date;
    
            // Constructore
            ClientThread(Socket socket) {
                // a unique id
                id = ++uniqueId;
                this.socket = socket;
                /* Creating both Data Stream */
                System.out.println("Thread trying to create Object Input/Output Streams");
                try
                {
                    // create output first
                    sOutput = new ObjectOutputStream(socket.getOutputStream());
                    sInput  = new ObjectInputStream(socket.getInputStream());
                    // read the username
                    username = (String) sInput.readObject();
                    display(username + " just connected.");
                }
                catch (IOException e) {
                    display("Exception creating new Input/output Streams: " + e);
                    return;
                }
                // have to catch ClassNotFoundException
                // but I read a String, I am sure it will work
                catch (ClassNotFoundException e) {
                }
                date = new Date().toString() + "\n";
            }
    
            // what will run forever
            public void run() {
                // to loop until LOGOUT
                boolean keepGoing = true;
                while(keepGoing) {
                    // read a String (which is an object)
                    try {
                        cm = (ChatMessage) sInput.readObject();
                    }
                    catch (IOException e) {
                        display(username + " Exception reading Streams: " + e);
                        break;              
                    }
                    catch(ClassNotFoundException e2) {
                        break;
                    }
                    // the messaage part of the ChatMessage
                    String message = cm.getMessage();
    
                    // Switch on the type of message receive
                    switch(cm.getType()) {
    
                    case ChatMessage.MESSAGE:
                        broadcast(username + ": " + message);
                        break;
                    case ChatMessage.LOGOUT:
                        display(username + " disconnected with a LOGOUT message.");
                        keepGoing = false;
                        break;
                    case ChatMessage.WHOISIN:
                        writeMsg("List of the users connected at " + sdf.format(new Date()) + "\n");
                        // scan al the users connected
                        for(int i = 0; i < al.size(); ++i) {
                            ClientThread ct = al.get(i);
                            writeMsg((i+1) + ") " + ct.username + " since " + ct.date);
                        }
                        break;
                    }
                }
                // remove myself from the arrayList containing the list of the
                // connected Clients
                remove(id);
                close();
            }
    
            // try to close everything
            private void close() {
                // try to close the connection
                try {
                    if(sOutput != null) sOutput.close();
                }
                catch(Exception e) {}
                try {
                    if(sInput != null) sInput.close();
                }
                catch(Exception e) {};
                try {
                    if(socket != null) socket.close();
                }
                catch (Exception e) {}
            }
    
            /*
             * Write a String to the Client output stream
             */
            private boolean writeMsg(String msg) {
                // if Client is still connected send the message to it
                if(!socket.isConnected()) {
                    close();
                    return false;
                }
                // write the message to the stream
                try {
                    sOutput.writeObject(msg);
                }
                // if an error occurs, do not abort just inform the user
                catch(IOException e) {
                    display("Error sending message to " + username);
                    display(e.toString());
                }
                return true;
            }
        }
    }
    

1 个答案:

答案 0 :(得分:2)

添加成员变量chatContent并编写如下方法以向其中添加内容。

StringBuilder chatContent = new StringBuilder();

private void addText(String chatText){
    chatContent.append(chatText).append("\n");
}

并在每次附加到聊天文本区域时调用它,并且在写入文件时使用此chatContent作为要写入的内容源。

也许会有所帮助。

或者您也可以使用

将内容直接流式传输到文件中
FileOutputStream

更新1:

选中此JTextArea txt; txt.getText() skips "\n"

这可能会有所帮助。

更新2

// Replace this line 

    File fileName = new File(chooser.getSelectedFile() + "");

    // With following code
    String _fileName = chooser.getSelectedFile();

    if(_fileName != null && !_fileName.endsWith(".txt")){
        _fileName = _fileName + ".txt";
    }

    File fileName = new File(_fileName);