⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 onlinefrm.java

📁 简单的聊天程序
💻 JAVA
字号:
import java.io.*;
import java.net.*;
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.Timer;


public class OnLineFrm {
	private ObjectInputStream input;
	private JFrame f;
	private int WIDTH,HEIGHT,SCREEN_WIDTH;
	private Point currentBaseP;
	private Timer hideListTimer;
	private Thread refreshListTimer;
	private volatile boolean isHided = false;
	private volatile boolean isRunning = true;
	private JList list;
	private DefaultListModel model;
	private MyCellRenderer render;
	private JCheckBox hideCheckBox;
	private JButton setMyInfoBtn;
	private Vector<ClientInfo> infoVector;
	private String qqNumber,ip,port,nickname;
	private JPopupMenu popMenu;
	//用于接收信息,转发给相应的窗口
	private DatagramSocket socketR;
 	private DatagramPacket packetR;
	public OnLineFrm(ObjectInputStream input,
			String qqNumber,String ip,String port){

		init(input,qqNumber,ip,port);
		buildGUI();
		hookEvent();
		initWorkThread();
	}
	private void buildGUI(){
		this.f = new JFrame("猫猫2007");
		this.f.setIconImage(new ImageIcon("Icon/titleIcon.gif").getImage());
		Dimension size = Toolkit.getDefaultToolkit().getScreenSize();
		this.SCREEN_WIDTH = size.width;
		this.WIDTH = size.width/4;
		this.HEIGHT = size.height;
		this.f.setSize(WIDTH,HEIGHT);
		this.f.setResizable(false);
		this.currentBaseP = new Point(size.width*3/4,0);
		this.f.setLocation(size.width*3/4,0);
		/**
		 * 添加在线列表
		 */
		model = new DefaultListModel();
		list = new JList(model);
		render = new MyCellRenderer();
		list.setCellRenderer(render);
		list.setBackground(Color.pink);
		JScrollPane scrP = new JScrollPane(list);
		this.f.add(scrP,BorderLayout.CENTER);

		/**
		 * 自动隐藏按钮
		 */
		hideCheckBox= new JCheckBox("自动隐藏",false);
		this.setMyInfoBtn = new JButton("个人设置");
		/**
		 * 初始化按钮面板
		 */
		JPanel btnP1 = new JPanel();
		btnP1.setBackground(Color.CYAN);
		btnP1.setLayout(new FlowLayout(FlowLayout.LEFT));
		btnP1.add(hideCheckBox);
		JPanel btnP2 = new JPanel();
		btnP2.setBackground(Color.CYAN);
		btnP2.setLayout(new FlowLayout(FlowLayout.RIGHT));
		btnP2.add(this.setMyInfoBtn);
		JPanel btnP = new JPanel();
		btnP.setLayout(new GridLayout(1,2));
		btnP.add(btnP1);
		btnP.add(btnP2);
		this.f.add(btnP,BorderLayout.SOUTH);
		/**
		 * 用于查看资料和聊天的PopupMenu
		 */
		initPopMenu();
		this.f.setVisible(true);

	}
	private void acceptWorkTrd(){
		//监听指定端口接收数据
		try {
			this.socketR = new DatagramSocket(9000);
		} catch (SocketException e)
		{}
		new Thread(new Runnable(){
			public void run(){
				acceptMsg();
			}
		}).start();
	}
	private void acceptMsg(){
		while(isRunning){
			try{
				//一次最多能传送500字
				byte[] buffer = new byte[1024];
				packetR = new DatagramPacket(buffer,buffer.length);
				this.socketR.receive(packetR);
				MyUtilities.playSound("Sound/msg.wav");
				String s = new String(buffer,0,packetR.getLength());
				StringTokenizer st = new StringTokenizer(s,"$");
				new TalkFrm(st.nextToken(),st.nextToken(),st.nextToken());
				Thread.sleep(2000);
			}catch(Exception e)
			{}
		}
	}
	private void initPopMenu(){
		this.popMenu = new JPopupMenu();
		Action viewInfoAction = new AbstractAction(){
			public void actionPerformed(ActionEvent e){
				
				popMenu.setVisible(false);
			}
		};
		viewInfoAction.putValue(Action.NAME, "查看资料");
		popMenu.add(viewInfoAction);
		popMenu.add(new JSeparator());
		Action deleteAction = new AbstractAction(){
			public void actionPerformed(ActionEvent e){
				refreshList(list.getSelectedIndex());
				popMenu.setVisible(false);
			}
		};
		deleteAction.putValue(Action.NAME, "删除");
		Action talkAction = new AbstractAction(){
			public void actionPerformed(ActionEvent e){
				popMenu.setVisible(false);
			}
		};
		talkAction.putValue(Action.NAME, "发送消息");
		popMenu.add(deleteAction);
		popMenu.add(new JSeparator());
		popMenu.add(talkAction);
		popMenu.setVisible(false);
		popMenu.pack();
		
	}
	private void dealTalk(){
		//隐藏在线列表
		if(!this.hideCheckBox.isSelected()){
			this.hideCheckBox.setSelected(true);
		}
		new TalkFrm((String)this.list.getSelectedValue(),
				   this.nickname,
				   this.infoVector.elementAt(
				   this.list.getSelectedIndex()).ip);
		
	}
	private void hookEvent(){
		//隐藏列表
		this.f.addComponentListener(new ComponentAdapter(){
			public void componentMoved(ComponentEvent e){
				currentBaseP = e.getComponent().getLocation();
			}
		});
		this.f.addWindowListener(new WindowAdapter(){
			public void windowClosing(WindowEvent e){
				/**
				 * 退出前通知服务器
				 */
				try{
				new ObjectOutputStream(
						new Socket(
					    ip,Integer.parseInt(port)).getOutputStream()
					    ).writeObject(new Message("下线",qqNumber));
				}catch(Exception ex)
				{}
				isRunning = false;
				if(hideListTimer.isRunning()){
					hideListTimer.stop();
				}
				System.exit(0);
			}
		});
		this.list.addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e){
				//双击
				if(e.getClickCount() == 2){
					/**
					 * 建立聊天窗口前先隐藏在线列表
					 */
					dealTalk();
				}//右击
				else if(e.getClickCount()==1&&SwingUtilities.isRightMouseButton(e)){
					/**
					 * 显示PopMenu
					 */
					for(int i=0;i < model.size();++i){
						if(list.getCellBounds(i, i+1).contains(e.getPoint())){
							list.setSelectedIndex(i);
						}
					}
					if(!infoVector.elementAt(list.getSelectedIndex()).number.equals(qqNumber)){
						popMenu.show(list,e.getPoint().x,e.getPoint().y);
					}
				}
			}
		});
		this.hideCheckBox.addItemListener(new ItemListener(){

			public void itemStateChanged(ItemEvent e) {
				if(e.getStateChange() == ItemEvent.SELECTED){
					if(!hideListTimer.isRunning()){
						hideListTimer.restart();
					}else{
						hideListTimer.start();
					}
				}
				else if(e.getStateChange() == ItemEvent.DESELECTED){
					hideListTimer.stop();
				}
			}

		});
	}
	private void initWorkThread() {
		/*原本要实现为隐藏服务的
		 * try {
			Robot r = new Robot();
			r.mouseMove(this.currentBaseP.x+this.WIDTH/2,
					this.currentBaseP.y+this.HEIGHT/2);
		} catch (AWTException e) {
			e.printStackTrace();
		}*/
		/*初始化为自动隐藏服务的Timer线程*/
		this.hideListTimer = new Timer(1500, new ActionListener(){
			public void actionPerformed(ActionEvent e){
				resetLocation(MouseInfo.getPointerInfo().getLocation()
				);
			}
		});
		this.hideListTimer.setRepeats(true);

		this.refreshListTimer = new Thread(new Runnable(){
			public void run(){
				refreshList();
			}
		});
		refreshListTimer.start();
	}
	private void init(ObjectInputStream input,
			String qqNumber,String ip,String port){
		this.infoVector = new Vector<ClientInfo>();
		this.qqNumber = qqNumber;
		this.ip = ip;
		this.port = port;
		this.input = input;
	}
	/**
	 * 从服务器接收列表信息并更新
	 */
	private void refreshList(){
		while(this.isRunning){
			try {
				Object o = this.input.readObject();
				if(o instanceof ClientInfo){
					/*更新在线列表*/
					ClientInfo info = (ClientInfo)o;
					this.render.iconNames.add(info.iconName);
					this.model.addElement(info.nickName);
					if(info.number.equals(qqNumber)){
						//记录当前用户的昵称
						this.nickname = info.nickName;
					}
					/*保存好友资料*/
					this.infoVector.add(info);
				}else if(o instanceof Message){
					Message m = (Message)o;
					if(m.sysMsg.equals("有人下线")){
						//防止用户已经删除了该用户啦!
						for(int i=0;i < this.infoVector.size();++i){
							if(this.infoVector.elementAt(i).number.equals(m.msg)){
								refreshList(i);
								break;
							}
						}
					}
				}
				Thread.sleep(2000);
			} catch (Exception e)
			{}
		}
	}
	/**
	 * 列表的某项被删除后,更新这一项后面的ClientInfo中各项Index
	 */
	private void refreshList(int index){
		//更新List
		this.model.remove(index);
		this.render.iconNames.remove(index);
		this.list.repaint();
		//更新用户信息
		this.infoVector.remove(index);
	}
	/**
	 * 负责隐藏和显示列表
	 */
	private void resetLocation(Point currentPoint){
		//显示的时候鼠标移出了List
		if(!isHided){
			if(!(new Rectangle(this.currentBaseP,
					new Dimension(WIDTH,HEIGHT)
			).contains(currentPoint))){
				//隐藏
				hideFrm();
			}
		}else{
			if(isNeedShow(currentPoint)){
				showFrm();
			}
		}
	}
	private void hideFrm(){
		Point newP = null;
		if(currentBaseP.x<0)
			newP = new Point(1-WIDTH,0);
		else if(currentBaseP.x> this.SCREEN_WIDTH-WIDTH)
			newP = new Point(this.SCREEN_WIDTH-1,0);
		else
			newP = new Point(currentBaseP.x,1-this.HEIGHT);
		this.f.setLocation(newP);
		this.isHided = true;
	}
	private void showFrm(){
		if(this.currentBaseP.x <0){
			this.currentBaseP.x =0;
		}else if(this.currentBaseP.x>this.SCREEN_WIDTH-this.WIDTH){
			this.currentBaseP.x = this.SCREEN_WIDTH-this.WIDTH;
		}
		currentBaseP.y =0;
		this.f.setLocation(currentBaseP);
		this.isHided = false;
	}
	private boolean isNeedShow(Point p){
		return	(p.x==0&&currentBaseP.x<=0)||		
		(p.y==0&&currentBaseP.x>=0)||
		(p.x==this.SCREEN_WIDTH-1&&currentBaseP.x >(this.SCREEN_WIDTH-this.WIDTH)
		);
	}
	private class MyCellRenderer extends JPanel implements ListCellRenderer {
		private Vector<String> iconNames;
		private JLabel iconLab;
		public MyCellRenderer(){
			iconNames = new Vector<String>();
			iconLab = new JLabel();
			this.setLayout(new FlowLayout(FlowLayout.LEFT));
			this.add(iconLab);
		}
		public Component getListCellRendererComponent(
				JList list,
				Object value,            // value to display
				int index,               // cell index
				boolean isSelected,      // is the cell selected
				boolean cellHasFocus)    // the list and the cell have the focus
		{
			this.iconLab.setIcon(
					new ImageIcon("PersonIcon/"+iconNames.elementAt(index)));
			this.iconLab.setText(value.toString());
			this.iconLab.setIconTextGap(10);
			if(isSelected){
				this.setBackground(Color.cyan);
			}else{
				this.setBackground(list.getBackground());
			}
			return this;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -