简易聊天程序教程(六)主窗口和聊天窗口

源代码下载链接:http://download.csdn.net/detail/sky453589103/9514686

如果有什么问题,欢迎留言。

主窗口用的是JList控件,在显示了登陆的跟人信息之后,接下来就是好友的列表。

为了方便以后拓展 ,我把好友的信息封装在FriendInformation中,FriendInformation类的定义也很简单的,都能看懂。


下面来逐步分析一下MainWin类:

MainWin中比较重要的是事件的监听:

好友列表中的右键菜单的监听:

		JMenuItem item = new JMenuItem("remove");
		item.addActionListener(new ActionListener () {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				RequestMessage request = new RequestMessage();
				request.setFrom(username);
				request.setTo(friendJList.getSelectedValue().getName());
				request.setCommand("remove a friend");
				try {
					PrintStream out = new PrintStream(getServer().getOutputStream());
					out.print(request.Format());
				} catch (IOException e) {

				}
			}
			
		});
		friendListPopupMenu.add(item);
在因为我的右键菜单中只有一个选项,因此写的很简单,但是用来举例,完全足够了。当选中了这个选项之后,客户端会生成删除还有的请求报文发送给服务器端,服务器端hi执行这个动作,如果删除成功,就返回删除了之后的好友列表。


好友列表的选定模式应该是单选的,通过下面的函数来设定:

this.friendJList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

好友列表的监听操作:

		this.friendJList.addMouseListener(new MouseListener() {

			@Override
			public void mouseClicked(MouseEvent e) {
				// if mouse's right key click, the line will be selected.
				if (e.getButton() == 3) {
					friendJList.setSelectedIndex(friendJList.locationToIndex(e.getPoint()));
				}
				// getButton function's return value has three value.
				// 1 represent mouse's left key.
				// 3 represent mouse's right key.
				if (e.getButton() == 1 && e.getClickCount() >= 2) {
					// index of being double clicked line
					// int index = friendJList.getSelectedIndex();
					FriendInformation f = (FriendInformation) friendJList.getSelectedValue();
					// FriendInformation f = friendList.get(index);
					if (f.getStatus().equals("on")) {
						AddChatWin(f.getName());
					} else {
						JOptionPane.showMessageDialog(null, f.getName() + " is offline!", "message",
								JOptionPane.INFORMATION_MESSAGE);
					}
					friendJList.clearSelection();
				}
				else if (e.getButton() == 3 && friendJList.getSelectedIndex() >= 0) {
					friendListPopupMenu.show(e.getComponent(), e.getX(), e.getY());
				}

			}
		});

省略了的后面的三个函数可以不看,都是空的。

				if (e.getButton() == 3) {
					friendJList.setSelectedIndex(friendJList.locationToIndex(e.getPoint()));
				}

getButton函数会有三个返回值,1代表左键,2代表中键,3代表右键。

这段代码,实现的是,如果是右击一行,这一行也会被选中。

接下来判断的

1.是不是左键双击了某一行。如果是,就创建响应的聊天窗口,如果聊天窗口存在就将它显示出来。

2.是不是右键单击了某一行,如果是,就弹出右键菜单。

自定义JList的渲染模式, 需要调用setCellRenderer函数才会生效:

class FriendJListRenderer extends JPanel implements ListCellRenderer<FriendInformation> {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private JLabel lbIcon = new JLabel();
	private JLabel lbName = new JLabel();
	private JLabel lbStatus = new JLabel();

	public FriendJListRenderer() {
		setLayout(new BorderLayout(5, 5));

		JPanel panelText = new JPanel(new GridLayout(0, 1));
		panelText.add(lbName);
		panelText.add(lbStatus);
		add(lbIcon, BorderLayout.WEST);
		add(panelText, BorderLayout.CENTER);
	}

	@Override
	public Component getListCellRendererComponent(JList<? extends FriendInformation> list, FriendInformation friend,
			int index, boolean isSelected, boolean cellHasFocus) {
		ImageIcon icon = new ImageIcon(getClass().getResource("/SimpleChat/Mushroom2.png"));
		lbIcon.setIcon(icon);
		// lbIcon.setText("this is a icon \r\n but not show by List\r\n
		// error?");
		lbName.setText(friend.getName());
		lbStatus.setText(friend.getStatus());
		lbStatus.setForeground(Color.blue);

		// set Opaque to change background color of JLabel
		lbName.setOpaque(true);
		lbStatus.setOpaque(true);
		lbIcon.setOpaque(true);

		// when select item
		if (isSelected) {
			lbName.setBackground(list.getSelectionBackground());
			lbStatus.setBackground(list.getSelectionBackground());
			lbIcon.setBackground(list.getSelectionBackground());
			setBackground(list.getSelectionBackground());
		} else { // when don't select
			lbName.setBackground(list.getBackground());
			lbStatus.setBackground(list.getBackground());
			lbIcon.setBackground(list.getBackground());
			setBackground(list.getBackground());
		}
		return this;
	}
}


添加好友的按钮的事件监听:

在按下添加好友的按钮之后会先出现一个带输入框的窗口,在输入了要添加的好友的名字之后,就可以执行添加好友的操作。

		addFriendButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				// String inputValue = JOptionPane.showInputDialog(this, "Please
				// input a name");
				String inputValue = JOptionPane.showInputDialog(null,
						"Please input a name",
						"add a new friend",
						JOptionPane.CLOSED_OPTION);
				if (!inputValue.equals("")) {
					RequestMessage request = new RequestMessage();
					request.setFrom(username);
					request.setTo(inputValue);
					request.setCommand("add a friend");

					try {
						PrintStream out = new PrintStream(getServer().getOutputStream());
						out.print(request.Format());
					} catch (IOException e) {

					}
				}
			}

		});


需要注意的是,在登陆操作之后,所有的来自服务器的响应的消息都会在startn函数中接收,然后根据响应消息的code和description做出响应的处理。因为篇幅原因,这不在展开了。

而聊天窗口中,负责的只是消息文本的添加和发送,接收信息的四级操作是在主窗口中进行的。因为在这样做可以避免同时有多个流在监听输入,而造成混乱。

聊天窗口在接收到对方的信息的时候,会加上当前的系统时间,通过下面代码实现:

	public void addMessage(String from, String content) {
		Date date = new Date();
		messageTextArea.setText(
				messageTextArea.getText() + "\r\n" + from + "    " + dateFormat.format(date) + "\r\n" + content);

	}
通过Date类来获取当前的系统时间,并格式化消息,添加到消息文本框中。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值