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日
陈小灏  LV15 2023年12月27日
xinxin23383  LV7 2023年11月28日
liugua777  LV2 2023年5月7日
微信网友_6444139264921600  LV6 2023年4月29日
xiexiaoming05  LV14 2022年5月21日
waitingforyou  LV20 2022年3月31日
13112360  LV2 2021年12月5日
Aoifee  LV4 2021年11月9日
18350164218  LV13 2021年6月18日
最近浏览更多
yinfei305  LV2 6月19日
Luck_ZDM  LV12 5月22日
krispeng  LV13 4月15日
347469264  LV1 4月2日
pengboyue  LV1 4月1日
woldxy  LV12 4月1日
小安同学  LV7 2023年12月25日
xinxin23383  LV7 2023年11月28日
xp95323  LV14 2023年11月27日
3334004690  LV10 2023年10月18日
顶部 客服 微信二维码 底部
>扫描二维码关注最代码为好友扫描二维码关注最代码为好友