?? chatclient.java
字號:
//ChatClient.java
package chatclient;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.rmi.RemoteException;
import java.util.Hashtable;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.text.JTextComponent;
import javax.swing.text.Keymap;
import chat.ChatServer;
import chat.Chatter;
public class ChatClient extends JFrame {
//存儲已有聊天用戶,key:用戶名.value: 對應的Chatter對象
Hashtable hash = new Hashtable();
//自己的用戶名
String my_name = "chatter";
//服務器地址
String serverAddr;
//代表客戶端到遠程對象
Chatter chatter;
//服務器端到遠程對象
ChatServer server;
JTextArea displayBox;
JTextArea inputBox;
JComboBox usersBox;
JButton sendButton;
JLabel statusLabel;
ConnectionAction connectAction = new ConnectionAction();
//讓用戶輸入用戶名和服務器地址到對話框
ConnectDlg dlg = new ConnectDlg(this);
public static void main(String[] args) {
new ChatClient();
}
//客戶端界面類構(gòu)造函數(shù)
public ChatClient() {
super("聊天-客戶端");
layoutComponent();
setupMenu();
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
exit();
}
});
show();
}
//設置菜單
private void setupMenu() {
JMenuBar menuBar = new JMenuBar();
JMenuItem conn = new JMenuItem(connectAction);
JMenuItem exit = new JMenuItem("退出");
exit.addActionListener(new AbstractAction() {
public void actionPerformed(ActionEvent evt) {
exit();
}
});
JMenu file = new JMenu("文件");
file.add(conn);
menuBar.add(file);
setJMenuBar(menuBar);
}
//處理 退出 的函數(shù)
private void exit() {
destroy();
System.exit(0);
}
//布置各個界面元素
public void layoutComponent() {
setSize(400, 400);
JPanel contentPane = new JPanel();
//使用GridBagLayout對各控件布局
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
contentPane.setLayout(gridbag);
//最上端的顯示消息的文本域
c.fill = GridBagConstraints.BOTH;
c.gridwidth = GridBagConstraints.REMAINDER;
c.gridheight = 6;
c.weightx = 100;
c.weighty = 100;
c.insets.top = 5;
displayBox = new JTextArea();
displayBox.setLineWrap(true);
displayBox.setEditable(false);
displayBox.setMargin(new Insets(5, 5, 5, 5));
JScrollPane scrollPane = new JScrollPane(displayBox);
contentPane.add(scrollPane, c);
//消息 標簽
c.gridheight = 1;
c.weightx = 0;
c.weighty = 0;
c.insets.top = 10;
JLabel msgLabel = new JLabel("消息:");
contentPane.add(msgLabel, c);
//消息輸入文本框
c.gridheight = 6;
c.insets.top = 0;
c.gridwidth = GridBagConstraints.RELATIVE;
c.weightx = 100;
inputBox = new JTextArea();
addKeymapBindings();
inputBox.setLineWrap(true);
inputBox.setWrapStyleWord(true);
JScrollPane inputScrollPane = new JScrollPane(inputBox);
inputScrollPane.setPreferredSize(new Dimension(250, 50));
inputScrollPane.setMinimumSize(new Dimension(250, 50));
contentPane.add(inputScrollPane, c);
//發(fā)送消息 按鈕
c.weightx = 0;
c.gridwidth = GridBagConstraints.REMAINDER;
sendButton =
new JButton(
new ImageIcon(getClass().getResource("images/send.gif")));
sendButton.setToolTipText("發(fā)送消息");
sendButton.setPreferredSize(new Dimension(50, 50));
sendButton.setMinimumSize(new Dimension(50, 50));
sendButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
sendMessage();
}
});
contentPane.add(sendButton, c);
//發(fā)送給 標簽
c.weightx = 0;
c.fill = GridBagConstraints.HORIZONTAL;
c.gridheight = 1;
JLabel sendtoLabel = new JLabel("發(fā)送給:");
contentPane.add(sendtoLabel, c);
//用戶 下拉列表框
usersBox = new JComboBox();
usersBox.setBackground(Color.WHITE);
usersBox.addItem("所有用戶");
contentPane.add(usersBox, c);
//狀態(tài)欄
JPanel statusPane = new JPanel(new GridLayout(1, 1));
statusLabel = new JLabel("未連接");
statusPane.add(statusLabel);
contentPane.add(statusPane, c);
setContentPane(contentPane);
//實例化ChatterImpl對象
try {
chatter = new ChatterImpl(this);
} catch (Exception e) {
e.printStackTrace();
return;
}
}
public void destroy() {
try {
disconnect();
} catch (java.rmi.RemoteException ex) {
ex.printStackTrace();
}
}
//執(zhí)行連接操作
protected void connect()
throws
java.rmi.RemoteException,
java.net.MalformedURLException,
java.rmi.NotBoundException {
server =
(ChatServer) java.rmi.Naming.lookup(
"//" + serverAddr + "/ChatServer");
server.login(my_name, chatter);
}
//退出聊天室
protected void disconnect() throws java.rmi.RemoteException {
if (server != null)
server.logout(my_name);
}
//**********************************************************************
//以下四個函數(shù)是實現(xiàn)Chatter接口
public void receiveEnter(
String name,
Chatter chatter,
boolean hasEntered) {
if (name != null && chatter != null) {
hash.put(name, chatter);
if (!name.equals(my_name)) {
//對新加入聊天到用戶,在displayBox給出提示
if (!hasEntered)
display(name + " 進入聊天室");
usersBox.addItem(name);
}
}
}
public void receiveExit(String name) {
if (name != null && chatter != null)
hash.remove(name);
for (int i = 0; i < usersBox.getItemCount(); i++) {
if (name.equals((String) usersBox.getItemAt(i))) {
usersBox.remove(i);
break;
}
}
display(name + " 離開聊天室");
}
public void receiveChat(String name, String message) {
display(name + ": " + message);
}
public void receiveWhisper(String name, String message) {
display(name + " (私聊): " + message);
}
//*********************************************************************
//在消息輸入框中 處理鍵盤消息,Ctrl+Enter換行,Enter則發(fā)送消息
protected void addKeymapBindings() {
Keymap keymap =
JTextComponent.addKeymap("MyBindings", inputBox.getKeymap());
Action action = null;
KeyStroke key = null;
//用戶在消息輸入框中按回車發(fā)送消息
action = new AbstractAction() {
public void actionPerformed(ActionEvent evt) {
sendMessage();
}
};
key = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
keymap.addActionForKeyStroke(key, action);
//Ctrl+Enter則實現(xiàn)換行
action = new AbstractAction() {
public void actionPerformed(ActionEvent evt) {
inputBox.append("\n");
}
};
key = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, Event.CTRL_MASK);
keymap.addActionForKeyStroke(key, action);
inputBox.setKeymap(keymap);
}
//在顯示消息的文本域中顯示消息
private void display(String s) {
if (!s.endsWith("\n")) {
displayBox.append(s + "\n");
} else {
displayBox.append(s);
}
int length = displayBox.getText().length() - 1;
displayBox.select(length, length);
}
//從消息框取得消息內(nèi)容,發(fā)送消息函數(shù)
private void sendMessage() {
String message = inputBox.getText();
if (message != null && message.length() > 0) {
inputBox.setText(null);
inputBox.setCaretPosition(0);
display(my_name + ":" + message);
if (server != null) {
if ("所有用戶".equals(usersBox.getSelectedItem())) {//發(fā)送給所有用戶
try {
server.chat(my_name, message);
} catch (java.rmi.RemoteException ex) {
ex.printStackTrace();
}
} else {//私聊,發(fā)給所選用戶
String destUserName = (String) usersBox.getSelectedItem();
Chatter destChatter = (Chatter) hash.get(destUserName);
try {
destChatter.receiveWhisper(my_name, message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
}
inputBox.requestFocus();
}
public void serverStop() {
display("聊天服務器關閉");
server = null;
hash.clear();
connectAction.setEnabled(true);
}
//處理連接命令的 Action類
class ConnectionAction extends AbstractAction {
public ConnectionAction() {
super("連接");
putValue(Action.SHORT_DESCRIPTION, "連接到聊天服務器");
putValue(
Action.ACCELERATOR_KEY,
KeyStroke.getKeyStroke("control C"));
}
public void actionPerformed(ActionEvent evt) {
dlg.pack();
dlg.setLocationRelativeTo(ChatClient.this);
dlg.setVisible(true);
if (dlg.getValue() == JOptionPane.OK_OPTION) {
try {
my_name = dlg.getUserName();
serverAddr = dlg.getServerAddr();
connect();
inputBox.setEditable(true);
displayBox.setText("");
statusLabel.setText(my_name + " 已連接");
this.setEnabled(false);
} catch (Exception e) {
e.printStackTrace();
statusLabel.setText("不能連接到聊天服務器");
return;
}
}
}
} //End class ConnectionAction
} //END CLASS
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -