GUI部分由Jformdesigner自动生成
网络编程部分由UDP实现
效果图如下:
代码实现:
public class Chat extends Frame
{
public Chat() {
initComponents();
initOthers();
}
private void initOthers() {
this.setVisible(true);
sendArea.setLineWrap(true); //激活自动换行功能
sendArea.setWrapStyleWord(true); // 激活断行不断字功能
new Receive().start();
try {
socket = new DatagramSocket();
bw = new BufferedWriter(new FileWriter("config.txt",true)); //需要在尾部追加
} catch (Exception e) {
e.printStackTrace();
}
}
private DatagramSocket socket ;
private BufferedWriter bw;
private void thisWindowClosing(WindowEvent e) {
socket.close();
try {
bw.close();
} catch (IOException e1) {
e1.printStackTrace();
}
System.exit(0);
}
private void clearMouseClicked(MouseEvent e) {
displayArea.setText("");
}
private void shakeMouseClicked(MouseEvent e){
try {
send(new byte[]{-1},sendArea.getText());
} catch (Exception e1) {
e1.printStackTrace();
}
}
private void send(byte[] arr, String ip) throws Exception{
DatagramPacket packet =
new DatagramPacket(arr, arr.length, InetAddress.getByName(ip), 9999);
socket.send(packet); //发送数据
}
private void shake()
{
int x = this.getLocation().x; //获取横坐标位置
int y = this.getLocation().y; //获取纵坐标位置
for(int i = 0; i < 20; i++) {
try {
this.setLocation(x + 20, y + 20);
Thread.sleep(20);
this.setLocation(x + 20, y - 20);
Thread.sleep(20);
this.setLocation(x - 20, y + 20);
Thread.sleep(20);
this.setLocation(x - 20, y - 20);
Thread.sleep(20);
this.setLocation(x, y);
}catch (Exception e1)
{
e1.printStackTrace();
}
}
}
private class Receive extends Thread { //接收和发送需要同时执行,所以定义成多线程的
public void run() {
try {
DatagramSocket socket = new DatagramSocket(9999);
DatagramPacket packet = new DatagramPacket(new byte[8192], 8192);
while(true) {
socket.receive(packet); //接收信息
byte[] arr = packet.getData(); //获取字节数据
int len = packet.getLength(); //获取有效的字节数据
if(arr[0] == -1 && len == 1) { //如果发过来的数组第一个存储的值是-1,并且数组长度是1
shake();
continue; //终止本次循环,继续下次循环,因为震动后不需要执行下面的代码
}
String message = new String(arr,0,len); //转换成字符串
String time = getCurrentTime(); //获取当前时间
String ip = packet.getAddress().getHostAddress(); //获取ip地址
String str = time + " " + ip + " :\r\n" + message + "\r\n\r\n";
bw.write(str);
displayArea.append(str);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private String getCurrentTime() {
Date d = new Date(); //创建当前日期对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
return sdf.format(d); //将时间格式化
}
private void sendMouseClicked(MouseEvent e) {
try {
send();
} catch (Exception e1) {
e1.printStackTrace();
}
}
private void send() throws Exception{
String message = sendArea.getText(); //获取发送区域的内容
String ip = ipArea.getText(); //获取ip地址;
ip = ip.trim().length() == 0 ? "255.255.255.255" : ip;
send(message.getBytes(),ip);
String time = getCurrentTime(); //获取当前时间
String str = time + " 我对:" + (ip.equals("255.255.255.255") ? "所有人" : ip) + "说\r\n" + message + "\r\n\r\n";
displayArea.append(str); //将信息添加到显示区域中
bw.write(str); //将信息写到数据库中
sendArea.setText("");
}
private void loadMouseClicked(MouseEvent e) {
try {
loadFile();
} catch (Exception e1) {
e1.printStackTrace();
}
}
private void loadFile() throws Exception{
bw.flush(); //刷新缓冲区
FileInputStream fis = new FileInputStream("config.txt");
ByteArrayOutputStream baos = new ByteArrayOutputStream(); //在内存中创建缓冲区
int len;
byte[] arr = new byte[8192];
while((len = fis.read(arr)) != -1) {
baos.write(arr, 0, len);
}
String str = baos.toString(); //将内存中的内容转换成了字符串
displayArea.setText(str);
fis.close();
}
private void send(MouseEvent e) {
// TODO add your code here
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
ipArea = new JTextField();
send = new JButton();
clear = new JButton();
load = new JButton();
shake = new JButton();
scrollPane1 = new JScrollPane();
displayArea = new JTextArea();
scrollPane2 = new JScrollPane();
sendArea = new JTextArea();
//======== this ========
setResizable(false);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
thisWindowClosing(e);
}
});
//---- send ----
send.setText("\u53d1\u9001");
send.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
send(e);
sendMouseClicked(e);
}
});
//---- clear ----
clear.setText("\u6e05\u7a7a");
clear.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
clearMouseClicked(e);
}
});
//---- load ----
load.setText("\u52a0\u8f7d");
load.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
loadMouseClicked(e);
}
});
//---- shake ----
shake.setText("\u9707\u52a8");
shake.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
shakeMouseClicked(e);
shakeMouseClicked(e);
}
});
//======== scrollPane1 ========
{
//---- displayArea ----
displayArea.setEditable(false);
scrollPane1.setViewportView(displayArea);
}
//======== scrollPane2 ========
{
scrollPane2.setViewportView(sendArea);
}
GroupLayout layout = new GroupLayout(this);
layout.setHonorsVisibility(false);
setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup()
.addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
.addComponent(scrollPane1, GroupLayout.DEFAULT_SIZE, 386, Short.MAX_VALUE)
.addGroup(GroupLayout.Alignment.LEADING, layout.createSequentialGroup()
.addComponent(ipArea, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addComponent(send)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
.addComponent(clear)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
.addComponent(load)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
.addComponent(shake)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(scrollPane2, GroupLayout.DEFAULT_SIZE, 386, Short.MAX_VALUE))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup()
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(scrollPane1, GroupLayout.PREFERRED_SIZE, 289, GroupLayout.PREFERRED_SIZE)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
.addComponent(scrollPane2, GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE)
.addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
.addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
.addComponent(ipArea, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
.addComponent(shake)
.addComponent(load)
.addComponent(clear)
.addComponent(send))
.addGap(18, 18, 18))
);
pack();
setLocationRelativeTo(getOwner());
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JTextField ipArea;
private JButton send;
private JButton clear;
private JButton load;
private JButton shake;
private JScrollPane scrollPane1;
private JTextArea displayArea;
private JScrollPane scrollPane2;
private JTextArea sendArea;
// JFormDesigner - End of variables declaration //GEN-END:variables
public static void main(String[] args) {
new Chat();
}
}