仿QQ聊天软件及源码java版

一直以来,很多java的同志们都没有一个完整资料来参考。把源码贴出来,大家共享!

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.Rectangle;
import java.awt.SystemTray;
import java.awt.Toolkit;
import java.awt.TrayIcon;
import java.awt.TrayIcon.MessageType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.Scanner;
import java.util.Stack;
import java.util.prefs.Preferences;

import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JPopupMenu;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.border.TitledBorder;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;


public class EQ extends JDialog{
	private JTextField ipEndTField;
	private JTextField ipStartTField;
	private JTextField userNameTField;//用户框
	private JPasswordField passwordTField;//密码框
	private JTextField placardPathTField;//placard:公告
	private JTextField updatePathTField;//更新路径
	private JTextField pubPathTField;
	public static EQ frame = null;
	private ChatTree chatTree;
	private JPopupMenu popupMenu;//右键菜单
	private JTabbedPane tabbedPane;//分页面板
	private JToggleButton searchUserButton;//搜索用户按钮
	private JProgressBar progressBar;//滚动条
	private JList faceList;
	private JButton selectInterfaceOKButton;
	private DatagramSocket ss;//数据报插座
	private final JLabel stateLabel;
	private static String user_dir;
	private static File localFile;
	private static File netFile;
	private String netFilePath;
	private JButton messageAlertButton;
	private Stack messageStack;Stack 类表示后进先出(LIFO)的对象堆栈。
	private ImageIcon messageAlertIcon;
	private ImageIcon messageAlertNullIcon;
	private Rectangle location;
	public static TrayIcon trayicon;
	private Dao dao;
	//Preferences.systeRoot:返回系统的根首选项节点   Preferences:参数选择
	public final static Preferences preferences = Preferences.systemRoot();
	private JButton userInfoButton;
	//----------------------------------------------------------------------------------
	public static void main(String[] args){
		try{
			String laf = preferences.get("lookAndFeel", "java默认");
			if(laf.indexOf("当前系统") > -1){
				UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
			}
			EQ frame = new EQ();
			frame.setVisible(true);
			frame.SystemTrayInitial();// 初始化系统栏
			frame.server();
			frame.checkPlacard();
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	//----------------------------------------------------------------------------------
	public EQ(){
		super(new JFrame());
		frame = this;
		dao = Dao.getDao();
		location = dao.getLocation();
		setTitle("EQ聊天");
		setBounds(location);
		progressBar = new JProgressBar();
		//BevelBorder:该类实现简单的双线斜面边框。Bevel:斜面     lowered:凹入斜面类型。
		progressBar.setBorder(new BevelBorder(BevelBorder.LOWERED));
		tabbedPane = new JTabbedPane();
		popupMenu = new JPopupMenu();
		chatTree = new ChatTree(this);
		user_dir = System.getProperty("user.dir");// 程序执行路径用于系统更新
		localFile = new File(user_dir + File.separator + "EQ.jar");// 本地EQ文件
		stateLabel = new JLabel();// 状态栏标签
		this.addWindowListener(new FrameWindowListener());// 添加窗体监视器
		this.addComponentListener(new ComponentAdapter(){
			public void componentResized(final ComponentEvent e){
				saveLocation();
			}
			public void componentMoved(final ComponentEvent e){
				saveLocation();
			}
		});
		try{// 启动通讯服务端口
			ss = new DatagramSocket(1111);
		}catch(SocketException e2){
			if(e2.getMessage().startsWith("Address already in use")){
				showMessageDialog("服务端口被占用,或者本软件已经运行。");
			}
			System.exit(0);
		}
		{// 初始化公共信息按钮
			messageAlertIcon = new ImageIcon(EQ.class.getResource("/image/messageAlert.gif"));
			messageAlertNullIcon = new ImageIcon(EQ.class.getResource("/image/messageAlertNull20.gif"));
			messageStack = new Stack();
			messageAlertButton = new JButton();
			messageAlertButton.setHorizontalAlignment(SwingConstants.RIGHT);
			messageAlertButton.setContentAreaFilled(false);//不填充内容区域
			final JPanel BannerPanel = new JPanel();
			BannerPanel.setLayout(new BorderLayout());
			this.add(BannerPanel,BorderLayout.NORTH);
			userInfoButton = new JButton();
			BannerPanel.add(userInfoButton,BorderLayout.WEST);
			userInfoButton.setMargin(new Insets(0,0,0,10));//Margin:边距    insets:插入 
			initUserInfoButton();// 初始化本地用户头像按钮
			BannerPanel.add(messageAlertButton,BorderLayout.CENTER);
			messageAlertButton.addActionListener(new ActionListener(){

				@Override
				public void actionPerformed(ActionEvent arg0) {
					if(!messageStack.empty()){
						showMessageDialog(messageStack.pop());//堆栈顶部的对象(Vector 对象中的最后一项)。 
					}
				}
			});
			messageAlertButton.setIcon(messageAlertIcon);
			showMessageBar();
		}
		this.add(tabbedPane,BorderLayout.CENTER);
		tabbedPane.setTabPlacement(SwingConstants.LEFT);//设置此选项卡窗格的选项卡布局
		ImageIcon userTicon = new ImageIcon(EQ.class.getResource("/image/tabIcon/tabLeft.PNG"));
		tabbedPane.addTab(null,userTicon,createUserList(),"用户列表");
		ImageIcon sysOTicon = new ImageIcon(EQ.class.getResource("/image/tabIcon/tabLeft2.PNG"));
		tabbedPane.addTab(null, sysOTicon, createSysToolPanel(), "系统操作");
		ImageIcon sysSTicon = new ImageIcon(EQ.class.getResource("/image/tabIcon/tabLeft3.png"));
		tabbedPane.addTab(null, sysSTicon, createSysSetPanel(), "系统设置");
		this.setAlwaysOnTop(true);//总在顶部
	}
	//----------------------------------------------------------------------------------
	private JScrollPane createSysSetPanel(){//系统设置面板
		final JPanel sysSetPanel = new JPanel();
		JScrollPane scrollPane = new JScrollPane(sysSetPanel);
		sysSetPanel.setLayout(new BoxLayout(sysSetPanel,BoxLayout.Y_AXIS));
		scrollPane.setBorder(new EmptyBorder(0,0,0,0));
		final JPanel sysPathPanel = new JPanel();
		sysPathPanel.setMaximumSize(new Dimension(600,200));
		sysPathPanel.setBorder(new TitledBorder("系统路径"));//title - 边框应显示的标题
		sysPathPanel.setLayout(new GridLayout(0,1));
		sysSetPanel.add(sysPathPanel);
		sysPathPanel.add(new JLabel("程序升级路径"));
		updatePathTField = new JTextField(preferences.get("updatePath", "请输入路径"));
		sysPathPanel.add(updatePathTField);
		sysPathPanel.add(new JLabel("系统公告路径:"));
		placardPathTField = new JTextField(preferences.get("placardPath","请输入路径"));
		sysPathPanel.add(placardPathTField);
		sysPathPanel.add(new JLabel("公共程序路径:"));
		pubPathTField = new JTextField(preferences.get("pubPath", "请输入路径"));
		sysPathPanel.add(pubPathTField);
		final JButton pathOKButton = new JButton("确定");
		pathOKButton.setActionCommand("sysOK");
		pathOKButton.addActionListener(new SysSetPanelOKListener());
		sysSetPanel.add(pathOKButton);
		final JPanel loginPanel = new JPanel();
		loginPanel.setMaximumSize(new Dimension(600, 90));
		loginPanel.setBorder(new TitledBorder("登录升级服务器"));
		final GridLayout gridLayout_1 = new GridLayout(0, 1);
		gridLayout_1.setVgap(5);
		loginPanel.setLayout(gridLayout_1);
		sysSetPanel.add(loginPanel);
		final JPanel panel_7 = new JPanel();
		panel_7.setLayout(new BoxLayout(panel_7, BoxLayout.X_AXIS));
		loginPanel.add(panel_7);
		panel_7.add(new JLabel("用户名:"));
		userNameTField = new JTextField(preferences.get("username", "请输入用户名"));
		panel_7.add(userNameTField);
		final JPanel panel_8 = new JPanel();
		panel_8.setLayout(new BoxLayout(panel_8, BoxLayout.X_AXIS));
		loginPanel.add(panel_8);
		panel_8.add(new JLabel("密 码:"));
		passwordTField = new JPasswordField("*****");
		panel_8.add(passwordTField);
		final JButton loginOKButton = new JButton("确定");
		sysSetPanel.add(loginOKButton);
		loginOKButton.setActionCommand("loginOK");
		loginOKButton.addActionListener(new SysSetPanelOKListener());
		final JPanel ipPanel = new JPanel();
		final GridLayout gridLayout_2 = new GridLayout(0, 1);
		gridLayout_2.setVgap(5);
		ipPanel.setLayout(gridLayout_2);
		ipPanel.setMaximumSize(new Dimension(600, 90));
		ipPanel.setBorder(new TitledBorder("IP搜索范围"));
		sysSetPanel.add(ipPanel);
		final JPanel panel_5 = new JPanel();
		panel_5.setLayout(new BoxLayout(panel_5, BoxLayout.X_AXIS));
		ipPanel.add(panel_5);
		panel_5.add(new JLabel("起始IP:"));
		ipStartTField = new JTextField(preferences.get("ipStart", "192.168.0.1"));
		panel_5.add(ipStartTField);
		final JPanel panel_6 = new JPanel();
		panel_6.setLayout(new BoxLayout(panel_6, BoxLayout.X_AXIS));
		ipPanel.add(panel_6);
		panel_6.add(new JLabel("终止IP:"));
		ipEndTField = new JTextField(preferences.get("ipEnd", "192.168.1.255"));
		panel_6.add(ipEndTField);
		final JButton ipOKButton = new JButton("确定");
		ipOKButton.setActionCommand("ipOK");
		ipOKButton.addActionListener(new SysSetPanelOKListener());
		sysSetPanel.add(ipOKButton);
		return scrollPane;
	}
	//----------------------------------------------------------------------------------
	private JScrollPane createUserList(){// 用户列表面板
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		addUserPopup(chatTree,getPopupMenu());// 为用户添加弹出菜单
		scrollPane.setViewportView(chatTree);
		scrollPane.setBorder(new EmptyBorder(0,0,0,0));
		chatTree.addMouseListener(new ChatTreeMouseListener());
		
		return scrollPane;
	}
	//----------------------------------------------------------------------------------
	private JScrollPane createSysToolPanel() {// 系统工具面板
		JPanel sysToolPanel = new JPanel(); // 系统工具面板
		sysToolPanel.setLayout(new BorderLayout());
		JScrollPane sysToolScrollPanel = new JScrollPane();
		sysToolScrollPanel
				.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		sysToolScrollPanel.setBorder(new EmptyBorder(0, 0, 0, 0));
		sysToolScrollPanel.setViewportView(sysToolPanel);
		sysToolPanel.setBorder(new BevelBorder(BevelBorder.LOWERED));
		JPanel interfacePanel = new JPanel();
		sysToolPanel.add(interfacePanel, BorderLayout.NORTH);
		interfacePanel.setLayout(new BorderLayout());
		interfacePanel.setBorder(new TitledBorder("界面选择-再次启动生效"));
		faceList = new JList(new String[]{"当前系统", "java默认"});
		interfacePanel.add(faceList);
		faceList.setBorder(new BevelBorder(BevelBorder.LOWERED));
		final JPanel interfaceSubPanel = new JPanel();
		interfaceSubPanel.setLayout(new FlowLayout());
		interfacePanel.add(interfaceSubPanel, BorderLayout.SOUTH);
		selectInterfaceOKButton = new JButton("确定");
		selectInterfaceOKButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				preferences.put("lookAndFeel", faceList.getSelectedValue().toString());
				JOptionPane.showMessageDialog(EQ.this, "重新运行本软件后生效");
			}
		});
		interfaceSubPanel.add(selectInterfaceOKButton);

		JPanel searchUserPanel = new JPanel(); // 用户搜索面板
		sysToolPanel.add(searchUserPanel);
		searchUserPanel.setLayout(new BorderLayout());
		final JPanel searchControlPanel = new JPanel();
		searchControlPanel.setLayout(new GridLayout(0, 1));
		searchUserPanel.add(searchControlPanel, BorderLayout.SOUTH);
		final JList searchUserList = new JList(new String[]{"检测用户列表"});// 新添加用户列表
		final JScrollPane scrollPane_2 = new JScrollPane(searchUserList);
		scrollPane_2.setDoubleBuffered(true);
		searchUserPanel.add(scrollPane_2);
		searchUserList.setBorder(new BevelBorder(BevelBorder.LOWERED));
		searchUserButton = new JToggleButton();
		searchUserButton.setText("搜索新用户");
		searchUserButton.addActionListener(new SearchUserActionListener(searchUserList));
		searchControlPanel.add(progressBar);
		searchControlPanel.add(searchUserButton);
		searchUserPanel.setBorder(new TitledBorder("搜索用户"));

		final JPanel sysUpdatePanel = new JPanel();
		sysUpdatePanel.setOpaque(false);
		sysUpdatePanel.setLayout(new GridBagLayout());
		sysUpdatePanel.setBorder(new TitledBorder("系统操作"));
		sysToolPanel.add(sysUpdatePanel, BorderLayout.SOUTH);
		final JButton sysUpdateButton = new JButton("系统更新");
		final GridBagConstraints gridBagConstraints_1 = new GridBagConstraints();
		gridBagConstraints_1.gridx = 0;
		gridBagConstraints_1.gridy = 0;
		sysUpdatePanel.add(sysUpdateButton, gridBagConstraints_1);
		sysUpdateButton.addActionListener(new SysUpdateListener());// 添加系统更新事件
		final JLabel updateLabel = new JLabel("最近更新:");
		final GridBagConstraints updateLabelLayout = new GridBagConstraints();
		updateLabelLayout.gridy = 1;
		updateLabelLayout.gridx = 0;
		sysUpdatePanel.add(updateLabel, updateLabelLayout);
		final JLabel updateDateLabel = new JLabel();// 程序更新日期标签
		Date date = new Date(localFile.lastModified());
		String dateStr = String.format("%tF % 0) {
								byte[] data = new byte[len];
								if (fis.read(data) > 0) {
									fout.write(data);
								}
							}
							fis.close();
							fout.close();
							frameUpdate.setVisible(false);
							frameUpdate = null;
							showMessageDialog("更新完毕,请重新启动程序。");
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}).start();
			} else {
				showMessageDialog("已经是最新的程序了。");
			}
		}
	}
	//----------------------------------------------------------------------------------
	private void checkPlacard() { // 检测公告信息方法
		String placardDir = preferences.get("placardPath", null);
		if (placardDir == null) {
			pushMessage("未设置公告路径");
			return;
		}
		File placard = new File(placardDir);
		try {
			if (placard.exists() && placard.isFile()) {
				StringBuilder placardStr = new StringBuilder();
				Scanner sc = new Scanner(new FileInputStream(placard));
				while (sc.hasNextLine()) {
					placardStr.append(sc.nextLine());
				}
				pushMessage(placardStr.toString());
			}
		} catch (FileNotFoundException e) {
			pushMessage("公告路径错误,或公告文件不存在");
		}
	}
	//----------------------------------------------------------------------------------
	public void setStatic(String str){// 设置状态栏信息
		if(stateLabel != null){
			stateLabel.setText(str);
		}
	}
	
	public void pushMessage(String info){// 堆压信息
		if(!messageStack.contains(info)){
			messageStack.push(info);
		}
	}
	
	private void showMessageDialog(String message){
		JOptionPane.showMessageDialog(this, message);
	}
	//----------------------------------------------------------------------------------
	private String showInputDialog(String str){// 显示输入对话框
		String newName = JOptionPane.showInputDialog(this,
				"输入" + str + "的新名字");
		return newName;
	}
	private class accessFolderActionListener implements ActionListener {// 访问资源
		public void actionPerformed(final ActionEvent e) {
			TreePath path = chatTree.getSelectionPath();
			if (path == null)
				return;
			DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
					.getLastPathComponent();
			User user = (User) node.getUserObject();
			String ip = "\\\\"+user.getIp();
			String command = e.getActionCommand();
			if (command.equals("computer")) {
				Resource.startFolder(ip);
			}
			if (command.equals("public")) {
				String serverPaeh = preferences.get("pubPath", null);
				if (serverPaeh == null) {
					pushMessage("未设置公共程序路径");
					return;
				}
				Resource.startFolder(serverPaeh);
			}
		}
	}

	private class RenameActionListener implements ActionListener {// 更名
		public void actionPerformed(final ActionEvent e) {
			TreePath path = chatTree.getSelectionPath();
			if (path == null)
				return;
			DefaultMutableTreeNode node = (DefaultMutableTreeNode) path
					.getLastPathComponent();
			User user = (User) node.getUserObject();
			String newName = showInputDialog(user.getName());
			if (newName != null && !newName.isEmpty()) {
				user.setName(newName);
				dao.updateUser(user);
				DefaultTreeModel model = (DefaultTreeModel) chatTree.getModel();
				model.reload();
				chatTree.setSelectionPath(path);
				initUserInfoButton();
			}
		}
	}
	private class FrameWindowListener extends WindowAdapter {
		public void windowClosing(final WindowEvent e) {// 系统关闭事件
			setVisible(false);
		}
	}
	private class AddUserActionListener implements ActionListener {
		public void actionPerformed(final ActionEvent e) {// 添加用户
			String ip = JOptionPane.showInputDialog(EQ.this, "输入新用户IP地址");
			if (ip != null)
				chatTree.addUser(ip, "add");
		}
	}
	private class delUserActionListener implements ActionListener {
		public void actionPerformed(final ActionEvent e) {// 删除用户
			chatTree.delUser();
		}
	}
	private class messagerGroupSendActionListener implements ActionListener {// 信使群发
		public void actionPerformed(final ActionEvent e) {
			String message = JOptionPane.showInputDialog(EQ.this, "请输入群发信息",
					"信使群发", JOptionPane.INFORMATION_MESSAGE);
			if (message != null && !message.equals("")) {
				TreePath[] selectionPaths = chatTree.getSelectionPaths();
				Resource.sendGroupMessenger(selectionPaths, message);
			} else if (message != null && message.isEmpty()) {
				JOptionPane.showMessageDialog(EQ.this, "不能发送空信息!");
			}
		}
	}
	private void SystemTrayInitial() { // 系统栏初始化
		if (!SystemTray.isSupported()) // 判断当前系统是否支持系统栏
			return;
		try {
			String title = "TT";
			String company = "成都市同道科技有限公司";
			SystemTray sysTray = SystemTray.getSystemTray();
			Image image = Toolkit.getDefaultToolkit().getImage(
					EQ.class.getResource("/icons/sysTray.png"));// 系统栏图标
			trayicon = new TrayIcon(image, title + "\n" + company, createMenu());
			trayicon.setImageAutoSize(true);
			trayicon.addActionListener(new SysTrayActionListener());
			sysTray.add(trayicon);
			trayicon.displayMessage(title, company, MessageType.INFO);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	private PopupMenu createMenu() { // 创建系统栏菜单的方法
		PopupMenu menu = new PopupMenu();
		MenuItem exitItem = new MenuItem("退出");
		exitItem.addActionListener(new ActionListener() { // 系统栏退出事件
					public void actionPerformed(ActionEvent e) {
						System.exit(0);
					}
				});
		MenuItem openItem = new MenuItem("打开");
		openItem.addActionListener(new ActionListener() {// 系统栏打开菜单项事件
					public void actionPerformed(ActionEvent e) {
						if (!isVisible()) {
							setVisible(true);
							toFront();
						} else
							toFront();
					}
				});

		// 系统栏的访问服务器菜单项事件
		MenuItem publicItem = new MenuItem("访问服务器");
		publicItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String serverPaeh = preferences.get("pubPath", null);
				if (serverPaeh == null) {
					pushMessage("未设置公共程序路径");
					return;
				}
				Resource.startFolder(serverPaeh);
			}
		});
		menu.add(publicItem);
		menu.add(openItem);
		menu.addSeparator();
		menu.add(exitItem);
		return menu;
	}
	class SysTrayActionListener implements ActionListener {// 系统栏双击事件
		public void actionPerformed(ActionEvent e) {
			setVisible(true);
			toFront();
		}
	}
}



你可能感兴趣的:(实战,java,聊天,qq,string,null,date)