技术需求
- Socket编程
- IO流
- 线程
- JavaFx基础
- mysql数据库基础
项目讲解
这是一个socket编程的典型的基础项目,实现的是群聊聊天室,需要联机的,自己去改一下IP就行了,我这里用的是localhost,本项目的UI设计是JavaFx,核心代码都有注释,开发模式是MVC开发模式,对javaFx不太熟的小伙伴,可以自己去简单的学习一下UI的设计,需要一个SceneBuilder,就能很嗨皮的设计UI了。
在这里良心推荐一个
JavaFx的自学网址:http://www.javafxchina.net/blog/docs/
如果有的小伙伴用的是Swing,那我也推荐一个
Swing的自学网址:http://c.biancheng.net/view/1206.html
注意swing用的工具是windowBuilder,原理基本上是一样的
简单的说一下,JavaFx更新,swing很老,我开始学的是Swing,怎么说呢,写代码很随意,要求也没那么严格,但是javaFx就不一样了,它是严格的遵从MVC的开发模式的,对于编程有基础的同学,建议用JavaFx,模块化编程值得推荐,这是主流的趋势,如果你写的还是毫无章法的,我只能说,小伙子,早点把习惯改好吧,,,不然总会吃亏的。
由于写项目的时候没有太过注意,而且这也本身就是个测试项目,所以,没有注意命名的格式,个人比较偏爱骆驼峰命名法,有兴趣的可以去看一下,这里的命名就别吐槽我了。匈牙利命名法,,,怎么写就怎么不爽,反正我不喜欢,,,
界面演示
代码情况
model是毫无水平的,Dao也是毫无水平的,主要的就是Controller这个代码和Server,这两个类是核心,在这里帖一个Controller类的代码吧。
package application;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.URL;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;
import Dao.messageDao;
import Dao.onlineDao;
import Dao.userDao;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.stage.Stage;
import model.Message;
import model.User;
import model.Useronline;
public class Controller implements Initializable {
@FXML
private Button registerButton;//进入注册界面按钮,handle方法进入
@FXML
private Button loginbtn;//登录按钮,进入聊天室
@FXML
private Button sendmsg;//发送信息,sendmesssage方法进入
@FXML
private Button registbtn;//进入注册界面点击注册
@FXML
private TextField loginname;
@FXML
private PasswordField loginpw;
@FXML
private Label tips;//显示用户名不存在的
@FXML
private Label tips2;//显示密码错误的
@FXML
private PasswordField loginpw2;
@FXML
private Label usernametips;
@FXML
private Label pwtips;
@FXML
private TextArea onlinetext;
@FXML
private TextField text;
@FXML
private TextArea showmess;
private String content="";
private userDao dao=new userDao();
static onlineDao onlineDao=new onlineDao();
static TextArea myshowmess;
static TextArea myonlinetext;
static Threads threads=new Threads();
int count=0;
static ObjectOutputStream dos = null;
static ObjectInputStream dis = null;
public void handle() {
Register register = new Register();
Stage stage = new Stage();
register.start(stage);
}
public void login() throws Exception {
User name=dao.get(loginname.getText());
if(name!=null) {
if(loginpw.getText().equals(name.getPassword())) {
ChatRoom ct= new ChatRoom(name);
Stage stage = new Stage();
//登录成功之后改成在线,数据库
onlineDao.updateOnline(name.getUsername(), 1);
ct.start(stage);
//关闭原有的窗口
loginbtn.getScene().getWindow().hide();
}else{
tips2.setText("Username or password is error!");
}
}else{
tips.setText("This user doesn't exist");
}
}
public void regist() throws Exception {
User name=dao.get(loginname.getText());
if(name==null) {
if(loginpw.getText().equals(loginpw2.getText())) {
dao.insert(loginname.getText(),loginpw.getText());
//刚注册的时候默认的是不在线
onlineDao.insert(loginname.getText(), 0);
registbtn.getScene().getWindow().hide();
}
else
pwtips.setText("The second pw must be same as the first!");
}
else usernametips.setText("This user has already exist!");
}
public void sendmessage() throws IOException {
String st = text.getText().trim();
User user=ChatRoom.user;//获取聊天界面的user
Date now = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String nowStr = sdf.format(now);// 获取现在的时间
content = "\n" +user.getUsername()+"\t"+ nowStr + "\n" +"\t"+ st;
text.setText("");
Message message=new Message(user.getUsername(), content);
dos.writeObject(message);
messageDao messageDao=new messageDao();
messageDao.insert(user.getUsername(), content);
}
@Override
public void initialize(URL location, ResourceBundle resources) {
myshowmess=showmess;
myonlinetext=onlinetext;
}
public static class Threads implements Runnable{
private boolean state=true;
private boolean flag=true;
public void run() {
while(state) {
try {
if (flag) {
FindoldMyshowmess();
flag=false;//这样只有在第一次发消息前上面的if语句才有效
}
Findonline();
Message message1 = (Message)dis.readObject();
//追加
myshowmess.appendText(message1.getMessage()+ '\n');
} catch (IOException e) {
state=false;
System.exit(0);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
//找聊天记录
private void FindoldMyshowmess(){
try {
messageDao messageDao=new messageDao();
List<Message> messageList=messageDao.getListmessage();
for (Message message : messageList) {
myshowmess.appendText( message.getMessage()+ '\n');
}
if (myshowmess.getText().equals("")) {
myshowmess.appendText("---没有历史消息奥---"+'\n');
}else{
myshowmess.appendText("---以上是历史消息---"+'\n');
}
} catch (Exception e) {
myshowmess.setText("聊天记录获取失败"+"\n");
}
}
private void Findonline(){
try {
//这样可以消除闪屏
TextArea Myonlinetext=new TextArea();
TextArea myontonlinetext=new TextArea();
List<Useronline> useronlineList=onlineDao.getUesronline();
for (Useronline useronline : useronlineList) {
if(useronline.getOnline()==1){
Myonlinetext.setText(Myonlinetext.getText() + useronline.getUsername()+"(in)"+'\n');
}else {
myontonlinetext.setText(myontonlinetext.getText()+useronline.getUsername()+"(out)"+"\n");
}
}
myonlinetext.setText(Myonlinetext.getText()+myontonlinetext.getText());
} catch (SQLException e) {
myonlinetext.setText("在线成员获取失败");
}
}
}
}
接下来的代码,有需要研究的,去贡献下积分,嘻嘻,谢谢啦。
项目下载
友情提示
下载项目的小伙伴,跑不出来不要喷我,代码的运行,应该是先开服务器,再开客户端,客户端可以开多个,别傻傻的直接一上来就开客户端。。。