您的位置:首页 > 其它

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

2016-05-09 17:08 417 查看
源代码下载链接: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类来获取当前的系统时间,并格式化消息,添加到消息文本框中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: