源代碼下載鏈接: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()));
}
接下來判斷的
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) {
}
}
}
});
而聊天窗口中,負責的只是消息文本的添加和發送,接收信息的四級操作是在主窗口中進行的。因爲在這樣做可以避免同時有多個流在監聽輸入,而造成混亂。
聊天窗口在接收到對方的信息的時候,會加上當前的系統時間,通過下面代碼實現:
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類來獲取當前的系統時間,並格式化消息,添加到消息文本框中。