java課設(shè)之簡(jiǎn)易聊天室全部代碼

github地址https://github.com/HWenTing/MyChatRoom

在學(xué)習(xí)了半年java基礎(chǔ)知識(shí)后敛滋,在上學(xué)期我們完成了java課設(shè)屡谐,現(xiàn)在正好想起來(lái)魂爪,順便整理一下滓侍。代碼總行數(shù)約2400行撩笆,涉及知識(shí):java基礎(chǔ)捺球,socket套接字連接,一部分與數(shù)據(jù)庫(kù)連接知識(shí)夕冲,GUI氮兵,多線程,文件io等歹鱼。代碼部分參考過(guò)他人代碼泣栈。


該課設(shè)主要包括登錄,注冊(cè)弥姻,聊天室南片,貪吃蛇,截屏五大板塊庭敦。
大體界面就是這樣子啦(原諒我的審美23333)


登錄

注冊(cè)

貪吃蛇

***
聊天室

截屏

沒(méi)錯(cuò)疼进,總體就是這個(gè)樣子的,以下附上代碼颠悬,還有設(shè)計(jì)文檔總結(jié)報(bào)告等,需要的小伙伴可以聯(lián)系我哇~


CatBean

這個(gè)類主要用于封裝

import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;

public class CatBean implements Serializable {
    private int type; // 1私聊 0上下線更新 -1下線請(qǐng)求 2請(qǐng)求發(fā)送文件 3.確定接收文件
    private HashSet<String> clients; // 存放選中的客戶
    private HashSet<String> to;
    public HashMap<String, ClientBean> onlines;
    private String info;
    private String timer;
    private String name;
    private String fileName;
    private int size;
    private String ip;
        private int port;
    public int getSize() {
        return size;
    }
    public void setSize(int size) {
        this.size = size;
    }
    public String getFileName() {
        return fileName;
    }
    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
    public HashSet<String> getTo() {
        return to;
    }
    public void setTo(HashSet<String> to) {
        this.to = to;
    }
    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }
    public HashSet<String> getClients() {
        return clients;
    
    public void setClients(HashSet<String> clients) {
        this.clients = clients;
    }
    public String getInfo() {
        return info;
    }
    public void setInfo(String info) {
        this.info = info;
    }
    public String getTimer() {
        return timer;
    }
    public void setTimer(String timer) {
        this.timer = timer;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getIp() {
        return ip;
    }
    public void setIp(String ip) {
        this.ip = ip;
    }
    public int getPort() {
        return port;
    }
    public void setPort(int port) {
        this.port = port;
    }
    public HashMap<String, ClientBean> getOnlines() {
        return onlines;
    }
    public void setOnlines(HashMap<String, ClientBean> onlines) {
        this.onlines = onlines;
    }
}

CatChatroom

聊天室的主頁(yè)面刊苍,包含GUI與后臺(tái)邏輯



import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;

import javax.swing.AbstractListModel;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ListCellRenderer;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;

/**
 * 用戶列表中每個(gè)用戶顯示狀態(tài)
 * @author HP
 *
 */

class CellRenderer extends JLabel implements ListCellRenderer {
    CellRenderer() {
        setOpaque(true);
    }

    public Component getListCellRendererComponent(JList list, Object value,
            int index, boolean isSelected, boolean cellHasFocus) {

        setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));// 加入寬度為5的空白邊框

        if (value != null) {
            setText(value.toString());
            setIcon(new ImageIcon("images//tou1.png"));//設(shè)置頭像
        }
        //設(shè)置用戶被選中和為被選中兩種前景與背景顏色狀態(tài)表示
        if (isSelected) {
            //被選中時(shí)
            setBackground(new Color(255, 255, 153));// 設(shè)置背景色
            setForeground(Color.black);//設(shè)置字體色
        } else {
            //未被選中
            setBackground(Color.white); // 設(shè)置背景色
            setForeground(Color.black);//設(shè)置字體色
        }
        setEnabled(list.isEnabled());
        setFont(new Font("sdf", Font.ROMAN_BASELINE, 13));
        setOpaque(true);
        return this;
    }
}


class UUListModel extends AbstractListModel{
    
    private Vector vs;
    
    public UUListModel(Vector vs){
        this.vs = vs;
    }

    @Override
    public Object getElementAt(int index) {
        // TODO Auto-generated method stub
        return vs.get(index);
    }

    @Override
    public int getSize() {
        // TODO Auto-generated method stub
        return vs.size();
    }
    
}


public class CatChatroom extends JFrame {

    private static final long serialVersionUID = 6129126482250125466L;

    private static JPanel contentPane;
    private static Socket clientSocket;
    private static ObjectOutputStream oos;
    private static ObjectInputStream ois;
    private static String name;
    private static JTextArea textArea;
    private static AbstractListModel listmodel;
    private static JList list;
    private static String filePath;
    private static JLabel lblNewLabel;
    private static JProgressBar progressBar;
    private static Vector onlines;
    private static boolean isSendFile = false;
    private static boolean isReceiveFile = false;

    // 聲音
    private static File file, file2;
    private static URL cb, cb2;
    private static AudioClip aau, aau2;
    private File contentFile;
    /**
     * Create the frame.
     */

    public CatChatroom(String u_name, Socket client) {
        // 賦值
        name = u_name;
        clientSocket = client;
        onlines = new Vector();
        
        SwingUtilities.updateComponentTreeUI(this);

        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");//改變窗口顯示風(fēng)格
        } catch (ClassNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (InstantiationException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IllegalAccessException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (UnsupportedLookAndFeelException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }


        
        setTitle(name);

        setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        setBounds(440, 200, 896, 796);
        contentPane = new JPanel() {
            private static final long serialVersionUID = 1L;
            @Override//加載背景圖片
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawImage(new ImageIcon("images\\q1.jpg").getImage(), 0, 0,
                        getWidth(), getHeight(), null);
            }
        };
        
        try {
        contentFile=new File(name);
        } catch (Exception e) {
        // TODO: handle exception
        }
    
        setContentPane(contentPane);
        contentPane.setLayout(null);

        // 聊天信息顯示區(qū)域
        
        JScrollPane scrollPane = new JScrollPane();
        scrollPane.setBounds(10, 10, 490, 510);
        getContentPane().add(scrollPane);
        //聊天信息顯示框
        textArea = new JTextArea();
        textArea.setEditable(false);
        textArea.setLineWrap(true);//激活自動(dòng)換行功能 
        textArea.setWrapStyleWord(true);//激活斷行不斷字功能 
        textArea.setFont(new Font("sdf", Font.BOLD, 17));
        //將以往聊天記錄顯示在聊天信息顯示框
        try {
        BufferedReader br=new BufferedReader(new FileReader(contentFile));
        String tempString = null;
        textArea.setFont(new Font("sdf", Font.BOLD, 13));
        while((tempString=br.readLine())!=null){
            textArea.append(tempString+"\n");
        }
        textArea.setFont(new Font("sdf", Font.BOLD, 17));

        br.close();
        
    } catch ( IOException e3) {
        // TODO Auto-generated catch block
        e3.printStackTrace();
    }
        
        scrollPane.setViewportView(textArea);
        
        // 打字區(qū)域
        JScrollPane scrollPane_1 = new JScrollPane();
        scrollPane_1.setBounds(10, 557, 498, 137);
        getContentPane().add(scrollPane_1);
        //輸入信息顯示框
        final JTextArea textArea_1 = new JTextArea();
        textArea_1.setLineWrap(true);//激活自動(dòng)換行功能 
        textArea_1.setWrapStyleWord(true);//激活斷行不斷字功能 
        textArea_1.setFont(new Font("sdf", Font.PLAIN, 18));
        scrollPane_1.setViewportView(textArea_1);

        // 關(guān)閉按鈕
        final JButton btnNewButton = new JButton("關(guān)閉");
        btnNewButton.setBounds(270, 700, 100, 40);
        getContentPane().add(btnNewButton);

        // 發(fā)送按鈕
        JButton btnNewButton_1 = new JButton("發(fā)送");
        btnNewButton_1.setBounds(224+180, 700, 100, 40);
        getRootPane().setDefaultButton(btnNewButton_1);
        getContentPane().add(btnNewButton_1);
        //貪吃蛇按鈕
        JButton btnNewButton_2 = new JButton("貪吃蛇");
        btnNewButton_2.setBounds(344+230, 700, 100, 40);
        //貪吃蛇按鈕增添事件監(jiān)聽(tīng)
        btnNewButton_2.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                // 啟動(dòng)貪吃蛇小游戲
                GreedSnake gs;
                try {
                    gs = new GreedSnake();
                } catch (Exception e2) {
                    // TODO: handle exception
                }
            }
        });
        getContentPane().add(btnNewButton_2);
        
        //截屏按鈕
        JButton btnNewButton_3 = new JButton("截屏");
        btnNewButton_3.setBounds(466+255, 700, 100, 40);
        //截屏按鈕增添事件監(jiān)聽(tīng)
        btnNewButton_3.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
            Sreen ss=new Sreen();
            //啟動(dòng)截屏功能
            ss.doStart();
                
            }
        });
        getContentPane().add(btnNewButton_3);
        
        //清屏按鈕
        JButton btnNewButton_4 = new JButton("清屏");
        btnNewButton_4.setBounds(414,523, 100, 34);
        //增加時(shí)間監(jiān)聽(tīng)
        btnNewButton_4.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                textArea.setText(null);
                
            }
        });
        getContentPane().add(btnNewButton_4);
        
        // 在線客戶列表
        listmodel = new UUListModel(onlines) ;
        list = new JList(listmodel);
        list.setCellRenderer(new CellRenderer());
        list.setOpaque(false);
        Border etch = BorderFactory.createEtchedBorder();
        list.setBorder(BorderFactory.createTitledBorder(etch, "<"+u_name+">"
                + "在線客戶:", TitledBorder.LEADING, TitledBorder.TOP, new Font(
                "sdf", Font.BOLD, 20), Color.green));//標(biāo)題欄設(shè)置
        //在線用戶滾動(dòng)區(qū)域
        JScrollPane scrollPane_2 = new JScrollPane(list);
        scrollPane_2.setBounds(530, 10, 345,575);
        scrollPane_2.setOpaque(false);
        scrollPane_2.getViewport().setOpaque(false);
        getContentPane().add(scrollPane_2);

        // 文件傳輸欄        progressBar       它可以 簡(jiǎn)單地輸出進(jìn)度的變化情況
        progressBar = new JProgressBar();
        progressBar.setBounds(530, 650, 345, 25);
        progressBar.setMinimum(1);
        progressBar.setMaximum(100);
        getContentPane().add(progressBar);

        // 文件傳輸提示
        lblNewLabel = new JLabel(
                "文件傳輸信息欄:");
        lblNewLabel.setFont(new Font("SimSun", Font.PLAIN, 15));
        lblNewLabel.setBackground(Color.WHITE);
        lblNewLabel.setBounds(530, 610,345, 25);
        getContentPane().add(lblNewLabel);

        try {
            oos = new ObjectOutputStream(clientSocket.getOutputStream());
            // 記錄上線客戶的信息在catbean中,并發(fā)送給服務(wù)器
            CatBean bean = new CatBean();
            bean.setType(0);
            bean.setName(name);
            bean.setTimer(CatUtil.getTimer());
            oos.writeObject(bean);
            oos.flush();

            // 消息提示聲音
            file = new File("sounds\\消息.wav");
            cb = file.toURL();
            aau = Applet.newAudioClip(cb);
            // 上線提示聲音
            file2 = new File("sounds\\上線.wav");
            cb2 = file2.toURL();
            aau2 = Applet.newAudioClip(cb2);

            // 啟動(dòng)客戶接收線程
            new ClientInputThread().start();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // 發(fā)送按鈕事件監(jiān)聽(tīng)
        btnNewButton_1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String info = textArea_1.getText();
                List to = list.getSelectedValuesList();//獲取所選擇對(duì)象
                //若未選擇對(duì)象
                if (to.size() < 1) {
                    JOptionPane.showMessageDialog(getContentPane(), "請(qǐng)選擇聊天對(duì)象");
                    return;
                }
                //若選擇對(duì)象為自己
                if (to.toString().contains(name+"(我)")) {
                    JOptionPane
                            .showMessageDialog(getContentPane(), "不能向自己發(fā)送信息");
                    return;
                }
                //若發(fā)送信息為空
                if (info.equals("")) {
                    JOptionPane.showMessageDialog(getContentPane(), "不能發(fā)送空信息");
                    return;
                }
                //正常情況下,建立連接,發(fā)送數(shù)據(jù)
                CatBean clientBean = new CatBean();
                clientBean.setType(1);
                clientBean.setName(name);
                String time = CatUtil.getTimer();
                clientBean.setTimer(time);
                clientBean.setInfo(info);
                HashSet set = new HashSet();
                set.addAll(to);
                clientBean.setClients(set);
                sendMessage(clientBean);

                // 自己發(fā)的內(nèi)容也要現(xiàn)實(shí)在自己的屏幕上面
                textArea.append(time + " 我對(duì)" + to + "說(shuō):\r\n" + info + "\r\n");
                //將發(fā)送信息保存在本地文件中,作為聊天記錄
                try {
                    FileWriter fw=new FileWriter(contentFile,true);
                    BufferedWriter bw=new BufferedWriter(fw);
                    bw.write(time + "我對(duì)<" + to + ">說(shuō):\r\n" + info + "\r\n");
                    
                    bw.close();
                    fw.close();
                } catch (IOException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
                //清空發(fā)送消息欄并重新獲取焦點(diǎn)
                textArea_1.setText(null);
                textArea_1.requestFocus();
            }
        });

        // 關(guān)閉按鈕事件監(jiān)聽(tīng)
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //在文件傳輸時(shí)不能關(guān)閉窗口
                if(isSendFile || isReceiveFile){
                    JOptionPane.showMessageDialog(contentPane,
                            "正在傳輸文件中志鞍,您不能離開(kāi)...",
                            "Error Message", JOptionPane.ERROR_MESSAGE);
                }else{
                //發(fā)送下線消息
                btnNewButton.setEnabled(false);
                CatBean clientBean = new CatBean();
                clientBean.setType(-1);
                clientBean.setName(name);
                clientBean.setTimer(CatUtil.getTimer());
                sendMessage(clientBean);
                }
            }
        });

        // 窗口事件監(jiān)聽(tīng)    
        this.addWindowListener(new WindowAdapter() {
            @Override
            //離開(kāi)
            public void windowClosing(WindowEvent e) {
                // TODO Auto-generated method stub
                if(isSendFile || isReceiveFile){
                    JOptionPane.showMessageDialog(contentPane,
                            "正在傳輸文件中仙蚜,您不能離開(kāi)...",
                            "Error Message", JOptionPane.ERROR_MESSAGE);
                }else{
                int result = JOptionPane.showConfirmDialog(getContentPane(),
                        "您確定要離開(kāi)聊天室");//取得用戶選擇
                //若用戶選擇確定離開(kāi)贾节,發(fā)送下線消息
                if (result == 0) {
                    CatBean clientBean = new CatBean();
                    clientBean.setType(-1);
                    clientBean.setName(name);
                    clientBean.setTimer(CatUtil.getTimer());
                    sendMessage(clientBean);
                }
                }
            }
        });

        // 在線用戶列表監(jiān)聽(tīng)
        list.addMouseListener(new MouseAdapter() {

            @Override//鼠標(biāo)事件監(jiān)聽(tīng)
            public void mouseClicked(MouseEvent e) {
                List to = list.getSelectedValuesList();
                //雙擊事件代表發(fā)送文件
                if (e.getClickCount() == 2) {
                    //如過(guò)發(fā)送對(duì)象為自己
                    if (to.toString().contains(name+"(我)")) {
                        JOptionPane
                                .showMessageDialog(getContentPane(), "不能向自己發(fā)送文件");
                        return;
                    }
                    
                    // 雙擊打開(kāi)文件文件選擇框
                    JFileChooser chooser = new JFileChooser();
                    chooser.setDialogTitle("選擇文件框"); // 標(biāo)題
                    chooser.showDialog(getContentPane(), "選擇"); // 按鈕的名字

                    // 判定是否選擇了文件
                    if (chooser.getSelectedFile() != null) {
                        // 獲取路徑
                        filePath = chooser.getSelectedFile().getPath();
                        File file = new File(filePath);
                        // 如果文件為空
                        if (file.length() == 0) {
                            JOptionPane.showMessageDialog(getContentPane(),
                                    filePath + "文件為空,不允許發(fā)送.");
                            return;
                        }
                        //正常狀態(tài)斤程,建立連接墨吓,發(fā)送請(qǐng)求
                        CatBean clientBean = new CatBean();
                        clientBean.setType(2);// 請(qǐng)求發(fā)送文件
                        clientBean.setSize(new Long(file.length()).intValue());
                        clientBean.setName(name);
                        clientBean.setTimer(CatUtil.getTimer());
                        clientBean.setFileName(file.getName()); // 記錄文件的名稱
                        clientBean.setInfo("請(qǐng)求發(fā)送文件");

                        // 判斷要發(fā)送給誰(shuí)
                        HashSet<String> set = new HashSet<String>();
                        set.addAll(list.getSelectedValuesList());
                        clientBean.setClients(set);
                        sendMessage(clientBean);
                    }
                }
            }
        });

    }
/**
 * 線程接收類
 * @author HP
 *
 */
    class ClientInputThread extends Thread {

        @Override
        public void run() {
            try {
                // 不停的從服務(wù)器接收信息
                while (true) {
                    ois = new ObjectInputStream(clientSocket.getInputStream());
                    final CatBean  bean = (CatBean) ois.readObject();
                    //分析接受到catbean的類型
                    switch (bean.getType()) {
                    case 0: {
                        // 更新列表
                        onlines.clear();//清空列表
                        HashSet<String> clients = bean.getClients();
                        Iterator<String> it = clients.iterator();
                        //重新加載
                        while (it.hasNext()) {
                            String ele = it.next();
                            if (name.equals(ele)) {
                                onlines.add(ele + "(我)");
                            } else {
                                onlines.add(ele);
                            }
                        }

                        listmodel = new UUListModel(onlines);
                        list.setModel(listmodel);
                        aau2.play();//上線聲音
                        textArea.append(bean.getInfo() + "\r\n");
                        textArea.selectAll();
                        break;
                    }
                    case -1: {
                        //直接下線
                        return;
                    }
                    case 1: {
                        //獲取發(fā)送信息
                        String info = bean.getTimer() + "  " +bean.getName()
                                + "對(duì) " +bean.getClients() + "說(shuō):\r\n";
                        //將對(duì)方發(fā)送消息中自己的名字替換成“我”
                        if (info.contains(name) ) {
                            info = info.replace(name, "我");
                        }
                        aau.play();
                        textArea.append(info+bean.getInfo() + "\r\n");
                        //將對(duì)方發(fā)送的消息寫(xiě)入聊天記錄中
                        try {
                            FileWriter fw=new FileWriter(contentFile,true);
                            BufferedWriter bw=new BufferedWriter(fw);
                            bw.write(info+bean.getInfo() + "\r\n");
                            
                            bw.close();
                            fw.close();
                        } catch (IOException e1) {
                            // TODO Auto-generated catch block
                            e1.printStackTrace();
                        }
                        textArea.selectAll();
                        break;
                    }
                    case 2: {
                        // 由于等待目標(biāo)客戶確認(rèn)是否接收文件是個(gè)阻塞狀態(tài)式矫,所以這里用線程處理
                        new Thread(){
                            public void run() {
                                //顯示是否接收文件對(duì)話框
                                int result = JOptionPane.showConfirmDialog(
                                        getContentPane(), bean.getInfo());
                                //對(duì)用戶做出的選擇做出反應(yīng)
                                switch(result){
                                    case 0:{  //接收文件
                                        JFileChooser chooser = new JFileChooser();
                                        chooser.setDialogTitle("保存文件框"); // 標(biāo)題
                                        //默認(rèn)文件名稱還有放在當(dāng)前目錄下
                                        chooser.setSelectedFile(new File(bean
                                                .getFileName()));
                                        chooser.showDialog(getContentPane(), "保存"); // 設(shè)置按鈕名字
                                        //保存路徑
                                        String saveFilePath =chooser.getSelectedFile().toString();
                                
                                        //創(chuàng)建客戶CatBean
                                        CatBean clientBean = new CatBean();
                                        clientBean.setType(3);
                                        clientBean.setName(name);  //接收文件的客戶名字
                                        clientBean.setTimer(CatUtil.getTimer());
                                        clientBean.setFileName(saveFilePath);
                                        clientBean.setInfo("確定接收文件");

                                        // 判斷要發(fā)送給誰(shuí)
                                        HashSet<String> set = new HashSet<String>();
                                        set.add(bean.getName());
                                        clientBean.setClients(set);  //文件來(lái)源
                                        clientBean.setTo(bean.getClients());//給這些客戶發(fā)送文件
                                    
                                    
                                    
                                        // 創(chuàng)建新的tcp socket 接收數(shù)據(jù)
                                        try {
                                            ServerSocket ss = new ServerSocket(0); // 0可以獲取空閑的端口號(hào)
                                            clientBean.setIp(clientSocket.getInetAddress().getHostAddress());
                                            clientBean.setPort(ss.getLocalPort());
                                            sendMessage(clientBean); // 先通過(guò)服務(wù)器告訴發(fā)送方, 你可以直接發(fā)送文件到我這里了
                                            isReceiveFile=true;
                                            //等待文件來(lái)源的客戶板熊,輸送文件....目標(biāo)客戶從網(wǎng)絡(luò)上讀取文件,并寫(xiě)在本地上
                                            Socket sk = ss.accept();
                                            textArea.append(CatUtil.getTimer() + "  " + bean.getFileName()
                                                    + "文件保存中.\r\n");
                                            DataInputStream dis = new DataInputStream(  //從網(wǎng)絡(luò)上讀取文件
                                                    new BufferedInputStream(sk.getInputStream()));
                                            DataOutputStream dos = new DataOutputStream(  //寫(xiě)在本地上
                                                    new BufferedOutputStream(new FileOutputStream(
                                                            saveFilePath)));
                
                                            int count = 0;
                                            int num = bean.getSize() / 100;
                                            int index = 0;
                                            while (count < bean.getSize()) {
                                                int t = dis.read();
                                                dos.write(t);
                                                count++;
                                            
                                                if(num>0){
                                                    if (count % num == 0 && index < 100) {
                                                        progressBar.setValue(++index);
                                                    }
                                                    lblNewLabel.setText("下載進(jìn)度:" + count
                                                            + "/" + bean.getSize() + "  整體" + index
                                                            + "%");
                                                }else{
                                                    lblNewLabel.setText("下載進(jìn)度:" + count
                                                            + "/" + bean.getSize() +"  整體:"+new Double(new Double(count).doubleValue()/new Double(bean.getSize()).doubleValue()*100).intValue()+"%");
                                                    if(count==bean.getSize()){
                                                        progressBar.setValue(100);
                                                    }
                                                }
                                            }
                                        
                                        //給文件來(lái)源客戶發(fā)條提示竭贩,文件保存完畢
                                        PrintWriter out = new PrintWriter(sk.getOutputStream(),true);
                                        out.println(CatUtil.getTimer() + " 發(fā)送給"+name+"的文件[" + bean.getFileName()+"]"
                                                + "文件保存完畢.\r\n");
                                        out.flush();
                                        dos.flush();
                                        dos.close();
                                        out.close();
                                        dis.close();
                                        sk.close();
                                        ss.close();
                                        textArea.append(CatUtil.getTimer() + "  " + bean.getFileName()
                                                + "文件保存完畢.存放位置為:"+saveFilePath+"\r\n");
                                        isReceiveFile = false;
                                    } catch (Exception e) {
                                        // TODO Auto-generated catch block
                                        e.printStackTrace();
                                    }
                                    
                                    break;
                                }default: {
                                    //用戶選擇取消接收
                                    CatBean clientBean = new CatBean();
                                    clientBean.setType(4);
                                    clientBean.setName(name);  //接收文件的客戶名字
                                    clientBean.setTimer(CatUtil.getTimer());
                                    clientBean.setFileName(bean.getFileName());
                                    clientBean.setInfo(CatUtil.getTimer() + "  "
                                            + name + "取消接收文件["
                                            + bean.getFileName() + "]");
                                    // 判斷要發(fā)送給誰(shuí)
                                    HashSet<String> set = new HashSet<String>();
                                    set.add(bean.getName());
                                    clientBean.setClients(set);  //文件來(lái)源
                                    clientBean.setTo(bean.getClients());//給這些客戶發(fā)送文件
                                    sendMessage(clientBean);
                                    break;
                                }
                            }
                            };  
                        }.start();
                        break;
                    }
                    case 3: {  //目標(biāo)客戶愿意接收文件肪获,源客戶開(kāi)始讀取本地文件并發(fā)送到網(wǎng)絡(luò)上
                        textArea.append(bean.getTimer() + "  "+ bean.getName() + "確定接收文件" + ",文件傳送中..\r\n");//在聊天面板顯示信息
                        new Thread(){
                            public void run() {
                                
                                try {
                                    isSendFile = true;
                                    //創(chuàng)建要接收文件的客戶套接字
                                    Socket s = new Socket(bean.getIp(),bean.getPort());
                                    DataInputStream dis = new DataInputStream(
                                            new FileInputStream(filePath));  //本地讀取該客戶剛才選中的文件
                                    DataOutputStream dos = new DataOutputStream(
                                            new BufferedOutputStream(s
                                                    .getOutputStream()));  //網(wǎng)絡(luò)寫(xiě)出文件
                                    int size = dis.available();
                                    
                                    int count = 0;  //讀取次數(shù)
                                    int num = size / 100;
                                    int index = 0;
                                    while (count < size) {
                                        
                                        int t = dis.read();
                                        dos.write(t);
                                        count++;  //每次只讀取一個(gè)字節(jié)
                                        //顯示傳輸進(jìn)度
                                        if(num>0){
                                            if (count % num == 0 && index < 100) {
                                                progressBar.setValue(++index);
    
                                            }
                                            
                                            lblNewLabel.setText("上傳進(jìn)度:" + count + "/"
                                                            + size + "  整體" + index
                                                            + "%");
                                        }else{
                                            lblNewLabel.setText("上傳進(jìn)度:" + count + "/"
                                                    + size +"  整體:"+new Double(new Double(count).doubleValue()/new Double(size).doubleValue()*100).intValue()+"%"
                                                    );
                                            if(count==size){
                                                progressBar.setValue(100);
                                            }
                                        }
                                    }
                                    dos.flush();
                                    dis.close();
                                  //讀取目標(biāo)客戶的提示保存完畢的信息
                                    BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
                                    textArea.append( br.readLine() + "\r\n");
                                    isSendFile = false;
                                    br.close();
                                    s.close();
                                } catch (Exception ex) {
                                    ex.printStackTrace();
                                }
                            
                            };
                        }.start();
                        break;
                    }
                    case 4: {
                        textArea.append(bean.getInfo() + "\r\n");
                        break;
                    }
                    default: {
                        break;
                    }
                    }
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (clientSocket != null) {
                    try {
                        clientSocket.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
                System.exit(0);
            }
        }
    }
/**
 * 傳輸信息方法
 * @param clientBean
 */
    private void sendMessage(CatBean clientBean) {
        try {
            oos = new ObjectOutputStream(clientSocket.getOutputStream());
            oos.writeObject(clientBean);
            oos.flush();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

CatLogin

用于實(shí)現(xiàn)登錄


import java.awt.Color;
import java.awt.Cursor;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.sql.Connection;
import java.sql.DriverManager;
//import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
/**
 * 登錄界面窗口
 * 實(shí)現(xiàn)用戶登錄功能
 * @author DH
 *
 */
public class CatLogin extends JFrame {
    private static final long serialVersionUID = 1L;
    private JButton btnNewButton;
    private JButton btnNewButton_1;
    private JLabel lblNewLabel;
    private JPanel contentPane;
    private JTextField textField;
    private JPasswordField passwordField;
    public static HashMap<String, ClientBean> onlines;
    boolean loginCheck = false;
    boolean exist = false;
    boolean valid = false;
    boolean regsuccess = false;
    // MySQL URL declaration
    final String URL = "jdbc:mysql://localhost:3306/sys?useSSL=true";
    final String USERNAME = "root";
    final String PASSWORD = "123456";
    private Connection conn = null;
    private Statement state = null;
    
    /**
     * Launch the application.
     * 
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    // 啟動(dòng)登陸界面
                    CatLogin frame = new CatLogin();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public CatLogin() {
        
        setTitle("聊天室登錄界面");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(472, 235, 967, 681);

        contentPane = new JPanel() {
            private static final long serialVersionUID = 1L;
            @Override//鋪設(shè)背景圖片
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawImage(new ImageIcon(
                        "images/圖片1.png").getImage(), 0,
                        0, getWidth(), getHeight(), null);
            }
        };
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);
        
        //用戶名輸入框
        textField = new JTextField();
        textField.setFont(new Font( "Serif", 1, 25));//設(shè)置字體
        textField.setBounds(197, 376, 190, 50);
        textField.setOpaque(false);//此方法是設(shè)置控件是否透明的。true表示不透明虹蒋,false表示透明。文本區(qū)域設(shè)為透明
        contentPane.add(textField);
        textField.setColumns(10);
        
        //密碼輸入框
        passwordField = new JPasswordField();
        passwordField.setFont(new Font( "Serif", 1, 25));//設(shè)置字體
        passwordField.setEchoChar('*');//設(shè)置顯示字符
        passwordField.setOpaque(false);//文本區(qū)域設(shè)為透明
        passwordField.setBounds(197, 464, 190, 50);
        contentPane.add(passwordField);
        
        //登錄按鈕
        btnNewButton = new JButton();
        btnNewButton.setIcon(new ImageIcon("images\\登錄1.png"));//設(shè)置圖標(biāo)背景
        btnNewButton.setBounds(459, 537, 108, 54);
        btnNewButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));//設(shè)置鼠標(biāo)在該區(qū)域顯示狀態(tài)變化
        getRootPane().setDefaultButton(btnNewButton);//設(shè)置回車(chē)響應(yīng)
        contentPane.add(btnNewButton);
        
        //注冊(cè)按鈕
        btnNewButton_1 = new JButton();
        btnNewButton_1.setIcon(new ImageIcon("images\\圖片2.png"));//設(shè)置圖標(biāo)背景
        btnNewButton_1.setBounds(773, 276, 111, 56);
        btnNewButton_1.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));//設(shè)置鼠標(biāo)在該區(qū)域顯示狀態(tài)變化
        contentPane.add(btnNewButton_1);

        // 提示信息
        lblNewLabel = new JLabel();
        lblNewLabel.setBounds(220, 521, 190, 30);
        lblNewLabel.setFont(new Font("Dialog", 1,  15));
        lblNewLabel.setForeground(Color.red);
        contentPane.add(lblNewLabel);

        // 監(jiān)聽(tīng)登陸按鈕
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
            String u_name = textField.getText();//獲取用戶輸入的用戶名    
            String u_pwd = new String(passwordField.getPassword());//獲取用戶輸入的密碼
            try {
                //調(diào)用用戶登錄方法
                LoginDatabase(u_name, u_pwd);
                
            } catch (SQLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
                
                
            }
        });

        //注冊(cè)按鈕監(jiān)聽(tīng)
        btnNewButton_1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                btnNewButton_1.setEnabled(false);
                CatResign frame = new CatResign();
                frame.setVisible(true);// 顯示注冊(cè)界面
                setVisible(false);// 隱藏掉登陸界面
                
            }
        });
    }
/**
 * 登錄數(shù)據(jù)庫(kù)方法哲银,傳入用戶名和用戶密碼
 * @param u_name 
 * @param u_pwd
 * @throws SQLException
 */
    protected void LoginDatabase(String u_name, String u_pwd) throws SQLException {
        ResultSet result = null;
        try {
            // 連接到MySQL
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            state = conn.createStatement();
            // 從MySQL中讀取數(shù)據(jù)
            result = state.executeQuery("SELECT * FROM test WHERE `name` =" + "'" + u_name + "'");
            // 檢查用戶名是否存在
            if (result.next()) {
                // 進(jìn)行數(shù)據(jù)比對(duì)
                if (result.getString(1).equals(u_name)) {
                    if (result.getString(2).equals(u_pwd)) {
                        
                        try {
                            Socket client = new Socket("localhost", 8520);//建立端口號(hào)連接

                            btnNewButton.setEnabled(false);
                            CatChatroom frame = new CatChatroom(u_name,
                                    client);
                            frame.setVisible(true);// 顯示聊天界面
                            this.setVisible(false);// 隱藏掉登陸界面

                        } catch (UnknownHostException e1) {
                            
                            errorTip("The connection with the server is interrupted, please login again");
                        } catch (IOException e1) {

                            errorTip("The connection with the server is interrupted, please login again");
                        }
                        
                    }else{
                        //給出用戶提示信息草巡,并清空信息欄
                        lblNewLabel.setText("您輸入的密碼有誤!");
                        textField.setText("");
                        passwordField.setText("");
                        textField.requestFocus();
                    }
                }else{
                    //給出用戶提示信息玛迄,并清空信息欄
                    lblNewLabel.setText("您輸入昵稱不存在讥蟆!");
                    textField.setText("");
                    passwordField.setText("");
                    textField.requestFocus();
                }
            }

        } catch (SQLException ex) {
            System.out.println("SQLException:" + ex.getMessage());
            System.out.println("SQLState:" + ex.getSQLState());
            System.out.println("VendorError:" + ex.getErrorCode());
        } catch (ClassNotFoundException ex) {
            System.out.println("Not Found:" + ex.toString());
        }finally {
            
        }
    }
    
    protected void errorTip(String str) {
        // TODO Auto-generated method stub
        //顯示錯(cuò)誤信息,清空信息欄
        JOptionPane.showMessageDialog(contentPane, str, "Error Message",
                JOptionPane.ERROR_MESSAGE);
        textField.setText("");
        passwordField.setText("");
        textField.requestFocus();
    }
}

CatResign

實(shí)現(xiàn)新用戶注冊(cè)

import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
/**
 * 注冊(cè)界面
 * @author DH
 *
 */

public class CatResign extends JFrame {
    //界面基礎(chǔ)組件
    private JPanel contentPane;
    private JTextField textField;
    private JPasswordField passwordField;
    private JPasswordField passwordField_1;
    private JLabel lblNewLabel;
    private JButton btnNewButton_1;
    private JButton btnNewButton;
    
    //數(shù)據(jù)庫(kù)信息
    final String URL = "jdbc:mysql://localhost:3306/sys?useSSL=true";
    final String USERNAME = "root";
    final String PASSWORD = "123456";
    private Connection conn = null;
    private Statement state = null;
    private PreparedStatement ptmt = null;
/**
 * 初始化注冊(cè)界面
 */
    public CatResign() {
        setTitle("聊天室注冊(cè)界面");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(560, 300, 700,500);
        contentPane = new JPanel() {
            private static final long serialVersionUID = 1L;

            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                //加載背景圖片
                g.drawImage(new ImageIcon("images\\注冊(cè)頁(yè)面2.png").getImage(), 0,0, getWidth(), getHeight(), null);
            }
        };
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);
        
        //用戶名輸入框
        textField = new JTextField();
        textField.setBounds(260, 162, 170, 38);
        textField.setOpaque(false);//文本區(qū)域設(shè)為透明
        contentPane.add(textField);
        textField.setColumns(10);
        
        //密碼輸入框
        passwordField = new JPasswordField();
        passwordField.setEchoChar('*');
        passwordField.setOpaque(false);//文本區(qū)域設(shè)為透明
        passwordField.setBounds(257, 238, 174, 37);
        contentPane.add(passwordField);
        
        //密碼確認(rèn)輸入框
        passwordField_1 = new JPasswordField();
        passwordField_1.setBounds(255, 301, 180, 41);
        passwordField_1.setOpaque(false);//文本區(qū)域設(shè)為透明
        contentPane.add(passwordField_1);

        //注冊(cè)按鈕
        btnNewButton_1 = new JButton();
        btnNewButton_1.setIcon(new ImageIcon("images\\注冊(cè)1.jpg"));//加圖標(biāo)
        btnNewButton_1.setBounds(446, 376, 86, 46);
        btnNewButton_1.setContentAreaFilled(false);
        btnNewButton_1.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));//設(shè)置鼠標(biāo)在該區(qū)域顯示狀態(tài)變化
        contentPane.add(btnNewButton_1);

        //返回按鈕
        btnNewButton = new JButton("");
        btnNewButton.setBounds(311, 374, 83, 48);
        btnNewButton.setContentAreaFilled(false);
        btnNewButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));//設(shè)置鼠標(biāo)在該區(qū)域顯示狀態(tài)變化
        contentPane.add(btnNewButton);

        //提示信息
        lblNewLabel = new JLabel();
        lblNewLabel.setBounds(260, 125, 170, 38);
        lblNewLabel.setFont(new Font("SimSun", Font.BOLD, 17));
        lblNewLabel.setForeground(Color.red);
        contentPane.add(lblNewLabel);
        
        //返回按鈕監(jiān)聽(tīng)
        btnNewButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                btnNewButton.setEnabled(false);
                //返回登陸界面
                CatLogin frame = new CatLogin();
                frame.setVisible(true);//顯示登錄界面
                setVisible(false);//隱藏注冊(cè)界面
            }
        });
        
        //注冊(cè)按鈕監(jiān)聽(tīng)
        btnNewButton_1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //獲取用戶輸入的信息
                String u_name = textField.getText();
                String u_pwd = new String(passwordField.getPassword());
                String u_pwd_ag = new String(passwordField_1.getPassword());
                try {
                    //調(diào)用注冊(cè)方法進(jìn)行用戶注冊(cè)
                    Registerer(u_name ,u_pwd,u_pwd_ag);
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
            }}
        );
    }
    /**
     * 注冊(cè)方法
     * @param username
     * @param password
     * @param confirm
     * @throws SQLException
     */
    protected void Registerer(String username, String password, String confirm) throws SQLException {
        ResultSet result = null;
        try {
            // 連接到數(shù)據(jù)庫(kù)
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            state = conn.createStatement();
            // Check if password is correctly set
            if (username.length() != 0) {
                //判斷兩輸入次密碼是否一致
                if (password.equals(confirm)) {
                    
                    result = state.executeQuery("SELECT * FROM test WHERE `name` =" + "'" + username + "'");
                    if (result.next()) {
                        //檢測(cè)是否用戶名已存在
                        if (result.getString(1).equals(username)) {
                            lblNewLabel.setText("用戶名已存在!");
                        }
                    } else {
                        // 將信息寫(xiě)入到數(shù)據(jù)庫(kù)
                        ptmt = conn.prepareStatement("INSERT INTO test ( name , keyword ) VALUES ( ? , ? )");
                        ptmt.setString(1, username);
                        ptmt.setString(2, password);
                        int check = ptmt.executeUpdate();
                        // 檢查數(shù)據(jù)庫(kù)注冊(cè)是否成功
                        if (check > 0){
                            btnNewButton_1.setEnabled(false);
                            //返回登陸界面
                            CatLogin frame = new CatLogin();
                            frame.setVisible(true);//顯示登錄界面
                            setVisible(false);//隱藏注冊(cè)界面
                        }
                    }
                }else{
                    lblNewLabel.setText("密碼不一致!");
                    }
            }else{
                lblNewLabel.setText("密碼不能為空瘟则!");
            }
        } catch (SQLException ex) {
            System.out.println("SQLException:" + ex.getMessage());
            System.out.println("SQLState:" + ex.getSQLState());
            System.out.println("VendorError:" + ex.getErrorCode());
        } catch (ClassNotFoundException ex) {
            System.out.println("Not Found:" + ex.toString());
        }
    }
}

CatServer

服務(wù)器程序


import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;


/**
 * 服務(wù)器端,用于接受發(fā)送各種數(shù)據(jù)
 * @author DH
 *
 */
public class CatServer {
    private static ServerSocket ss;
    public static HashMap<String, ClientBean> onlines;
    static {
        try {
            //建立端口號(hào)
            ss = new ServerSocket(8520);
            onlines = new HashMap<String, ClientBean>();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
/**
 * 線程內(nèi)部類
 * @author HP
 *
 */
    class CatClientThread extends Thread {
        private Socket client;
        private CatBean bean;
        private ObjectInputStream ois;
        private ObjectOutputStream oos;

        public CatClientThread(Socket client) {
            this.client = client;
        }

        @Override
        public void run() {
            try {
                // 不停的從客戶端接收信息
                while (true) {
                    ois = new ObjectInputStream(client.getInputStream());//獲取輸入流
                    bean = (CatBean)ois.readObject();// 讀取從客戶端接收到的catbean信息
                    
                    // 對(duì)catbean中的類型進(jìn)行分析,分別作出回應(yīng)
                    switch (bean.getType()) {
                    // 上下線更新
                    case 0: { // 上線
                        // 記錄上線客戶的用戶名和端口在clientbean中
                        ClientBean cbean = new ClientBean();
                        cbean.setName(bean.getName());
                        cbean.setSocket(client);
                        // 用戶列表中添加在線用戶
                        onlines.put(bean.getName(), cbean);
                        // 創(chuàng)建服務(wù)器的catbean,并發(fā)送給客戶端
                        CatBean serverBean = new CatBean();
                        serverBean.setType(0);
                        serverBean.setInfo(bean.getTimer() + "  "
                                + bean.getName() + "上線了");//設(shè)置在聊天面板顯示的上線提示
                        // 給所有在線用戶發(fā)出有人上線消息
                        HashSet<String> set = new HashSet<String>();
                        set.addAll(onlines.keySet());//刷新在線用戶列表
                        serverBean.setClients(set);
                        sendAll(serverBean);
                        break;
                    }
                    case -1: { // 下線
                        // 創(chuàng)建服務(wù)器的catbean策幼,并發(fā)送給客戶端
                        CatBean serverBean = new CatBean();
                        serverBean.setType(-1);

                        try {
                            oos = new ObjectOutputStream(
                                    client.getOutputStream());
                            oos.writeObject(serverBean);
                            oos.flush();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        //移除下線用戶
                        onlines.remove(bean.getName());

                        // 向剩下的在線用戶發(fā)送有人離開(kāi)的通知
                        CatBean serverBean2 = new CatBean();
                        serverBean2.setInfo(bean.getTimer() + "  "
                                + bean.getName() + " " + " 下線了");//下線信息
                        serverBean2.setType(0);
                        HashSet<String> set = new HashSet<String>();
                        set.addAll(onlines.keySet());
                        serverBean2.setClients(set);

                        sendAll(serverBean2);
                        return;
                    }
                    case 1: { // 聊天
                        
//                       創(chuàng)建服務(wù)器的catbean唐含,并發(fā)送給客戶端
                        CatBean serverBean = new CatBean();

                        serverBean.setType(1);
                        serverBean.setClients(bean.getClients());
                        serverBean.setInfo(bean.getInfo());
                        serverBean.setName(bean.getName());
                        serverBean.setTimer(bean.getTimer());
                        // 向選中的客戶發(fā)送數(shù)據(jù)
                        sendMessage(serverBean);
                        break;
                    }
                    case 2: { // 請(qǐng)求接受文件
                        // 創(chuàng)建服務(wù)器的catbean件缸,并發(fā)送給客戶端
                        CatBean serverBean = new CatBean();
                        String info = bean.getTimer() + "  " + bean.getName()
                                + "向你傳送文件,是否需要接受";

                        serverBean.setType(2);
                        serverBean.setClients(bean.getClients()); // 這是發(fā)送的目的地
                        serverBean.setFileName(bean.getFileName()); // 文件名稱
                        serverBean.setSize(bean.getSize()); // 文件大小
                        serverBean.setInfo(info);//提示信息內(nèi)容
                        serverBean.setName(bean.getName()); // 來(lái)源
                        serverBean.setTimer(bean.getTimer());
                        // 向選中的客戶發(fā)送數(shù)據(jù)
                        sendMessage(serverBean);

                        break;
                    }
                    case 3: { // 確定接收文件
                        CatBean serverBean = new CatBean();

                        serverBean.setType(3);
                        serverBean.setClients(bean.getClients()); // 文件來(lái)源
                        serverBean.setTo(bean.getTo()); // 文件目的地
                        serverBean.setFileName(bean.getFileName()); // 文件名稱
                        serverBean.setIp(bean.getIp());
                        serverBean.setPort(bean.getPort());
                        serverBean.setName(bean.getName()); // 接收的客戶名稱
                        serverBean.setTimer(bean.getTimer());
                        // 通知文件來(lái)源的客戶痊末,對(duì)方確定接收文件
                        sendMessage(serverBean);
                        break;
                    }
                    case 4: {
                        CatBean serverBean = new CatBean();

                        serverBean.setType(4);
                        serverBean.setClients(bean.getClients()); // 文件來(lái)源
                        serverBean.setTo(bean.getTo()); // 文件目的地
                        serverBean.setFileName(bean.getFileName());
                        serverBean.setInfo(bean.getInfo());
                        serverBean.setName(bean.getName());// 接收的客戶名稱
                        serverBean.setTimer(bean.getTimer());
                        sendMessage(serverBean);

                        break;
                    }
                    default: {
                        break;
                    }
                    }
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                close();
            }
        }

/**
* 向用戶發(fā)送數(shù)據(jù)
* @param serverBean
*/
        private void sendMessage(CatBean serverBean) {
            // 首先取得所有的values
            Set<String> cbs = onlines.keySet();
            Iterator<String> it = cbs.iterator();
            // 選中客戶
            HashSet<String> clients = serverBean.getClients();
            while (it.hasNext()) {
                // 在線客戶
                String client = it.next();
                // 選中的客戶中若是在線的盒件,就發(fā)送serverbean
                if (clients.contains(client)) {
                    Socket c = onlines.get(client).getSocket();
                    ObjectOutputStream oos;
                    try {
                        oos = new ObjectOutputStream(c.getOutputStream());
                        oos.writeObject(serverBean);
                        oos.flush();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                }
            }
        }

/**
 * 向所有用戶發(fā)送數(shù)據(jù)
 * @param serverBean
 */
        public void sendAll(CatBean serverBean) {
            Collection<ClientBean> clients = onlines.values();
            Iterator<ClientBean> it = clients.iterator();
            ObjectOutputStream oos;
            while (it.hasNext()) {
                Socket c = it.next().getSocket();
                try {
                    //進(jìn)行數(shù)據(jù)傳送
                    oos = new ObjectOutputStream(c.getOutputStream());
                    oos.writeObject(serverBean);
                    oos.flush();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
/**
 * 關(guān)閉各種流
 */
        private void close() {
            if (oos != null) {
                try {
                    oos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (ois != null) {
                try {
                    ois.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (client != null) {
                try {
                    client.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    public void start() {
        try {
            //不停接受來(lái)自客戶端的請(qǐng)求
            while (true) {
                //建立連接罗心,線程處理
                Socket client = ss.accept();
                new CatClientThread(client).start();
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
/**
 * 主方法
 * @param args
 */
    public static void main(String[] args) {
        new CatServer().start();
    }

}

CatUtil

可以用來(lái)封裝一些使用方法

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Properties;
/**
 * 方法類
 * @author DH
 *
 */
public class CatUtil {
    @SuppressWarnings("unused")
    public static String getTimer() {
        //獲取時(shí)間格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(new Date());
    }
    
}

ClientBean

import java.net.Socket;

public class ClientBean {
    private String name;
    private Socket socket;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Socket getSocket() {
        return socket;
    }

    public void setSocket(Socket socket) {
        this.socket = socket;
    }
}


GreedSnake

貪吃蛇代碼的實(shí)現(xiàn)


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

//Main Class

public class GreedSnake extends KeyAdapter {

    JFrame mainFrame;

    Canvas paintCanvas;

    JLabel labelScore;// 計(jì)分牌

    SnakeModel snakeModel = null;// 蛇

    public static final int DEFAULT_WIDTH = 500;

    public static final int DEFAULT_HEIGHT = 300;

    public static final int nodeWidth = 10;

    public static final int nodeHeight = 10;
    
    

    // GreedSnake():初始化游戲界面

    public GreedSnake() {
        
        // 設(shè)置界面元素
        mainFrame = new JFrame("貪吃蛇游戲");
        Container cp = mainFrame.getContentPane();
        mainFrame.setBounds(600,400,400,300);
        //得分牌
        labelScore = new JLabel("所得分?jǐn)?shù)為:", JLabel.CENTER);
        cp.add(labelScore, BorderLayout.NORTH);
        //畫(huà)布
        paintCanvas = new Canvas();
        paintCanvas.setSize(DEFAULT_WIDTH + 1, DEFAULT_HEIGHT + 1);
        paintCanvas.addKeyListener(this);
        cp.add(paintCanvas, BorderLayout.CENTER);
        JPanel panelButtom = new JPanel();
        panelButtom.setLayout(new BorderLayout());
        JLabel labelHelp;
        // 幫助信息
        labelHelp = new JLabel("按 PageUP 或 PageDown 鍵改變速度", JLabel.CENTER);
        panelButtom.add(labelHelp, BorderLayout.NORTH);
        labelHelp = new JLabel("按 Enter 或 S 鍵重新開(kāi)始游戲", JLabel.CENTER);
        panelButtom.add(labelHelp, BorderLayout.CENTER);
        labelHelp = new JLabel("按 SPACE 鍵或 P 鍵暫停游戲", JLabel.CENTER);
        panelButtom.add(labelHelp, BorderLayout.SOUTH);
        cp.add(panelButtom, BorderLayout.SOUTH);
        mainFrame.addKeyListener(this);
        mainFrame.pack();
        mainFrame.setResizable(false);// 設(shè)置窗口大小不能變化
        //窗口監(jiān)聽(tīng)器
        mainFrame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e){
                snakeModel.s.stop();
                mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            }
        });
        mainFrame.setVisible(true);
        begin();
        
    }
    
    // keyPressed():按鍵檢測(cè)

    public void keyPressed(KeyEvent e) {

        int keyCode = e.getKeyCode();//得到按鍵的值
        
        if (snakeModel.running)//在蛇運(yùn)動(dòng)時(shí)生效
            switch ( e.getKeyCode()) {
            //改變方向
            case KeyEvent.VK_UP:
                snakeModel.changeDirection(SnakeModel.UP);
                break;
            case KeyEvent.VK_DOWN:
                snakeModel.changeDirection(SnakeModel.DOWN);
                break;
            case KeyEvent.VK_LEFT:
                snakeModel.changeDirection(SnakeModel.LEFT);
                break;
            case KeyEvent.VK_RIGHT:
                snakeModel.changeDirection(SnakeModel.RIGHT);
                break;
            //改變速度
            case KeyEvent.VK_ADD:
            case KeyEvent.VK_PAGE_UP:
                snakeModel.speedUp();// 加速
                break;
            case KeyEvent.VK_SUBTRACT:
            case KeyEvent.VK_PAGE_DOWN:
                snakeModel.speedDown();// 減速
                break;
            //改變暫筒购叮或繼續(xù)狀態(tài)
            case KeyEvent.VK_SPACE:
            case KeyEvent.VK_P:
                snakeModel.changePauseState();// 暫停或繼續(xù)
                break;
            default:
            }
        // 重新開(kāi)始
        if (keyCode == KeyEvent.VK_S || keyCode == KeyEvent.VK_ENTER) {
            snakeModel.running = false;
            begin();
        }
    }

    // repaint():繪制游戲界面(包括蛇和食物)

    void repaint() {
        
    
        Graphics g = paintCanvas.getGraphics();
        // 加載背景
        g.drawImage(new ImageIcon("images\\q1.jpg").getImage(), 0, 0,
                DEFAULT_WIDTH, DEFAULT_HEIGHT, null);
        // 畫(huà)出蛇
        g.setColor(Color.BLACK);
        LinkedList<Node> na = snakeModel.nodeArray;
        Iterator<Node> it = na.iterator();
        
        while (it.hasNext()) {
            Node n = (Node) it.next();
            drawNode(g, n);
        }
        // 畫(huà)出食物
        g.setColor(Color.RED);
        Node n = snakeModel.food;
        drawNode(g, n);
        updateScore();
    }

    // drawNode():繪畫(huà)某一結(jié)點(diǎn)(蛇身或食物)

    private void drawNode(Graphics g, Node n) {
        g.fillRect(n.x * nodeWidth, n.y * nodeHeight, nodeWidth - 1, nodeHeight - 1);
    }

    // updateScore():改變計(jì)分牌

    public void updateScore() {
        String s = "所得分?jǐn)?shù)為: " + snakeModel.score;
        labelScore.setText(s);//將得分設(shè)置到得分版
    }

    // begin():游戲開(kāi)始削饵,放置貪吃蛇

    void begin() {

        if (snakeModel == null || !snakeModel.running) {
            //啟動(dòng)貪吃蛇
            snakeModel = new SnakeModel(this, DEFAULT_WIDTH / nodeWidth, DEFAULT_HEIGHT / nodeHeight);
            (new Thread(snakeModel)).start();
        }
    }
    


    
}

/**
 * 節(jié)點(diǎn)類
 * @author HP
 *
 */
class Node {
    int x;

    int y;
//初始化
    Node(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

/**
 * SnakeModel:貪吃蛇模型
 * 
 */ 

class SnakeModel implements Runnable {

    GreedSnake gs;

    boolean[][] matrix;// 界面數(shù)據(jù)保存在數(shù)組里

    LinkedList<Node> nodeArray = new LinkedList<Node>();

    Node food;

    int maxX;// 最大寬度

    int maxY;// 最大長(zhǎng)度

    int direction = 2;// 方向

    boolean running = false;

    int timeInterval = 200;// 間隔時(shí)間(速度)

    double speedChangeRate = 0.75;// 速度改變程度

    boolean paused = false;// 游戲狀態(tài)

    int score = 0;

    int countMove = 0;

    // UP和DOWN是偶數(shù)岩瘦,RIGHT和LEFT是奇數(shù)
    public static final int UP = 2;

    public static final int DOWN = 4;

    public static final int LEFT = 1;

    public static final int RIGHT = 3;
    
    Sound s=new Sound();

    
    // 初始化界面

    public SnakeModel(GreedSnake gs, int maxX, int maxY) {

        this.gs = gs;
        this.maxX = maxX;
        this.maxY = maxY;
        matrix = new boolean[maxX][];
        for (int i = 0; i < maxX; ++i) {
            matrix[i] = new boolean[maxY];
            Arrays.fill(matrix[i], false);// 沒(méi)有蛇和食物的地區(qū)置false
        }
        // 初始化貪吃蛇
        int initArrayLength = maxX > 20 ? 10 : maxX / 2;
        for (int i = 0; i < initArrayLength; ++i) {
            int x = maxX / 2 + i;
            int y = maxY / 2;
            nodeArray.addLast(new Node(x, y));
            matrix[x][y] = true;// 蛇身處置true
        }
        food = createFood();
        matrix[food.x][food.y] = true;// 食物處置true
    }

    // 改變運(yùn)動(dòng)方向

    public void changeDirection(int newDirection) {
        //上與下都為偶數(shù),左與右都為奇數(shù)窿撬,若方向的值除以2的余數(shù)相等启昧,則方向沖突
        if (direction % 2 != newDirection % 2) {// 避免沖突
            direction = newDirection;
        }
    }

    // 貪吃蛇運(yùn)動(dòng)函數(shù)

    public boolean moveOn() {

        Node n = (Node) nodeArray.getFirst();//頭node確定方向
        int x = n.x;
        int y = n.y;
        //頭node的移動(dòng)
        switch (direction) {
        case UP:
            y--;
            break;
        case DOWN:
            y++;
            break;
        case LEFT:
            x--;
            break;
        case RIGHT:
            x++;
            break;
        }
        
        if ((0 <= x && x < maxX) && (0 <= y && y < maxY)) {

            if (matrix[x][y]) {// 吃到食物或者撞到身體

                if (x == food.x && y == food.y) {// 吃到食物

                    nodeArray.addFirst(food);// 在頭部加上一結(jié)點(diǎn)
                    // 計(jì)分規(guī)則與移動(dòng)長(zhǎng)度和速度有關(guān)
                    int scoreGet = (10000 - 200 * countMove) / timeInterval;
                    score += (scoreGet > 0 ? scoreGet : 10);
                    countMove = 0;
                    food = createFood();
                    matrix[food.x][food.y] = true;
                    return true;
                } else
                    return false;// 撞到身體
            } else {// 什么都沒(méi)有碰到
                nodeArray.addFirst(new Node(x, y));// 加上頭部
                matrix[x][y] = true;
                n = (Node) nodeArray.removeLast();// 去掉尾部
                matrix[n.x][n.y] = false;
                countMove++;
                return true;
            }
        }
        return false;// 越界(撞到墻壁)
    }

    // run():貪吃蛇運(yùn)動(dòng)線程
    
    public void run() {
        running = true;
        
        s.play();
        while (running) {
            
            try {
                Thread.sleep(timeInterval);
            } catch (Exception e) {
                s.stop();
                break;
            }
            if (!paused) {

                if (moveOn()) {// 未結(jié)束
                    gs.repaint();
                } else {// 游戲結(jié)束
                    s.stop();
                    JOptionPane.showMessageDialog(null, "GAME OVER", "Game Over", JOptionPane.INFORMATION_MESSAGE);
                    break;
                }
            }else{
//              s.stop();
            }
        }
        running = false;
    }

    // createFood():生成食物及放置地點(diǎn)

    private Node createFood() {

        int x = 0;
        int y = 0;
        do {
            Random r = new Random();
            x = r.nextInt(maxX);
            y = r.nextInt(maxY);
        } while (matrix[x][y]);
        return new Node(x, y);
    }

    // speedUp():加快蛇運(yùn)動(dòng)速度

    public void speedUp() {
        timeInterval *= speedChangeRate;
    }

    // speedDown():放慢蛇運(yùn)動(dòng)速度

    public void speedDown() {

        timeInterval /= speedChangeRate;
    }

    // changePauseState(): 改變游戲狀態(tài)(暫停或繼續(xù))

    public void changePauseState() {
        if(paused){
            s.play();
        }else{
            s.stop();
        }
        paused = !paused;
        
        
    }
    
}

Sound

封裝一些對(duì)聲音的處理方法

import java.applet.AudioClip;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.JApplet;

public class Sound{  
      AudioClip christmas = loadSound("sounds\\貪吃蛇.wav");
        public static AudioClip loadSound(String filename) {  
            URL url = null;  
           try {  
                url = new URL("file:" + filename);  
            }   
            catch (MalformedURLException e) {;}  
           return JApplet.newAudioClip(url);  
       }  
       public void play() {  
          
            christmas.loop();  
       }  
       public void stop() {  
         
            christmas.stop();  
       }  
      
}  


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末座柱,一起剝皮案震驚了整個(gè)濱河市惭蹂,隨后出現(xiàn)的幾起案子航缀,更是在濱河造成了極大的恐慌,老刑警劉巖敬辣,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異酝锅,居然都是意外死亡苛聘,警方通過(guò)查閱死者的電腦和手機(jī)拣宰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)堵第,“玉大人帆谍,你說(shuō)我怎么就攤上這事酪术。” “怎么了太惠?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵殴胧,是天一觀的道長(zhǎng)诱建。 經(jīng)常有香客問(wèn)我豹芯,道長(zhǎng)容诬,這世上最難降的妖魔是什么铅匹? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任萝快,我火速辦了婚禮,結(jié)果婚禮上杠巡,老公的妹妹穿的比我還像新娘量窘。我一直安慰自己,他們只是感情好氢拥,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布蚌铜。 她就那樣靜靜地躺著锨侯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪冬殃。 梳的紋絲不亂的頭發(fā)上囚痴,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音审葬,去河邊找鬼深滚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛涣觉,可吹牛的內(nèi)容都是我干的痴荐。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼官册,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼生兆!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起膝宁,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤鸦难,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后员淫,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體合蔽,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年介返,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了辈末。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡映皆,死狀恐怖挤聘,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情捅彻,我是刑警寧澤组去,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站步淹,受9級(jí)特大地震影響从隆,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜缭裆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一键闺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧澈驼,春花似錦辛燥、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)徘六。三九已至,卻和暖如春榴都,著一層夾襖步出監(jiān)牢的瞬間待锈,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工嘴高, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留竿音,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓拴驮,卻偏偏與公主長(zhǎng)得像春瞬,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子莹汤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,743評(píng)論 25 707
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法快鱼,類相關(guān)的語(yǔ)法颠印,內(nèi)部類的語(yǔ)法纲岭,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法线罕,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,598評(píng)論 18 399
  • 不體諒世事艱澀的我 不體諒你的不易 花開(kāi)并蒂 泉水嗚咽心語(yǔ) 不體諒飯食的來(lái)之不易 不體諒你教我規(guī)矩做人的用意 滄桑...
    翔于閱讀 291評(píng)論 0 1
  • 我此行的目的是什么止潮? 把課程推廣到那里 嗯,然后呢钞楼? 我就可以在那里開(kāi)課了 這是你想要的嗎喇闸? 算是吧! 為什么你回...
    Sadhya閱讀 234評(píng)論 2 3
  • iframe 和 jsonp jsonp的方式其實(shí)及類似于 一般情況下的ajax請(qǐng)求是這樣的: 但他是不能跨域的...
    HarryPang閱讀 487評(píng)論 0 0