⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 chatclient.java

📁 编了一个简单的聊天器
💻 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();
	}
	
	//客户端界面类构造函数
	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);
	}
	
	//处理 退出 的函数
	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);

		//发送消息 按钮
		c.weightx = 0;
		c.gridwidth = GridBagConstraints.REMAINDER;
		sendButton =
			new JButton(
				new ImageIcon(getClass().getResource("images/send.gif")));
		sendButton.setToolTipText("发送消息");
		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);

		//发送给 标签
		c.weightx = 0;
		c.fill = GridBagConstraints.HORIZONTAL;
		c.gridheight = 1;
		JLabel sendtoLabel = new JLabel("发送给:");
		contentPane.add(sendtoLabel, c);

		//用户 下拉列表框
		usersBox = new JComboBox();
		usersBox.setBackground(Color.WHITE);
		usersBox.addItem("所有用户");
		contentPane.add(usersBox, c);

		//状态栏
		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();
		}
	}

	//执行连接操作
	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);
	}

//**********************************************************************
//以下四个函数是实现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则发送消息
	protected void addKeymapBindings() {
		Keymap keymap =
			JTextComponent.addKeymap("MyBindings", inputBox.getKeymap());

		Action action = null;
		KeyStroke key = null;

		//用户在消息输入框中按回车发送消息
		action = new AbstractAction() {
			public void actionPerformed(ActionEvent evt) {
				sendMessage();
			}
		};
		key = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
		keymap.addActionForKeyStroke(key, action);

		//Ctrl+Enter则实现换行
		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);
	}
	
	//从消息框取得消息内容,发送消息函数
	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())) {//发送给所有用户
					try {
						server.chat(my_name, message);
					} catch (java.rmi.RemoteException ex) {
						ex.printStackTrace();
					}
				} else {//私聊,发给所选用户
					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 + -