github地址https://github.com/HWenTing/MyChatRoom
在学习了半年java基础知识后,在上学期我们完成了java课设,现在正好想起来,顺便整理一下。代码总行数约2400行,涉及知识:java基础,socket套接字连接,一部分与数据库连接知识,GUI,多线程,文件io等。代码部分参考过他人代码。
该课设主要包括登录,注册,聊天室,贪吃蛇,截屏五大板块。
大体界面就是这样子啦(原谅我的审美23333)
***
没错,总体就是这个样子的,以下附上代码,还有设计文档总结报告等,需要的小伙伴可以联系我哇~
CatBean
这个类主要用于封装
import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
public class CatBean implements Serializable {
private int type; // 1私聊 0上下线更新 -1下线请求 2请求发送文件 3.确定接收文件
private HashSet clients; // 存放选中的客户
private HashSet to;
public HashMap 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 getTo() {
return to;
}
public void setTo(HashSet to) {
this.to = to;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public HashSet getClients() {
return clients;
public void setClients(HashSet 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 getOnlines() {
return onlines;
}
public void setOnlines(HashMap onlines) {
this.onlines = onlines;
}
}
CatChatroom
聊天室的主页面,包含GUI与后台逻辑
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;
/**
* 用户列表中每个用户显示状态
* @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"));//设置头像
}
//设置用户被选中和为被选中两种前景与背景颜色状态表示
if (isSelected) {
//被选中时
setBackground(new Color(255, 255, 153));// 设置背景色
setForeground(Color.black);//设置字体色
} else {
//未被选中
setBackground(Color.white); // 设置背景色
setForeground(Color.black);//设置字体色
}
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");//改变窗口显示风格
} 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);
// 聊天信息显示区域
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(10, 10, 490, 510);
getContentPane().add(scrollPane);
//聊天信息显示框
textArea = new JTextArea();
textArea.setEditable(false);
textArea.setLineWrap(true);//激活自动换行功能
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);
// 打字区域
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);//激活自动换行功能
textArea_1.setWrapStyleWord(true);//激活断行不断字功能
textArea_1.setFont(new Font("sdf", Font.PLAIN, 18));
scrollPane_1.setViewportView(textArea_1);
// 关闭按钮
final JButton btnNewButton = new JButton("关闭");
btnNewButton.setBounds(270, 700, 100, 40);
getContentPane().add(btnNewButton);
// 发送按钮
JButton btnNewButton_1 = new JButton("发送");
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);
//贪吃蛇按钮增添事件监听
btnNewButton_2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 启动贪吃蛇小游戏
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);
//截屏按钮增添事件监听
btnNewButton_3.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Sreen ss=new Sreen();
//启动截屏功能
ss.doStart();
}
});
getContentPane().add(btnNewButton_3);
//清屏按钮
JButton btnNewButton_4 = new JButton("清屏");
btnNewButton_4.setBounds(414,523, 100, 34);
//增加时间监听
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));//标题栏设置
//在线用户滚动区域
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 它可以 简单地输出进度的变化情况
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中,并发送给服务器
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);
// 启动客户接收线程
new ClientInputThread().start();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 发送按钮事件监听
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String info = textArea_1.getText();
List to = list.getSelectedValuesList();//获取所选择对象
//若未选择对象
if (to.size() < 1) {
JOptionPane.showMessageDialog(getContentPane(), "请选择聊天对象");
return;
}
//若选择对象为自己
if (to.toString().contains(name+"(我)")) {
JOptionPane
.showMessageDialog(getContentPane(), "不能向自己发送信息");
return;
}
//若发送信息为空
if (info.equals("")) {
JOptionPane.showMessageDialog(getContentPane(), "不能发送空信息");
return;
}
//正常情况下,建立连接,发送数据
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);
// 自己发的内容也要现实在自己的屏幕上面
textArea.append(time + " 我对" + to + "说:\r\n" + info + "\r\n");
//将发送信息保存在本地文件中,作为聊天记录
try {
FileWriter fw=new FileWriter(contentFile,true);
BufferedWriter bw=new BufferedWriter(fw);
bw.write(time + "我对<" + to + ">说:\r\n" + info + "\r\n");
bw.close();
fw.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//清空发送消息栏并重新获取焦点
textArea_1.setText(null);
textArea_1.requestFocus();
}
});
// 关闭按钮事件监听
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//在文件传输时不能关闭窗口
if(isSendFile || isReceiveFile){
JOptionPane.showMessageDialog(contentPane,
"正在传输文件中,您不能离开...",
"Error Message", JOptionPane.ERROR_MESSAGE);
}else{
//发送下线消息
btnNewButton.setEnabled(false);
CatBean clientBean = new CatBean();
clientBean.setType(-1);
clientBean.setName(name);
clientBean.setTimer(CatUtil.getTimer());
sendMessage(clientBean);
}
}
});
// 窗口事件监听
this.addWindowListener(new WindowAdapter() {
@Override
//离开
public void windowClosing(WindowEvent e) {
// TODO Auto-generated method stub
if(isSendFile || isReceiveFile){
JOptionPane.showMessageDialog(contentPane,
"正在传输文件中,您不能离开...",
"Error Message", JOptionPane.ERROR_MESSAGE);
}else{
int result = JOptionPane.showConfirmDialog(getContentPane(),
"您确定要离开聊天室");//取得用户选择
//若用户选择确定离开,发送下线消息
if (result == 0) {
CatBean clientBean = new CatBean();
clientBean.setType(-1);
clientBean.setName(name);
clientBean.setTimer(CatUtil.getTimer());
sendMessage(clientBean);
}
}
}
});
// 在线用户列表监听
list.addMouseListener(new MouseAdapter() {
@Override//鼠标事件监听
public void mouseClicked(MouseEvent e) {
List to = list.getSelectedValuesList();
//双击事件代表发送文件
if (e.getClickCount() == 2) {
//如过发送对象为自己
if (to.toString().contains(name+"(我)")) {
JOptionPane
.showMessageDialog(getContentPane(), "不能向自己发送文件");
return;
}
// 双击打开文件文件选择框
JFileChooser chooser = new JFileChooser();
chooser.setDialogTitle("选择文件框"); // 标题
chooser.showDialog(getContentPane(), "选择"); // 按钮的名字
// 判定是否选择了文件
if (chooser.getSelectedFile() != null) {
// 获取路径
filePath = chooser.getSelectedFile().getPath();
File file = new File(filePath);
// 如果文件为空
if (file.length() == 0) {
JOptionPane.showMessageDialog(getContentPane(),
filePath + "文件为空,不允许发送.");
return;
}
//正常状态,建立连接,发送请求
CatBean clientBean = new CatBean();
clientBean.setType(2);// 请求发送文件
clientBean.setSize(new Long(file.length()).intValue());
clientBean.setName(name);
clientBean.setTimer(CatUtil.getTimer());
clientBean.setFileName(file.getName()); // 记录文件的名称
clientBean.setInfo("请求发送文件");
// 判断要发送给谁
HashSet set = new HashSet();
set.addAll(list.getSelectedValuesList());
clientBean.setClients(set);
sendMessage(clientBean);
}
}
}
});
}
/**
* 线程接收类
* @author HP
*
*/
class ClientInputThread extends Thread {
@Override
public void run() {
try {
// 不停的从服务器接收信息
while (true) {
ois = new ObjectInputStream(clientSocket.getInputStream());
final CatBean bean = (CatBean) ois.readObject();
//分析接受到catbean的类型
switch (bean.getType()) {
case 0: {
// 更新列表
onlines.clear();//清空列表
HashSet clients = bean.getClients();
Iterator 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: {
//获取发送信息
String info = bean.getTimer() + " " +bean.getName()
+ "对 " +bean.getClients() + "说:\r\n";
//将对方发送消息中自己的名字替换成“我”
if (info.contains(name) ) {
info = info.replace(name, "我");
}
aau.play();
textArea.append(info+bean.getInfo() + "\r\n");
//将对方发送的消息写入聊天记录中
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: {
// 由于等待目标客户确认是否接收文件是个阻塞状态,所以这里用线程处理
new Thread(){
public void run() {
//显示是否接收文件对话框
int result = JOptionPane.showConfirmDialog(
getContentPane(), bean.getInfo());
//对用户做出的选择做出反应
switch(result){
case 0:{ //接收文件
JFileChooser chooser = new JFileChooser();
chooser.setDialogTitle("保存文件框"); // 标题
//默认文件名称还有放在当前目录下
chooser.setSelectedFile(new File(bean
.getFileName()));
chooser.showDialog(getContentPane(), "保存"); // 设置按钮名字
//保存路径
String saveFilePath =chooser.getSelectedFile().toString();
//创建客户CatBean
CatBean clientBean = new CatBean();
clientBean.setType(3);
clientBean.setName(name); //接收文件的客户名字
clientBean.setTimer(CatUtil.getTimer());
clientBean.setFileName(saveFilePath);
clientBean.setInfo("确定接收文件");
// 判断要发送给谁
HashSet set = new HashSet();
set.add(bean.getName());
clientBean.setClients(set); //文件来源
clientBean.setTo(bean.getClients());//给这些客户发送文件
// 创建新的tcp socket 接收数据
try {
ServerSocket ss = new ServerSocket(0); // 0可以获取空闲的端口号
clientBean.setIp(clientSocket.getInetAddress().getHostAddress());
clientBean.setPort(ss.getLocalPort());
sendMessage(clientBean); // 先通过服务器告诉发送方, 你可以直接发送文件到我这里了
isReceiveFile=true;
//等待文件来源的客户,输送文件....目标客户从网络上读取文件,并写在本地上
Socket sk = ss.accept();
textArea.append(CatUtil.getTimer() + " " + bean.getFileName()
+ "文件保存中.\r\n");
DataInputStream dis = new DataInputStream( //从网络上读取文件
new BufferedInputStream(sk.getInputStream()));
DataOutputStream dos = new DataOutputStream( //写在本地上
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("下载进度:" + count
+ "/" + bean.getSize() + " 整体" + index
+ "%");
}else{
lblNewLabel.setText("下载进度:" + count
+ "/" + bean.getSize() +" 整体:"+new Double(new Double(count).doubleValue()/new Double(bean.getSize()).doubleValue()*100).intValue()+"%");
if(count==bean.getSize()){
progressBar.setValue(100);
}
}
}
//给文件来源客户发条提示,文件保存完毕
PrintWriter out = new PrintWriter(sk.getOutputStream(),true);
out.println(CatUtil.getTimer() + " 发送给"+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() + "]");
// 判断要发送给谁
HashSet set = new HashSet();
set.add(bean.getName());
clientBean.setClients(set); //文件来源
clientBean.setTo(bean.getClients());//给这些客户发送文件
sendMessage(clientBean);
break;
}
}
};
}.start();
break;
}
case 3: { //目标客户愿意接收文件,源客户开始读取本地文件并发送到网络上
textArea.append(bean.getTimer() + " "+ bean.getName() + "确定接收文件" + ",文件传送中..\r\n");//在聊天面板显示信息
new Thread(){
public void run() {
try {
isSendFile = true;
//创建要接收文件的客户套接字
Socket s = new Socket(bean.getIp(),bean.getPort());
DataInputStream dis = new DataInputStream(
new FileInputStream(filePath)); //本地读取该客户刚才选中的文件
DataOutputStream dos = new DataOutputStream(
new BufferedOutputStream(s
.getOutputStream())); //网络写出文件
int size = dis.available();
int count = 0; //读取次数
int num = size / 100;
int index = 0;
while (count < size) {
int t = dis.read();
dos.write(t);
count++; //每次只读取一个字节
//显示传输进度
if(num>0){
if (count % num == 0 && index < 100) {
progressBar.setValue(++index);
}
lblNewLabel.setText("上传进度:" + count + "/"
+ size + " 整体" + index
+ "%");
}else{
lblNewLabel.setText("上传进度:" + count + "/"
+ size +" 整体:"+new Double(new Double(count).doubleValue()/new Double(size).doubleValue()*100).intValue()+"%"
);
if(count==size){
progressBar.setValue(100);
}
}
}
dos.flush();
dis.close();
//读取目标客户的提示保存完毕的信息
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
用于实现登录
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;
/**
* 登录界面窗口
* 实现用户登录功能
* @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 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 {
// 启动登陆界面
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//铺设背景图片
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));//设置字体
textField.setBounds(197, 376, 190, 50);
textField.setOpaque(false);//此方法是设置控件是否透明的。true表示不透明,false表示透明。文本区域设为透明
contentPane.add(textField);
textField.setColumns(10);
//密码输入框
passwordField = new JPasswordField();
passwordField.setFont(new Font( "Serif", 1, 25));//设置字体
passwordField.setEchoChar('*');//设置显示字符
passwordField.setOpaque(false);//文本区域设为透明
passwordField.setBounds(197, 464, 190, 50);
contentPane.add(passwordField);
//登录按钮
btnNewButton = new JButton();
btnNewButton.setIcon(new ImageIcon("images\\登录1.png"));//设置图标背景
btnNewButton.setBounds(459, 537, 108, 54);
btnNewButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));//设置鼠标在该区域显示状态变化
getRootPane().setDefaultButton(btnNewButton);//设置回车响应
contentPane.add(btnNewButton);
//注册按钮
btnNewButton_1 = new JButton();
btnNewButton_1.setIcon(new ImageIcon("images\\图片2.png"));//设置图标背景
btnNewButton_1.setBounds(773, 276, 111, 56);
btnNewButton_1.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));//设置鼠标在该区域显示状态变化
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);
// 监听登陆按钮
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String u_name = textField.getText();//获取用户输入的用户名
String u_pwd = new String(passwordField.getPassword());//获取用户输入的密码
try {
//调用用户登录方法
LoginDatabase(u_name, u_pwd);
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
//注册按钮监听
btnNewButton_1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
btnNewButton_1.setEnabled(false);
CatResign frame = new CatResign();
frame.setVisible(true);// 显示注册界面
setVisible(false);// 隐藏掉登陆界面
}
});
}
/**
* 登录数据库方法,传入用户名和用户密码
* @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中读取数据
result = state.executeQuery("SELECT * FROM test WHERE `name` =" + "'" + u_name + "'");
// 检查用户名是否存在
if (result.next()) {
// 进行数据比对
if (result.getString(1).equals(u_name)) {
if (result.getString(2).equals(u_pwd)) {
try {
Socket client = new Socket("localhost", 8520);//建立端口号连接
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
//显示错误信息,清空信息栏
JOptionPane.showMessageDialog(contentPane, str, "Error Message",
JOptionPane.ERROR_MESSAGE);
textField.setText("");
passwordField.setText("");
textField.requestFocus();
}
}
CatResign
实现新用户注册
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;
/**
* 注册界面
* @author DH
*
*/
public class CatResign extends JFrame {
//界面基础组件
private JPanel contentPane;
private JTextField textField;
private JPasswordField passwordField;
private JPasswordField passwordField_1;
private JLabel lblNewLabel;
private JButton btnNewButton_1;
private JButton btnNewButton;
//数据库信息
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;
/**
* 初始化注册界面
*/
public CatResign() {
setTitle("聊天室注册界面");
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\\注册页面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);//文本区域设为透明
contentPane.add(textField);
textField.setColumns(10);
//密码输入框
passwordField = new JPasswordField();
passwordField.setEchoChar('*');
passwordField.setOpaque(false);//文本区域设为透明
passwordField.setBounds(257, 238, 174, 37);
contentPane.add(passwordField);
//密码确认输入框
passwordField_1 = new JPasswordField();
passwordField_1.setBounds(255, 301, 180, 41);
passwordField_1.setOpaque(false);//文本区域设为透明
contentPane.add(passwordField_1);
//注册按钮
btnNewButton_1 = new JButton();
btnNewButton_1.setIcon(new ImageIcon("images\\注册1.jpg"));//加图标
btnNewButton_1.setBounds(446, 376, 86, 46);
btnNewButton_1.setContentAreaFilled(false);
btnNewButton_1.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));//设置鼠标在该区域显示状态变化
contentPane.add(btnNewButton_1);
//返回按钮
btnNewButton = new JButton("");
btnNewButton.setBounds(311, 374, 83, 48);
btnNewButton.setContentAreaFilled(false);
btnNewButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));//设置鼠标在该区域显示状态变化
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);
//返回按钮监听
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
btnNewButton.setEnabled(false);
//返回登陆界面
CatLogin frame = new CatLogin();
frame.setVisible(true);//显示登录界面
setVisible(false);//隐藏注册界面
}
});
//注册按钮监听
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 {
//调用注册方法进行用户注册
Registerer(u_name ,u_pwd,u_pwd_ag);
} catch (SQLException e1) {
e1.printStackTrace();
}
}}
);
}
/**
* 注册方法
* @param username
* @param password
* @param confirm
* @throws SQLException
*/
protected void Registerer(String username, String password, String confirm) throws SQLException {
ResultSet result = null;
try {
// 连接到数据库
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()) {
//检测是否用户名已存在
if (result.getString(1).equals(username)) {
lblNewLabel.setText("用户名已存在!");
}
} else {
// 将信息写入到数据库
ptmt = conn.prepareStatement("INSERT INTO test ( name , keyword ) VALUES ( ? , ? )");
ptmt.setString(1, username);
ptmt.setString(2, password);
int check = ptmt.executeUpdate();
// 检查数据库注册是否成功
if (check > 0){
btnNewButton_1.setEnabled(false);
//返回登陆界面
CatLogin frame = new CatLogin();
frame.setVisible(true);//显示登录界面
setVisible(false);//隐藏注册界面
}
}
}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
服务器程序
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;
/**
* 服务器端,用于接受发送各种数据
* @author DH
*
*/
public class CatServer {
private static ServerSocket ss;
public static HashMap onlines;
static {
try {
//建立端口号
ss = new ServerSocket(8520);
onlines = new HashMap();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 线程内部类
* @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信息
// 对catbean中的类型进行分析,分别作出回应
switch (bean.getType()) {
// 上下线更新
case 0: { // 上线
// 记录上线客户的用户名和端口在clientbean中
ClientBean cbean = new ClientBean();
cbean.setName(bean.getName());
cbean.setSocket(client);
// 用户列表中添加在线用户
onlines.put(bean.getName(), cbean);
// 创建服务器的catbean,并发送给客户端
CatBean serverBean = new CatBean();
serverBean.setType(0);
serverBean.setInfo(bean.getTimer() + " "
+ bean.getName() + "上线了");//设置在聊天面板显示的上线提示
// 给所有在线用户发出有人上线消息
HashSet set = new HashSet();
set.addAll(onlines.keySet());//刷新在线用户列表
serverBean.setClients(set);
sendAll(serverBean);
break;
}
case -1: { // 下线
// 创建服务器的catbean,并发送给客户端
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());
// 向剩下的在线用户发送有人离开的通知
CatBean serverBean2 = new CatBean();
serverBean2.setInfo(bean.getTimer() + " "
+ bean.getName() + " " + " 下线了");//下线信息
serverBean2.setType(0);
HashSet set = new HashSet();
set.addAll(onlines.keySet());
serverBean2.setClients(set);
sendAll(serverBean2);
return;
}
case 1: { // 聊天
// 创建服务器的catbean,并发送给客户端
CatBean serverBean = new CatBean();
serverBean.setType(1);
serverBean.setClients(bean.getClients());
serverBean.setInfo(bean.getInfo());
serverBean.setName(bean.getName());
serverBean.setTimer(bean.getTimer());
// 向选中的客户发送数据
sendMessage(serverBean);
break;
}
case 2: { // 请求接受文件
// 创建服务器的catbean,并发送给客户端
CatBean serverBean = new CatBean();
String info = bean.getTimer() + " " + bean.getName()
+ "向你传送文件,是否需要接受";
serverBean.setType(2);
serverBean.setClients(bean.getClients()); // 这是发送的目的地
serverBean.setFileName(bean.getFileName()); // 文件名称
serverBean.setSize(bean.getSize()); // 文件大小
serverBean.setInfo(info);//提示信息内容
serverBean.setName(bean.getName()); // 来源
serverBean.setTimer(bean.getTimer());
// 向选中的客户发送数据
sendMessage(serverBean);
break;
}
case 3: { // 确定接收文件
CatBean serverBean = new CatBean();
serverBean.setType(3);
serverBean.setClients(bean.getClients()); // 文件来源
serverBean.setTo(bean.getTo()); // 文件目的地
serverBean.setFileName(bean.getFileName()); // 文件名称
serverBean.setIp(bean.getIp());
serverBean.setPort(bean.getPort());
serverBean.setName(bean.getName()); // 接收的客户名称
serverBean.setTimer(bean.getTimer());
// 通知文件来源的客户,对方确定接收文件
sendMessage(serverBean);
break;
}
case 4: {
CatBean serverBean = new CatBean();
serverBean.setType(4);
serverBean.setClients(bean.getClients()); // 文件来源
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();
}
}
/**
* 向用户发送数据
* @param serverBean
*/
private void sendMessage(CatBean serverBean) {
// 首先取得所有的values
Set cbs = onlines.keySet();
Iterator it = cbs.iterator();
// 选中客户
HashSet clients = serverBean.getClients();
while (it.hasNext()) {
// 在线客户
String client = it.next();
// 选中的客户中若是在线的,就发送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();
}
}
}
}
/**
* 向所有用户发送数据
* @param serverBean
*/
public void sendAll(CatBean serverBean) {
Collection clients = onlines.values();
Iterator it = clients.iterator();
ObjectOutputStream oos;
while (it.hasNext()) {
Socket c = it.next().getSocket();
try {
//进行数据传送
oos = new ObjectOutputStream(c.getOutputStream());
oos.writeObject(serverBean);
oos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* 关闭各种流
*/
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 {
//不停接受来自客户端的请求
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
可以用来封装一些使用方法
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() {
//获取时间格式
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
贪吃蛇代码的实现
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;// 计分牌
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() {
// 设置界面元素
mainFrame = new JFrame("贪吃蛇游戏");
Container cp = mainFrame.getContentPane();
mainFrame.setBounds(600,400,400,300);
//得分牌
labelScore = new JLabel("所得分数为:", JLabel.CENTER);
cp.add(labelScore, BorderLayout.NORTH);
//画布
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 键重新开始游戏", 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);// 设置窗口大小不能变化
//窗口监听器
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e){
snakeModel.s.stop();
mainFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
});
mainFrame.setVisible(true);
begin();
}
// keyPressed():按键检测
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();//得到按键的值
if (snakeModel.running)//在蛇运动时生效
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;
//改变暂停或继续状态
case KeyEvent.VK_SPACE:
case KeyEvent.VK_P:
snakeModel.changePauseState();// 暂停或继续
break;
default:
}
// 重新开始
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);
// 画出蛇
g.setColor(Color.BLACK);
LinkedList na = snakeModel.nodeArray;
Iterator it = na.iterator();
while (it.hasNext()) {
Node n = (Node) it.next();
drawNode(g, n);
}
// 画出食物
g.setColor(Color.RED);
Node n = snakeModel.food;
drawNode(g, n);
updateScore();
}
// drawNode():绘画某一结点(蛇身或食物)
private void drawNode(Graphics g, Node n) {
g.fillRect(n.x * nodeWidth, n.y * nodeHeight, nodeWidth - 1, nodeHeight - 1);
}
// updateScore():改变计分牌
public void updateScore() {
String s = "所得分数为: " + snakeModel.score;
labelScore.setText(s);//将得分设置到得分版
}
// begin():游戏开始,放置贪吃蛇
void begin() {
if (snakeModel == null || !snakeModel.running) {
//启动贪吃蛇
snakeModel = new SnakeModel(this, DEFAULT_WIDTH / nodeWidth, DEFAULT_HEIGHT / nodeHeight);
(new Thread(snakeModel)).start();
}
}
}
/**
* 节点类
* @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;// 界面数据保存在数组里
LinkedList nodeArray = new LinkedList();
Node food;
int maxX;// 最大宽度
int maxY;// 最大长度
int direction = 2;// 方向
boolean running = false;
int timeInterval = 200;// 间隔时间(速度)
double speedChangeRate = 0.75;// 速度改变程度
boolean paused = false;// 游戏状态
int score = 0;
int countMove = 0;
// UP和DOWN是偶数,RIGHT和LEFT是奇数
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);// 没有蛇和食物的地区置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
}
// 改变运动方向
public void changeDirection(int newDirection) {
//上与下都为偶数,左与右都为奇数,若方向的值除以2的余数相等,则方向冲突
if (direction % 2 != newDirection % 2) {// 避免冲突
direction = newDirection;
}
}
// 贪吃蛇运动函数
public boolean moveOn() {
Node n = (Node) nodeArray.getFirst();//头node确定方向
int x = n.x;
int y = n.y;
//头node的移动
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);// 在头部加上一结点
// 计分规则与移动长度和速度有关
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 {// 什么都没有碰到
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():贪吃蛇运动线程
public void run() {
running = true;
s.play();
while (running) {
try {
Thread.sleep(timeInterval);
} catch (Exception e) {
s.stop();
break;
}
if (!paused) {
if (moveOn()) {// 未结束
gs.repaint();
} else {// 游戏结束
s.stop();
JOptionPane.showMessageDialog(null, "GAME OVER", "Game Over", JOptionPane.INFORMATION_MESSAGE);
break;
}
}else{
// s.stop();
}
}
running = false;
}
// createFood():生成食物及放置地点
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():加快蛇运动速度
public void speedUp() {
timeInterval *= speedChangeRate;
}
// speedDown():放慢蛇运动速度
public void speedDown() {
timeInterval /= speedChangeRate;
}
// changePauseState(): 改变游戏状态(暂停或继续)
public void changePauseState() {
if(paused){
s.play();
}else{
s.stop();
}
paused = !paused;
}
}
Sound
封装一些对声音的处理方法
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();
}
}