1
回答
JAVA聊天小程序--服务器与客户端已链接,可以收到消息,但是登陆过后客户端为空白,并且换行只在服务器端有用,颜色与字体到公屏就失效
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   

如图,如果单独开服务器,然后开客户端,一切就很正常,如客户端57568,但是如果开服务器后,从登陆界面登陆到客户端,就会变成空白的,如客户端57579。


代码如下:

Login.java(登陆端):

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import javax.swing.*;

 
public class Login implements ActionListener {
    /**
     * @author Laycher {@link http://laycher.cn}
     */
    JFrame jf;
    JTextField jtf;
    JPasswordField jpf;
 
    public Login() {
        jf = new JFrame("登录");
        jf.setLayout(new GridLayout(5, 1));
    //登陆界面图片背景    
        ImageIcon bg =new ImageIcon("D:/Files about/Picture/卡通图标文件夹/ktong005.png");
        JLabel label = new JLabel(bg);
        label.setBounds(0,0,bg.getIconWidth(),bg.getIconHeight());
        jf.getLayeredPane().add(label,new Integer(Integer.MIN_VALUE));
        JPanel jp=(JPanel)jf.getContentPane();
        jp.setOpaque(false);
        
        
        
        jf.add(new JPanel());
        JLabel jl1 = new JLabel("帐号: ");
        jtf = new JTextField(12);
        JPanel jp1 = new JPanel();
        jp1.setOpaque(false);
        jp1.add(jl1);
        jp1.add(jtf);
        jf.add(jp1);
 
        JLabel jl2 = new JLabel("密码: ");
        jpf = new JPasswordField(12);
        JPanel jp2 = new JPanel();
        jp2.setOpaque(false);
        jp2.add(jl2);
        jp2.add(jpf);
        jf.add(jp2);
 
        JPanel jp3 = new JPanel();
        jp3.setOpaque(false);
        JButton btn1 = new JButton("注册", new ImageIcon("D:/Files about/SSE/JAVA/JAVA/2015-07-02/原型设计/添加图标和图片的例子/images/Back.png"));
        btn1.addActionListener(this);
        JButton btn2 = new JButton("登录", new ImageIcon("D:/Files about/SSE/JAVA/JAVA/2015-07-02/原型设计/添加图标和图片的例子/images/Forward.png"));
        btn2.addActionListener(this);
        JButton btn3 = new JButton("取消", new ImageIcon("D:/Files about/SSE/JAVA/JAVA/2015-07-02/原型设计/添加图标和图片的例子/images/Forward.png"));
        btn3.addActionListener(this);
        jp3.add(btn1);
        jp3.add(btn2);
        jp3.add(btn3);
        jf.add(jp3);
 
        jf.setResizable(false);
        jf.setVisible(true);
        jf.setSize(309, 500);
        jf.setLocation(525, 225);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
 
    public static void main(String[] args) {
        new Login();
    }
 
    @Override
    public void actionPerformed(ActionEvent e) {
        String comm = e.getActionCommand();
        if (comm.equals("注册")) {
            jf.dispose();
            new Register();
        } else if (comm.equals("登录")) {
            if ("".equals(jtf.getText())
                    || "".equals(new String(jpf.getPassword()))
                    || jpf.getPassword() == null) {
                JOptionPane.showConfirmDialog(
                        jf,
                        "帐号密码不能为空\n请重新输入", "错误",
                        JOptionPane.DEFAULT_OPTION);
                jtf.setText(null);
                jpf.setText(null);
                jtf.requestFocus();
            } else {
                String s = jtf.getText() + "&&" + new String(jpf.getPassword());
                String name = jtf.getText() + "&&";
                File file = new File("D:\\reg.txt");
                try {
                    FileInputStream fis = new FileInputStream(file);
                    String s1 = "";
                    byte[] b = new byte[1024];
                    while (true) {
                        int i = fis.read(b);
                        if (i == -1)
                            break;
                        s1 = s1 + new String(b, 0, i);
                    }
                    fis.close();
                    int i = s1.indexOf(name);
                    int j = s1.indexOf(s);
                    if (i == -1) {
                        JOptionPane.showConfirmDialog(
                                jf,
                                "无此帐号\n请重新登录或注册", "错误",
                                JOptionPane.ERROR_MESSAGE);
                        jtf.setText(null);
                        jpf.setText(null);
                        jtf.requestFocus();// 光标回来
                    } else {
                        if (j == -1) {
                            JOptionPane.showConfirmDialog(
                                    jf,
                                    "密码错误\n请重新输入密码", "错误",
                                    JOptionPane.DEFAULT_OPTION);
                            jpf.setText(null);
                            jpf.requestFocus();// 光标回来
                        } else {
                            JOptionPane.showConfirmDialog(
                                    jf,
                                    "登录成功\n" + "帐号 : " + jtf.getText()
                                            + "\n密码 : "
                                            + new String(jpf.getPassword()),
                                    "登录结果", JOptionPane.DEFAULT_OPTION);
                            new MainFrame();
                        }
                    }
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        } else if (comm.equals("取消")) {
            System.exit(0);
        }
 
    }
 
}

ContextTest.java(客户端)

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.lang.*;
import java.util.Date;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Date;
 
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;











class ContextTest {
      public static void main(String[] args) {
        MainFrame mf = new MainFrame();
      }
    }

    @SuppressWarnings("serial")
    class MainFrame extends JFrame {
    //选项卡声明
        JMenuItem jm12,jmi1,jmi2,jmi3;
        JSeparator js;
        JTextArea jta;
        
        String name[] = {"testa","testb","testc"};
        JList list = new JList(name);
            private JTabbedPane tabbedPane;//声明选项卡组

            private JPanel panel1 = new JPanel();
            private JPanel panel2 = new JPanel();
            
    //菜单部分    
            JMenu jm1 = new JMenu("操作");
                
                JMenuItem jm1to1 = new JMenuItem("用户登陆");
                JMenuItem jm1to2 = new JMenuItem("用户注销");
                JMenuItem jm1to3 = new JMenuItem("退出");
            
            JMenu jm2 = new JMenu("设置");
                JMenuItem jm2to1 = new JMenuItem("开启/关闭私聊");
                JMenuItem jm2to2 = new JMenuItem("开启/关闭群聊");
                
            JMenu jm3 = new JMenu("帮助");
    //主界面部分    
        JTextArea jta1to1 = new JTextArea("公共聊天记录...",10,36);
        JScrollPane pane11 = new JScrollPane(jta1to1);
          
          JTextArea jta1to2 = new JTextArea("私人聊天记录...",10,36);
          JScrollPane pane12 = new JScrollPane(jta1to2); // 整个窗口的上半部分
      JPanel jpBottom = new JPanel(); // 整个窗口的下半部分
      
      JTextArea jta2 = new JTextArea("");
      JScrollPane pane2 = new JScrollPane(jta2);
      JComboBox jcb1 = new JComboBox(new String[] {"颜色:", "红色", "绿色", "蓝色", "黑色"});
      JComboBox jcb2 = new JComboBox(new String[] {"字体:", "楷体", "黑体", "幼圆", "宋体"});
      JButton btn = new JButton("发送");
      
      JPanel jpBottomRight = new JPanel(); // 整个窗口的右下角
      
      private Socket socket;
        private DataInputStream in;
        private DataOutputStream out;
        private String str;
        SendActionListener sendActionListener;
      
      public MainFrame() {
        super("");
        
        btn.addActionListener(new SendActionListener());
      //菜单条部分        

              this.setLayout(new BorderLayout());
              JMenuBar jmb = new JMenuBar();
              setJMenuBar(jmb);

              jmb.add(jm1); // jm1,jm2绑定到菜单条上
                  jm1.add(jm1to1);
                  jm1.add(jm1to2);
                  jm1.add(jm1to3);
              jmb.add(jm2);
                  jm2.add(jm2to1);
                  jm2.add(jm2to2);
              jmb.add(jm3);
        Container c = getContentPane();

        tabbedPane = new JTabbedPane();
    //主界面部分上面    
        tabbedPane.addTab("公共",null,panel1,"1");
        tabbedPane.addTab("私人",null,panel2,"2");
        
        GridLayout grid = new GridLayout(1,1,5,5);
        panel1.setLayout(grid);
        panel2.setLayout(grid);
        
        this.add(tabbedPane,BorderLayout.WEST);
        this.add(list);
        
        list.setFont(new Font("宋体", Font.PLAIN , 15));
        
        
        jta1to1.setFont(new Font("黑体", Font.PLAIN , 15));
        jta1to1.setEditable(false);
        panel1.add(pane11, BorderLayout.CENTER);

        
        jta1to2.setFont(new Font("黑体", Font.PLAIN , 15));
        jta1to2.setEditable(false);
        panel2.add(pane12, BorderLayout.CENTER);
        
      //主界面部分下面       
        c.add(jpBottom, BorderLayout.SOUTH);
        
        jta2.setFont(new Font("黑体", Font.PLAIN , 18));
        jta2.setAutoscrolls(true); // 在用户录入文字的时候,滚动条自动下滑
        pane2.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        pane2.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
        jpBottom.setLayout(new BorderLayout());
        jpBottom.add(pane2, BorderLayout.CENTER);
        jpBottom.add(jpBottomRight, BorderLayout.EAST);
        
        jpBottomRight.setLayout(new GridLayout(3, 1));
        jpBottomRight.add(jcb1);
        jpBottomRight.add(jcb2);
        jpBottomRight.add(btn);
        //颜色
        jcb1.addItemListener(
          new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
              switch( jcb1.getSelectedIndex() ) {
                case 1: jta2.setForeground(Color.RED); break;
                case 2: jta2.setForeground(Color.GREEN); break;
                case 3: jta2.setForeground(Color.BLUE); break;
                case 4: jta2.setForeground(Color.BLACK); break;
              }
            }
          }
        );
        
        
        //字体
        jcb2.addItemListener(
          new ItemListener() {
            public void itemStateChanged(ItemEvent e) {
              Font old = jta2.getFont(); // 保留原有字体的特性
              
              switch( jcb2.getSelectedIndex() ) {
                case 1:
                  jta2.setFont(
                    new Font("楷体", old.getStyle(), old.getSize())
                  );
                  break;
                case 2:
                  jta2.setFont(
                    new Font("黑体", old.getStyle(), old.getSize())
                  );
                  break;
                case 3:
                  jta2.setFont(
                    new Font("幼圆", old.getStyle(), old.getSize())
                  );
                  break;
                case 4:
                  jta2.setFont(
                    new Font("宋体", old.getStyle(), old.getSize())
                  );
                  break;
              }
            }
          }
        );
        
        
    
        
        jta1to1.setEditable(false);
        jta1to1.setLineWrap(true);
        jta1to1.setWrapStyleWord(true);
        
        
        setLocation(525, 225);
        setSize(700, 500);
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        
        connect();
        
        // 重写append方法,在前面加上日期和在末尾加上换行
        jta1to1 = new JTextArea() {
            @Override
            public void append(String str) {
                str = new Date().toString() + "   " + str + "\n";
                super.append(str);
               
            }
        };
      }
      private void connect() {
            int port = 8888;
            try {
                socket = new Socket("localhost", port);
                jta1to1.append("连接到服务,本地端口号" + socket.getLocalPort());
                setTitle("客户端" + socket.getLocalPort());
                in = new DataInputStream(socket.getInputStream());
                out = new DataOutputStream(socket.getOutputStream());
    
                String message;
                while ((message = in.readUTF()) != null) {
                    jta1to1.append(message);
                }
            } catch (IOException e) {
                jta1to1.append("连接异常");
                close();
            }
        }
      
    // 释放资源
        private int close() {
            int exitCode = 0;
            if (out != null) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    exitCode = 1;
                }
            }
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    exitCode = 1;
                }
    
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    exitCode = 1;
                    e.printStackTrace();
                }
            }
            return exitCode;
        }
    
        // 响应关闭操作
        private class WindowExitListener extends WindowAdapter {
            @Override
            public void windowClosing(WindowEvent event) {
                System.exit(close());
            }
        }
        
      private class SendActionListener implements ActionListener {
          
            
            public void actionPerformed(ActionEvent event) {
                str = jta2.getText();
                try {
                    out.writeUTF(str);
                    jta2.setText("");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
        }
    }

注册端:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
 
import javax.swing.*;
 
public class Register implements ActionListener {
    /**
     * @author Laycher {@link http://laycher.cn}
     */
    JFrame jf;
    JTextField jtf;
    JPasswordField jpf, jpf2;
 
    public Register() {
        jf = new JFrame("注册");
        jf.setLayout(new GridLayout(6, 1));
        jf.add(new JPanel());
        JLabel jl1 = new JLabel("帐号:");
        jtf = new JTextField(12);
        JPanel jp1 = new JPanel();
        jp1.add(jl1);
        jp1.add(jtf);
        jf.add(jp1);
 
        JLabel jl2 = new JLabel("密码:");
        jpf = new JPasswordField(12);
        JPanel jp2 = new JPanel();
        jp2.add(jl2);
        jp2.add(jpf);
        jf.add(jp2);
 
        JLabel jl3 = new JLabel("确认:");
        jpf2 = new JPasswordField(12);
        JPanel jp3 = new JPanel();
        jp3.add(jl3);
        jp3.add(jpf2);
        jf.add(jp3);
 
        JPanel jp4 = new JPanel();
        JButton jb1 = new JButton("确认注册", new ImageIcon("D:/Files about/SSE/JAVA/JAVA/2015-07-02/原型设计/添加图标和图片的例子/images/Forward.png"));
        jb1.addActionListener(this);
        JButton jb2 = new JButton("取消", new ImageIcon("D:/Files about/SSE/JAVA/JAVA/2015-07-02/原型设计/添加图标和图片的例子/images/Forward.png"));
        jb2.addActionListener(this);
        jp4.add(jb1);
        jp4.add(jb2);
        jf.add(jp4);
 
        jf.setResizable(false);
        jf.setVisible(true);
        jf.setSize(309, 500);
        jf.setLocation(525, 255);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
 
    public static void main(String[] args) {
        new Register();
    }
 
    @Override
    public void actionPerformed(ActionEvent e) {
        String comm = e.getActionCommand();
        if (comm.equals("确认注册")) {
            // jf.dispose();
            if ("".equals(jtf.getText())
                    || "".equals(new String(jpf.getPassword()))
                    || jpf.getPassword() == null
                    || "".equals(new String(jpf2.getPassword()))
                    || jpf2.getPassword() == null) {
                final JFrame jf = new JFrame("错误");
                JLabel jl = new JLabel("帐号或密码不能为空!");
                JPanel jp1 = new JPanel();
                JPanel jp2 = new JPanel();
                jp1.add(jl);
                jf.add(jp1);
                JButton jb = new JButton("确定");
                jb.addActionListener(new ActionListener() {
 
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        jf.dispose();
                    }
 
                });
                jp2.add(jb);
                jf.add(jp2);
                jf.setLayout(new GridLayout(2, 1));
                jf.setResizable(false);
                jf.setVisible(true);
                jf.pack();
                jf.setLocation(525, 255);
            } else {
                String s = jtf.getText() + "&&" + new String(jpf.getPassword())
                        + "\r\n";// '\r'+'\n'也可以,"\r"+"\n"也可以
                String name = jtf.getText() + "&&";
                File file = new File("D:\\reg.txt");
                try {
                    file.createNewFile(); // 当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。
                } catch (IOException e2) {
                    e2.printStackTrace();
                }
                try { // 读文件的注册信息
                    FileInputStream fis = new FileInputStream(file);
                    String s1 = "";
                    byte[] b = new byte[1024];
                    while (true) {
                        int i = fis.read(b);
                        if (i == -1)
                            break;
                        s1 = s1 + new String(b, 0, i);
                    }
                    fis.close();// 关闭流
                    int i = s1.indexOf(name);
                    if (i == -1) { // 如果文档中没有,要注册到文件中
                        if (new String(jpf.getPassword()).equals(new String(
                                jpf2.getPassword()))) {
                            try {
                                FileOutputStream fos = new FileOutputStream(
                                        file, true);
                                // true就是追加,false就是替换。
                                fos.write(s.getBytes());
                                fos.close();
                            } catch (Exception e1) {
                                e1.printStackTrace();
                            }
                            int a = JOptionPane.showConfirmDialog(jf, "注册成功!\n"
                                    + "帐号 : " + jtf.getText() + "\n密码 : "
                                    + new String(jpf.getPassword())
                                    + "\n点确定转入登录界面", "注册结果",
                                    JOptionPane.OK_CANCEL_OPTION);
                            if (a == 0) {
                                jf.dispose();
                                new Login();
                            }
                        } else {
                            JOptionPane.showConfirmDialog(
                                    jf, // 如果为null,此框架显示在中央,为jf则显示为jf的中央
                                    "两次密码不一样!\n请重新输入密码!", "密码不一样",
                                    JOptionPane.CLOSED_OPTION);
                            jpf.setText(null);
                            jpf2.setText(null);
                            jpf.requestFocus();// 光标回来
                        }
                    } else {
 
                        JOptionPane.showConfirmDialog(
                                jf, // 如果为null,此框架显示在中央,为jf则显示为jf的中央
                                "帐号已经被注册!\n请换一个帐号重新注册!", "错误",
                                JOptionPane.CLOSED_OPTION);
                        jtf.setText(null);
                        jpf.setText(null);
                        jpf2.setText(null);
                        jtf.requestFocus();// 光标回来
                    }
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        } else if (comm.equals("取消")) {
            System.exit(0);
        }
 
    }
}

服务器端:

import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
 
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
 
@SuppressWarnings("serial")
public class Server extends JFrame {
 
    private JScrollPane pane;
    private JTextArea textAreaShow;
    private ServerSocket serverSocket;
    private List<Socket> connectedSockets = new ArrayList<Socket>();
 
    public Server() {
        initFrame();
        int port = 8888;
        try {
            startServer(port);
        } catch (IOException e) {
            String text = "以端口号" + port + "启动Socket服务失败,检查端口是否被占用,并重新启动服务";
            textAreaShow.append(text);
        }
    }
 
    // 窗口初始化
    private void initFrame() {
 
        setTitle("服务端");
        setSize(500, 400);
        setMinimumSize(new Dimension(250, 200));
 
        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent event) {
                if (serverSocket != null) {
                    try {
                        serverSocket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                        System.exit(1);
                    }
                    System.exit(0);
                }
            }
        });
 
        // 重写JTextArea的append方法
        textAreaShow = new JTextArea() {
            @Override
            public void append(String str) {
                str = (new Date().toString()) + "  " + str + "\n";
                super.append(str);
            }
        };
        textAreaShow.setEditable(false);
        textAreaShow.setLineWrap(true);
        textAreaShow.setWrapStyleWord(true);
 
        pane = new JScrollPane(textAreaShow,
                JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
 
        add(pane);
 
        setVisible(true);
    }
 
    // 启动服务,等待客户端连接
    private void startServer(int port) throws IOException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        serverSocket = new ServerSocket(port);
        Socket socket;
        textAreaShow.append("服务已启动,端口号" + port);
        while (true) {
            socket = serverSocket.accept();
            String connectedMsg = "端口号" + socket.getPort() + " 已连接";
            textAreaShow.append(connectedMsg);
            dispatchMessage(connectedMsg);
            connectedSockets.add(socket);
            executorService.execute(new ServerThread(socket));
        }
    }
 
    // 向各客个连接转发发送消息
    private void dispatchMessage(String str) {
        DataOutputStream dos;
        for (Socket soc : connectedSockets) {
            try {
                dos = new DataOutputStream(soc.getOutputStream());
                dos.writeUTF(str);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
 
    // 处理各连接的线程
    private class ServerThread implements Runnable {
 
        private Socket socket;
        private DataInputStream in;
 
        public ServerThread(Socket socket) {
            this.socket = socket;
            try {
                in = new DataInputStream(socket.getInputStream());
            } catch (IOException e) {
                textAreaShow.append(e.getMessage());
            }
        }
 
       
        public void run() {
            try {
                String str;
                while ((str = in.readUTF()) != null) {
                    str = socket.getPort() + "说:" + str;
                    textAreaShow.append(str);
                    dispatchMessage(str);
                }
            } catch (IOException e) {
                textAreaShow.append("Port " + socket.getPort() + " 已断开连接");
                connectedSockets.remove(socket);
                closeSocket();
            }
        }
 
        private void closeSocket() {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
 
    public static void main(String[] args) {
        new Server();
    }
}

谢谢各位大大了,求助!!!

举报
RexIEnk
发帖于2年前 1回/592阅
顶部