package UDP;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
/*
*
*需求:编写一个类似qq那样可以聊天的可视化图像界面,实现功能
*1)用户输入文字可以显示在公共区域(所有人都可以看见)
* 2015年9月8日
*/
/**
* 接收显示在公共区域信息的类
*/
class rev_Message implements Runnable {
MulticastSocket s = null;
rev_Message(MulticastSocket s) {
this.s = s;
}
@Override
public void run() {
while (true) {
// 2,定义数据包,用于存储数据
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, 0, buf.length);
try {
System.out.println("wait connect...");
// 3,通过Socket的receive方法接收数据
s.receive(dp);
// 4,通过数据包的方法提取包中的数据,打印
System.out.println("ip:" + dp.getAddress().getHostAddress()
+ " ||port:" + dp.getPort());
String str = new String(dp.getData(), 0, dp.getData().length);
System.out.println("----->data:" + str);
String str1 = new String("ip:" + dp.getAddress() + "||"
+ "port:" + dp.getPort());
createMenu.getTxr_rev().append(
"\r\n" + str1 + "\r\n" + str + "\r\n");
} catch (IOException e) {
throw new RuntimeException("接收失败");
}
}
}
}
@SuppressWarnings("serial")
class createMenu extends JFrame {
private JButton btn_clear, btn_send, btn_close, btn_sure;
private static TextArea txr_send;
private static TextArea txr_rev;
private static JTextField txrname;
private JPanel contentPane1;
private JDialog dialog;
private JLabel label;
MulticastSocket s = null;
InetAddress group = null;
createMenu() {
this.s = UDP_ChatDemo2.s;
this.group = UDP_ChatDemo2.group;
init_menu();
someEvent();
}
private void someEvent() {
btn_send.addActionListener(new SendMsg2(s, group));
btn_clear.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
txr_send.setText("");
}
});
btn_close.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
txr_rev.addKeyListener(new KeyAdapter() {
@Override
public void keyTyped(KeyEvent e) {
e.consume();// 屏蔽掉法输入
}
});
txr_send.addKeyListener(new SendMsg2(s, group));
dialog.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
dialog.setVisible(false);
}
});
btn_sure.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
dialog.setVisible(false);
}
});
}
private void init_menu() {
setTitle("聊天");
setBounds(200, 100, 600, 500);// 设置窗体位置和大小
contentPane1 = new JPanel();// 创建内容面板
contentPane1.setBorder(new EmptyBorder(5, 5,5, 5));// 设置面板的边框
setContentPane(contentPane1);// 应用内容面板
GridBagLayout gbl_contentPane = new GridBagLayout();// 创建网格组布局
contentPane1.setLayout(gbl_contentPane);// 使用网格组布局
txr_rev = new TextArea();
GridBagConstraints gbc_edt_rev = new GridBagConstraints();// 创建网格组布局约束条件
gbc_edt_rev.insets = new Insets(0, 0, 5, 5);// 设置控件的空白
gbc_edt_rev.fill = GridBagConstraints.HORIZONTAL;
gbc_edt_rev.gridwidth = 3;
gbc_edt_rev.gridheight = 1;
contentPane1.add(txr_rev, gbc_edt_rev);// 增加显示文本及其约束条件
JPanel panel_send = new JPanel();
txr_send = new TextArea();
JPanel panel_name = new JPanel(new FlowLayout());
JLabel txtname = new JLabel("名字:");
txrname = new JTextField(10);
panel_name.add(txtname);
panel_name.add(txrname);
GridBagConstraints gbc_edt_name = new GridBagConstraints();
gbc_edt_name.fill = GridBagConstraints.HORIZONTAL;// 创建网格组布局约束条件
gbc_edt_name.gridx = 0;
gbc_edt_name.gridy = 2;
gbc_edt_name.gridwidth = 2;
gbc_edt_name.gridheight =1;
contentPane1.add(panel_name,gbc_edt_name);
panel_send.add(txr_send);
GridBagConstraints gbc_edt_send = new GridBagConstraints();// 创建网格组布局约束条件
gbc_edt_send.fill = GridBagConstraints.HORIZONTAL;
gbc_edt_send.insets = new Insets(5, 0, 5, 5);// 设置控件的空白
gbc_edt_send.gridx = 0;
gbc_edt_send.gridy = 1;
gbc_edt_send.gridwidth = 3;
gbc_edt_send.gridheight = 1;
contentPane1.add(panel_send, gbc_edt_send);
btn_send = new JButton("发送");
GridBagConstraints gbc_btn_send = new GridBagConstraints();// 创建网格组布局约束条件
gbc_btn_send.fill = GridBagConstraints.HORIZONTAL;// 设置填充方式
gbc_btn_send.weightx = 10.0;// 第三行的分布方式为10%
gbc_btn_send.insets = new Insets(0, 0, 5, 5);// 设置控件的空白
gbc_btn_send.gridx = 0;
gbc_btn_send.gridy = 4;
contentPane1.add(btn_send, gbc_btn_send);
btn_clear = new JButton("清除");
GridBagConstraints gbc_btn_clear = new GridBagConstraints();// 创建网格组布局约束条件
gbc_btn_clear.fill = GridBagConstraints.HORIZONTAL;// 设置填充方式
gbc_btn_clear.weightx = 10.0;// 第三行的分布方式为10%
gbc_btn_clear.insets = new Insets(0, 0, 5, 5);// 设置控件的空白
gbc_btn_clear.gridx = 1;
gbc_btn_clear.gridy = 4;
contentPane1.add(btn_clear, gbc_btn_clear);
btn_close = new JButton("关闭");
GridBagConstraints gbc_btn_close = new GridBagConstraints();// 创建网格组布局约束条件
gbc_btn_close.fill = GridBagConstraints.HORIZONTAL;// 设置填充方式
gbc_btn_close.weightx = 10.0;// 第三行的分布方式为10%
gbc_btn_close.insets = new Insets(0, 5, 5, 5);// 设置控件的空白
gbc_btn_close.gridx = 2;
gbc_btn_close.gridy = 4;
contentPane1.add(btn_close, gbc_btn_close);
dialog = new JDialog(dialog, "提示", true);
dialog.setBounds(50, 60, 300, 200);
dialog.setLayout(new FlowLayout());
btn_sure = new JButton("确定");
label = new JLabel(" 发送数据不为空,请重新输入 ");
dialog.add(label);
dialog.add(btn_sure);
}
public static TextArea getTxr_send() {
return txr_send;
}
public static TextArea getTxr_rev() {
return txr_rev;
}
class SendMsg2 implements ActionListener, KeyListener {
String msg = null;
MulticastSocket s = null;
InetAddress group = null;
public SendMsg2(MulticastSocket s, InetAddress group) {
this.s = s;
this.group = group;
}
public void actionPerformed(ActionEvent e) {
sendMsg();
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == e.VK_ENTER) {
sendMsg();
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
/**
* 发送数据
*/
private void sendMsg() {
// 如果名字为空 给出提示信息
if(txrname.getText().isEmpty()){
new JOptionPane().showMessageDialog(null, "请一定要取别名!");
}
byte[] buf = new byte[1024];
String line = txrname.getText() + ": "+txr_send.getText();
try {
if (!line.isEmpty()) {
System.out.print("input:");
buf = line.getBytes();
// 2,确定数据,并封装成数据包,里边有对方的ip地址和端口
DatagramPacket dp = new DatagramPacket(buf, 0, buf.length,
group, 5556);
// 3.通过Socket服务,将已有的数据发出去
s.send(dp);
String str1 = new String("ip:" + dp.getAddress() + "||"
+ "port:" + dp.getPort());
System.out.println("send===>" + str1);
txr_send.setText("");
line = txr_send.getText();
} else {
System.out.println("发送数据不为空,请重新输入");
dialog.setVisible(true);
}
} catch (Exception e1) {
// TODO Auto-generated catch block
System.out.println("发送失败");
e1.printStackTrace();
}
}
}
}
public class UDP_ChatDemo2 {
public static MulticastSocket s = null;
public static InetAddress group = null;
public static void main(String[] args) throws Exception {
// 实现组播数据传送的配置信息
SetMuticasSocket();
new createMenu().setVisible(true);
new Thread(new rev_Message(s)).start();
}
/**
* 实现组播数据传送的配置信息
*/
private static void SetMuticasSocket() {
// TODO Auto-generated method stub
try {
//IP网络的组播一般通过组播IP地址来实现。组播IP地址就是D类IP地址,即224.0.0.0至239.255.255.255之间的IP地址。
group = InetAddress.getByName("228.9.6.12");
} catch (UnknownHostException e1) {
System.out.println("组播地址绑定失败");
}
try {
s = new MulticastSocket(5556);
} catch (IOException e1) {
System.out.println("组播地址创建失败");
}
try {
s.joinGroup(group);
} catch (IOException e1) {
System.out.println("组播地址加入失败");
}
}
}