package client.frm;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.FontFormatException;
import java.awt.Frame;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowFocusListener;
import java.io.File;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.Socket;

import javax.imageio.ImageIO;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextPane;
import javax.swing.JWindow;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

import data.Face;
import data.FriendUser;
import data.JQMessage;
import data.Portrait;
import data.Record;

import tools.DateDeal;

 /**
 * 聊天窗体类。
 */
public class ChatPane extends JFrame implements ActionListener{

	private JLabel lblTop = new JLabel();
	private JLabel lblFriendInfo = new JLabel();
	private JLabel lblPhoto = new JLabel();
	private JTextPane txtMessage = new JTextPane();
	private JTextPane txtWrite = new JTextPane();
	
	private JPanel paneFriendInfo = new JPanel();
	private JPanel paneTools = new JPanel();
	private JPanel paneBtn = new JPanel();
	
	private JButton btnSend = new JButton("发送(S)");
	private JButton btnClose = new JButton("关闭(C)");
	private JButton btnSet = new JButton("↓");
	
	private JPopupMenu popupMenu = new JPopupMenu();
	private JCheckBoxMenuItem itemEnter = new JCheckBoxMenuItem("按Enter发送");
	private JCheckBoxMenuItem itemCEnter = new JCheckBoxMenuItem("按Ctrl+Enter发送");
	
	private Color bgColor = new Color(169,213,244);
	
	//private Socket client = null;
	private ObjectOutputStream oos = null;
	private FriendUser friendUser = null;
	private FriendUser selfUser = null;
	
	private JButton btnFaces = new JButton();
	private FaceWindow faceWindow = null;

	/**
	 * 窗体的构造函数。
	 * @param oos 输出对象流。
	 * @param friendUser FriendUser好友对象。
	 * @param selfUser FriendUser自己对象。
	 * @param show 是否显示。
	 */
	public ChatPane(ObjectOutputStream oos,FriendUser friendUser,FriendUser selfUser,boolean show) {
		this.oos = oos;
		this.friendUser = friendUser;
		this.selfUser = selfUser;
		setTitle("与 "+friendUser.getNickName()+" 交谈中");
		setSize(494,500);
		try {
			setIconImage(ImageIO.read(ChatPane.class.getResource("/client/images/chat/icon.gif")));
		} catch (IOException e) {
			System.out.println("错误"+e.getMessage());
		}
		//setResizable(false);
		Toolkit tk=Toolkit.getDefaultToolkit();
		setLocation((tk.getScreenSize().width-getSize().width)/2,(tk.getScreenSize().height-getSize().height)/2);
		
		init();
		btnClose.addActionListener(this);
		btnSend.addActionListener(this);
		btnSet.addActionListener(this);
		itemEnter.addActionListener(this);
		itemCEnter.addActionListener(this);
		btnFaces.addActionListener(this);
		
		txtMessage.setContentType("text/html");
		txtWrite.addKeyListener(new SendKeyListenter());
//		txtWrite.setContentType("text/html");
//		txtWrite.setText("<html><body style=\"font-size: 12px;font-family:'宋体';color:'red';font-style: normal;\" >测试数据</body></html>");
/*		StyleContext sc = StyleContext.getDefaultStyleContext();
		NamedStyle style = sc.new NamedStyle();
		//Style style = new StyleContext.NamedStyle();
		style.addAttribute("font-family", "宋体");
		style.addAttribute("font-size", "12px");
		style.addAttribute("font-style", "normal");
		style.addAttribute("color", "yellow");
		txtWrite.setLogicalStyle(style);
*/		
		setDefaultCloseOperation(DISPOSE_ON_CLOSE);
		setVisible(show);
	}
	
	/**
	 * 初始化面板。
	 */
	private void init(){
		lblTop.setPreferredSize(new Dimension(494,61));
		lblTop.setVerticalAlignment(SwingConstants.TOP);
		lblTop.setIcon(new ImageIcon(ChatPane.class.getResource("/client/images/chat/top.gif")));
		lblTop.setOpaque(true);
		lblTop.setBackground(bgColor);
		lblFriendInfo.setVerticalAlignment(SwingConstants.TOP);
		lblFriendInfo.setPreferredSize(new Dimension(151,407));
		lblFriendInfo.setIcon(new ImageIcon(ChatPane.class.getResource("/client/images/chat/friend_info.gif")));
		lblFriendInfo.setOpaque(true);
		lblFriendInfo.setBackground(bgColor);
		
		btnClose.setFocusPainted(false);
		btnClose.setPreferredSize(new Dimension(60,20));
		btnClose.setMargin(new Insets(0,5,0,5));
		btnSend.setFocusPainted(false);
		btnSend.setPreferredSize(new Dimension(60,20));
		btnSend.setMargin(new Insets(0,5,0,5));
		btnSet.setFocusPainted(false);
		btnSet.setPreferredSize(new Dimension(9,20));
		btnSet.setMargin(new Insets(0,-4,0,-5));
		
		btnFaces.setIcon(new Face(200));
		btnFaces.setMargin(new Insets(0,0,0,0));
		btnFaces.setBorder(new EmptyBorder(0,0,0,0));
		
		
		lblPhoto.setPreferredSize(new Dimension(20,20));
		lblPhoto.setIcon(new Portrait(friendUser.getPhoto(),friendUser.getState(),false));
		JLabel lblInfo = new JLabel(friendUser.getNickName()+"("+friendUser.getJqnum()+")  "+friendUser.getSignature());
		lblInfo.setPreferredSize(new Dimension(290,20));
		lblInfo.setForeground(Color.BLUE);
		//lblInfo.setBorder(new LineBorder(Color.BLACK));
		paneFriendInfo.setOpaque(true);
		paneFriendInfo.setBackground(new Color(205,237,255));
		paneFriendInfo.setPreferredSize(new Dimension(337,25));
		paneFriendInfo.setLayout(new FlowLayout(FlowLayout.LEFT,5,2));
		paneFriendInfo.add(lblPhoto);
		paneFriendInfo.add(lblInfo);
		
		paneTools.setOpaque(true);
		paneTools.setBackground(new Color(205,237,255));
		paneTools.setPreferredSize(new Dimension(337,25));
		paneTools.setLayout(new FlowLayout(FlowLayout.LEFT,2,5));
		paneTools.add(btnFaces);
		
		paneBtn.setPreferredSize(new Dimension(337,30));
		paneBtn.setOpaque(true);
		paneBtn.setBackground(bgColor);
		paneBtn.setLayout(new FlowLayout(FlowLayout.RIGHT,0,5));
		paneBtn.add(btnClose);
		paneBtn.add(new FillWidth(5,20,bgColor));
		paneBtn.add(btnSend);
		paneBtn.add(new FillWidth(5,20,bgColor));
		paneBtn.add(btnSet);
		
		JScrollPane spMessage = new JScrollPane(txtMessage);
		spMessage.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		spMessage.setBorder(new EmptyBorder(0,0,0,0));
		
		JScrollPane spWrite = new JScrollPane(txtWrite);
		spWrite.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
		spWrite.setBorder(new EmptyBorder(0,0,0,0));
		
		JPanel paneMessage = new JPanel();
		paneMessage.setLayout(new BorderLayout());
		paneMessage.add(paneFriendInfo,BorderLayout.NORTH);
		paneMessage.add(spMessage,BorderLayout.CENTER);
		
		
		
		JPanel paneWrite = new JPanel();
		paneWrite.setPreferredSize(new Dimension(337,96));
		paneWrite.setLayout(new BorderLayout());
		paneWrite.add(paneTools,BorderLayout.NORTH);
		paneWrite.add(spWrite,BorderLayout.CENTER);
		paneWrite.add(paneBtn,BorderLayout.SOUTH);
		
		JPanel paneCenter = new JPanel();
		paneCenter.setLayout(new BorderLayout());
		paneCenter.setBorder(new LineBorder(new Color(118,171,211)));
		paneCenter.setOpaque(true);
		paneCenter.setBackground(bgColor);
		paneCenter.add(paneMessage,BorderLayout.CENTER);
		paneCenter.add(paneWrite,BorderLayout.SOUTH);
		
		JPanel paneAll = new JPanel();
		paneAll.setLayout(new BorderLayout());
		paneAll.setOpaque(true);
		paneAll.setBackground(bgColor);
		paneAll.add(paneCenter,BorderLayout.CENTER);
		paneAll.add(paneBtn,BorderLayout.SOUTH);
		
		setLayout(new BorderLayout());
		add(lblTop,BorderLayout.NORTH);
		add(new FillWidth(6,407,bgColor),BorderLayout.WEST);
		add(lblFriendInfo,BorderLayout.EAST);
		add(paneAll,BorderLayout.CENTER);
		add(new FillWidth(494,5,bgColor),BorderLayout.SOUTH);
		
		ButtonGroup btnGroup = new ButtonGroup();
		btnGroup.add(itemCEnter);
		btnGroup.add(itemEnter);
		popupMenu.add(itemEnter);
		popupMenu.add(itemCEnter);
		itemCEnter.setSelected(true);
	}
	
	/**
	 * 关闭、发送、设置、按Enter、按Ctrl+Enter、表情按钮等事件。
	 */
	public void actionPerformed(ActionEvent e) {
		if(e.getSource()==btnClose){
			this.dispose();
			return;
		}
		if(e.getSource()==btnSend){
			String content = txtWrite.getText();
			//System.out.println(content);
			//txtMessage.setEditorKit(txtWrite.getEditorKit());
			//txtMessage.setDocument(txtWrite.getDocument());
			//txtMessage.setText(content);
			
			JQMessage message = new JQMessage();
			Record record = new Record();
			record.setFromid(selfUser.getJqnum());
			record.setToid(friendUser.getJqnum());
			record.setId(1);
			record.setContent(txtWrite.getText());
			showRecord(selfUser.getNickName(),record,Color.GREEN);
			message.setType(30);
			message.setObj(record);
			new WriteThread(message).start();
			txtWrite.setText("");
			return;
		}
		if(e.getSource()==btnSet){
			//Point point = getLocationOnScreen();
			//popupMenu.setLocation(point.x+getWidth()-150, point.y+getHeight()-20);
			//popupMenu.setVisible(true);
			popupMenu.show(this, getWidth()-150, getHeight()-20);
			return;
		}
		if(e.getSource()==itemEnter){
			removeSendKey();
			return;
		}
		if(e.getSource()==itemCEnter){
			removeSendKey();
			return;
		}
		if(e.getSource()==btnFaces){
			if(faceWindow==null)
				faceWindow = new FaceWindow(this);
			else{
				//faceWindow.pack();
				Point point = ChatPane.this.getLocationOnScreen();
				faceWindow.setLocation(point.x+20, point.y+120);
				faceWindow.setVisible(true);
			}
		}
	}
	
	/**
	 * 更新好友的图标。
	 * @param icon
	 */
	public void updateFriendPhoto(Icon icon){
		lblPhoto.setIcon(icon);
	}
	
	/**
	 * 显示用户昵称和聊天记录信息到聊天面板上。
	 * @param nickName 昵称
	 * @param record 聊天记录
	 * @param color 显示文字的颜色。
	 */
	public void showRecord(String nickName,Record record,Color color){
		//JOptionPane.showMessageDialog(null, record.getContent());
		insertString(nickName+" "+DateDeal.getDate2(record.getSendTime()), color);
		insertString(record.getContent(), null);
	}
	
	/**
	 * 将信息插入到聊天面板上。
	 * @param msg 消息的内容。
	 * @param color 显示文字的颜色。
	 */
	private void insertString(String msg,Color color){
		StyledDocument document = txtMessage.getStyledDocument();
		SimpleAttributeSet set = new SimpleAttributeSet();
		if(color!=null)
			StyleConstants.setForeground(set, color);
		try {
			document.insertString(document.getLength(), msg+"\n", set);
		} catch (BadLocationException e) {
			System.out.println("添加错误");
		}
	}
	
	/**
	 * 添加发送事件。
	 */
	private void removeSendKey(){
		txtWrite.removeKeyListener(txtWrite.getKeyListeners()[0]);
		txtWrite.addKeyListener(new SendKeyListenter());
	}
	
	
	/*public static void main(String[] args) {
		try {
			//System.out.println(JQClient.class.getResource("../tools/simsun.ttc").getPath());
			Font font = Font.createFont(Font.TRUETYPE_FONT, new File(MainPane.class.getResource("/tools/simsun.ttc").getPath()));
			font = font.deriveFont(Font.PLAIN, 12);
			SetFont.setFont(font);
		} catch (FontFormatException e) {
			System.out.println("错误:"+e.getMessage());
		} catch (IOException e) {
			System.out.println("错误:"+e.getMessage());
		}
		new ChatPane(null,null,null,true);
	}*/

	/**
	 * 
	 */
	private class WriteThread extends Thread{
		private JQMessage message = null;
		public WriteThread(JQMessage message) {
			this.message = message;
		}
		public void run() {
			try {
				if(oos!=null){
					oos.writeObject(message);
					oos.flush();
				}
			} catch (IOException e) {
				System.out.println("发生异常:"+e.getMessage());
				JOptionPane.showMessageDialog(null, "和服务端连接发生错误:"+e.getMessage()+",请重新登录!");
				System.exit(0);
			}
		}
	}
	
	/**
	 * 发送按钮设置事件类。
	 */
	private class SendKeyListenter extends KeyAdapter{
		public void keyPressed(KeyEvent e){ 
			//System.out.println(e.getModifiersEx()+"=="+e.paramString());
			if(e.getModifiers()==(KeyEvent.CTRL_DOWN_MASK+KeyEvent.VK_ENTER))
				System.out.println("ok");
			if((itemEnter.isSelected() && e.getKeyCode()==KeyEvent.VK_ENTER) || (itemCEnter.isSelected() && e.getModifiersEx()==(KeyEvent.CTRL_DOWN_MASK + KeyEvent.VK_ENTER)))
				btnSend.doClick();
			return;
		}
	}
	
	/**
	 * 表情显示JWindow类。
	 */
	private class FaceWindow extends JWindow implements ActionListener,Runnable,WindowFocusListener,MouseListener{
		private static final int faceNum  = 134;
		JPanel paneFace = new JPanel();
		JLabel[] btnFace = new JLabel[faceNum];
		
		/**
		 * 构造函数。
		 * @param owner 显示的窗体。
		 */
		public FaceWindow(Frame owner) {
			super(owner);
			setSize(395,245);
			Point point = ChatPane.this.getLocationOnScreen();
			setLocation(point.x+20, point.y+120);
			
			paneFace.setLayout(new GridLayout(9,15));
			for(int i=0;i<faceNum;i++){
				btnFace[i] = new JLabel();
				paneFace.add(btnFace[i]);
			}
			new Thread(this).start();
			
			JTabbedPane tabPane = new JTabbedPane();
			tabPane.add("默认", paneFace);
			add(tabPane);
			
			addWindowFocusListener(this);
			setVisible(true);
		}
		/**
		 * 将表情显示到JLabel上。
		 */
		public void run() {
			for(int i=0;i<faceNum;i++){
				//btnFace[i] = new JLabel();
				btnFace[i].setIcon(new Face(i));
				btnFace[i].addMouseListener(this);
				btnFace[i].setBorder(new EmptyBorder(1,1,1,1));
				repaint();
			}
			//repaint();
		}
		
		/**
		 * ActionListener事件。
		 */
		public void actionPerformed(ActionEvent e) {
			Object obj = e.getSource();
			if(obj instanceof JButton){
				JButton btnFace = (JButton)obj;
				txtWrite.insertIcon(btnFace.getIcon());
				this.dispose();
			}	
		}
		/**
		 * 该窗体失去焦点时事件。
		 */
		public void windowLostFocus(WindowEvent e) {
			dispose();
		}
		public void windowGainedFocus(WindowEvent e) {	}
		/**
		 * 鼠标点击事件。
		 */
		public void mouseClicked(MouseEvent e) {
			Object obj = e.getSource();
			if(obj instanceof JLabel){
				JLabel lbl = (JLabel)e.getSource();
				txtWrite.insertIcon(lbl.getIcon());
				this.dispose();
			}
		}
		/**
		 * 鼠标进入事件。
		 */
		public void mouseEntered(MouseEvent e) {
			Object obj = e.getSource();
			if(obj instanceof JLabel){
				JLabel lbl = (JLabel)e.getSource();
				lbl.setBorder(new LineBorder(Color.DARK_GRAY));
			}			
		}
		/**
		 * 鼠标移出时事件。
		 */
		public void mouseExited(MouseEvent e) {
			Object obj = e.getSource();
			if(obj instanceof JLabel){
				JLabel lbl = (JLabel)e.getSource();
				lbl.setBorder(new EmptyBorder(1,1,1,1));
			}			
		}
		public void mousePressed(MouseEvent e) {}
		public void mouseReleased(MouseEvent e) {}
	}
}
最近下载更多
krispeng  LV13 6月4日
小安同学  LV7 2023年12月25日
wertttak  LV1 2023年9月26日
1748462964  LV1 2023年7月14日
2017143155  LV12 2023年6月24日
buhuia  LV4 2023年6月9日
人工智能4708  LV11 2023年5月8日
liugua777  LV2 2023年5月4日
accp123456  LV2 2023年3月29日
yuanchuang  LV22 2023年2月14日
最近浏览更多
ilsfcqdf  LV3 9月12日
interface  LV22 7月13日
赵鑫cdsaljkdfsa  LV11 6月27日
28128觅北  LV2 5月22日
krispeng  LV13 4月15日
3334004690  LV10 3月20日
yhwyhw1  LV2 1月2日
2890892945  LV2 2023年12月26日
Sutnuf 2023年11月27日
暂无贡献等级
Wsy2860  LV1 2023年9月6日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友