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

📄 clientinterface.java

📁 Java网络编程精解/第8章数据库编程上机
💻 JAVA
字号:
//ClientInterface.java
package chatclient;

import java.io.*;
import java.awt.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;

import protocols.*;

public class ClientInterface extends JFrame
{
	private ChatClient client;
	
	//每次创建一个新的对象
	//private protocols.Message msg = new protocols.Message();
	
	JList lstClients;
	
	//保存所有窗口的引用
	protected Vector messageWindows;
	
	//提供相应的匹配
	protected Vector tabToClient;
	
	protected JButton bSend;
	protected JTextField tfMessage;
	
	protected JScrollPane scrlClients;
	
	protected JMenuBar menuBar;
	protected JMenu hlpMenu;
	protected JMenu tabMenu;
	protected JMenu fileMenu;
	protected JMenuItem exitFMenu;
	protected JMenuItem webHlpMenu;
	protected JMenuItem	helpHlpMenu;
	protected JMenuItem aboutHlpMenu;
	protected JMenuItem closeTabMenu;
	protected JMenuItem connectFMenu;
	protected JMenuItem configureFMenu;
	protected JMenuItem	disconnectFMenu;
	protected JMenuItem closeAllTabsMenu;
	
	protected JTabbedPane tbChatWindows;
	
	
	ClientInterface( ChatClient client )
	{
		super( "Fruit Cha(a)t Plate" );
		//this.setIconImage( new ImageIcon("Icons/dukeWaveRed.gif") );
		this.client = client;
		
		setUpMenu();
		setUpMainInterface();
		
		setVisible(true);
		tfMessage.requestFocus();
	}
	
	protected void setUpMenu()
	{
		exitFMenu = new JMenuItem("Exit",KeyEvent.VK_X);
		webHlpMenu = new JMenuItem("Fruit Cha(a)t on the WEB");
		helpHlpMenu = new JMenuItem("Help",KeyEvent.VK_H);
		connectFMenu = new JMenuItem("Connect",KeyEvent.VK_C);
		aboutHlpMenu = new JMenuItem("About",KeyEvent.VK_A);
		closeTabMenu = new JMenuItem( "Close Tab",KeyEvent.VK_C );
		configureFMenu = new JMenuItem("Configure Connection");
		disconnectFMenu = new JMenuItem("Disconnect",KeyEvent.VK_D);
		closeAllTabsMenu = new JMenuItem( "Close All Tabs",KeyEvent.VK_A );
		
		
		fileMenu = new JMenu("File");
		fileMenu.setMnemonic(KeyEvent.VK_F);
		fileMenu.add(connectFMenu);
		fileMenu.add(disconnectFMenu);
		fileMenu.add(configureFMenu);
		fileMenu.addSeparator();
		fileMenu.add(exitFMenu);
		
		tabMenu = new JMenu( "Tabs" );
		tabMenu.setMnemonic( KeyEvent.VK_T );
		tabMenu.add( closeTabMenu );
		tabMenu.add( closeAllTabsMenu );
		
		hlpMenu = new JMenu("Help");
		hlpMenu.setMnemonic(KeyEvent.VK_H);
		hlpMenu.add(helpHlpMenu);
		hlpMenu.addSeparator();
		hlpMenu.add(aboutHlpMenu);
		hlpMenu.add(webHlpMenu);
		
		menuBar = new JMenuBar();
		menuBar.add(fileMenu);
		menuBar.add( tabMenu );
		menuBar.add(hlpMenu);
		setJMenuBar(menuBar);
	}
	
	protected void setUpListeners()
	{
		configureFMenu.addActionListener( new ConfigureFMenu() );
		exitFMenu.addActionListener( new ExitButton() );
		helpHlpMenu.addActionListener( new HelpHlpMenu() );
		aboutHlpMenu.addActionListener( new AboutHlpMenu() );
		webHlpMenu.addActionListener( new WebHlpMenu() );
		connectFMenu.addActionListener( new ConnectFMenu() );
		disconnectFMenu.addActionListener( new DisconnectFMenu() );
		closeTabMenu.addActionListener( new CloseTabButton() );
		closeAllTabsMenu.addActionListener( new CloseAllTabsMenu() );
		
		bSend.addActionListener( new SendButton() );
		tfMessage.addActionListener( new SendMessage() );
		//tfMessage.addFocusListener( new FocusMessageField() );
		
		lstClients.addMouseListener( new SelectClient() );
		addWindowListener( new OnExit() );
	}
	
	protected void setUpProperties()
	{
		setSize(475,280);
		setResizable(false);
		
		bSend.setEnabled( false );
		tfMessage.setEnabled( false );
		
		disconnectFMenu.setEnabled( false );
		tabMenu.setEnabled( false );
		closeTabMenu.setEnabled( false );
		closeAllTabsMenu.setEnabled( false );
		
		lstClients.setFixedCellWidth(101);
		lstClients.setSelectionMode( ListSelectionModel.SINGLE_SELECTION );
		
		scrlClients = new JScrollPane( lstClients );
		scrlClients.setColumnHeaderView( new JLabel("Online Users" ) );
		
		setUpListeners();
	}
	
	protected void setUpMainInterface()
	{
		bSend = new JButton("       Send       ");
		
		tfMessage = new JTextField(32);		
		lstClients = new JList();
		
		setUpTabs();
		setUpProperties();
		
		Box displayBox = Box.createHorizontalBox();
		displayBox.add( tbChatWindows );
		displayBox.add( Box.createHorizontalStrut(3) );
		displayBox.add( scrlClients );
		
		Box commandBox = Box.createHorizontalBox();
		commandBox.add( tfMessage );
		commandBox.add( Box.createHorizontalStrut(3) );
		commandBox.add( bSend );
		
		Container cp = this.getContentPane();
		cp.setLayout( new FlowLayout(FlowLayout.LEFT) );
		cp.add( displayBox );
		cp.add( commandBox );
	}
	
	protected void setUpTabs()
	{
		messageWindows = new Vector(5,2);
		tabToClient = new Vector(5,2);
		tbChatWindows = new JTabbedPane( JTabbedPane.TOP,JTabbedPane.SCROLL_TAB_LAYOUT );
		
		//设置main room标志. 此标志不可以被停止
		messageWindows.addElement( new JTextArea(10,30) );
		((JTextArea)messageWindows.elementAt(0)).setLineWrap(true);
		((JTextArea)messageWindows.elementAt(0)).setEditable(false);		
		
		tbChatWindows.addTab( "Main Room",new JScrollPane( (JTextArea)
			messageWindows.elementAt(0),
			JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
			JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
		
		//tbChatWindows.setIconAt( 0,new ImageIcon( "Icons/Bear.gif" ) );
		//tbChatWindows.setForegroundAt( 0, Color.BLUE );
	}
	
	//同指定的朋友聊天
	void openNewTab( int friendId )
	{
		//Check if a conversation tab is already open for the friend
		//If yes then set focus to that tab
		int index = tabToClient.indexOf( new Integer( friendId ) );
		if( index != -1 )
		{
			tbChatWindows.setSelectedIndex( index );
			return;
		}
		
		messageWindows.addElement( new JTextArea(10,30) );
		tabToClient.addElement( new Integer(friendId) );
		((JTextArea)messageWindows.lastElement()).setLineWrap(true);
		((JTextArea)messageWindows.lastElement()).setEditable(false);		
		lstClients.setSelectedIndex( friendId );
		tbChatWindows.addTab( (String)lstClients.getSelectedValue(),(new JScrollPane( (JTextArea)messageWindows.lastElement() ) ) );
		
		tabMenu.setEnabled( true );
		closeTabMenu.setEnabled( true );
		closeAllTabsMenu.setEnabled( true );
	}
	
	private void showMessage( int tabSelected, String message )
	{
		((JTextArea)messageWindows.elementAt(tabSelected)).append( message );
	}
	
	void showMessage( Message userMsg )
	{
		int tabIndex = 0;
		
		if( ((Message)userMsg).audience == true )
		{
			((JTextArea)messageWindows.elementAt(tabIndex)).append( ((Message)userMsg).message + "\n");
		}
		else
		{
			tabIndex = tabToClient.indexOf( new Integer(((Message)userMsg).senderId) );
			//if( tabIndex == -1 )
			//JOptionPane.showMessageDialog( client.window, "Index Not Found", "Index Error", JOptionPane.INFORMATION_MESSAGE );				
			((JTextArea)messageWindows.elementAt(tabIndex+1)).append( ((Message)userMsg).message + "\n");
		}
		//JScrollBar hBar = scrlMessages.getVerticalScrollBar();
		//hBar.setValue( hBar.getMaximum() );
	}
	
	protected void sendMessage()
	{
		String str = tfMessage.getText();
		int tabSelected = tbChatWindows.getSelectedIndex();
		
		if( str.length() != 0 )
		{
			try
			{
				if( tabSelected == 0 )
				{
					client.sendPublicMessage( str );
				}
				else
				{
					Integer clientIndex = (Integer)tabToClient.elementAt( tabSelected-1 );
					client.sendPrivateMessage( clientIndex.intValue(),str );
					((JTextArea)messageWindows.elementAt( tabSelected )).append(client.Name + " says > " + str + "\n");
				}
			}
			catch( IOException io_ex )
			{
				showMessage( tabSelected,"\n\nCannot Send Message...\n\n" );
			}
			tfMessage.setText("");
		}
	}
	
	//除了主聊天室,关闭其他的聊天
	protected void closeAllTabs()
	{
		int index = 1;
		while( index != tbChatWindows.getTabCount() )
		{
			tbChatWindows.removeTabAt( index );
			messageWindows.removeElementAt( index );
		}
		tabToClient.clear();
		
		tabMenu.setEnabled( false );
		closeTabMenu.setEnabled( false );
		closeAllTabsMenu.setEnabled( false );
	}
	
	//表示断开连接
	synchronized void notifyDisconnect()
	{
		connectFMenu.setEnabled( true );
		disconnectFMenu.setEnabled( false );
		tfMessage.setEnabled( false );
		bSend.setEnabled( false );
		closeAllTabs();
		//lstClients.updateUI();
		lstClients.setEnabled( false );
	}
	
	void notifyUserLeft( String clientName )
	{
		int friendId = client.clientList.indexOf( clientName );
		int index = tabToClient.indexOf( new Integer( friendId ) );
		
		//如果没有任何的标志对于这个用户
		if( index == -1 )
			return;
		
		JOptionPane.showMessageDialog( client.window,clientName+" Has Logged Out",
			"User Left",JOptionPane.INFORMATION_MESSAGE );
		
		tbChatWindows.removeTabAt( index+1 );
		messageWindows.removeElementAt( index+1 );
		tabToClient.removeElementAt( index );
		
		if( tbChatWindows.getTabCount() == 1 )
		{
			tabMenu.setEnabled( false );
			closeTabMenu.setEnabled( false );
			closeAllTabsMenu.setEnabled( false );
		}					
	}
	
	class OnExit extends WindowAdapter implements WindowListener
	{
		public void windowClosing( WindowEvent we )
		{
			client.shutDown();
		}
		
		public void windowActivated(WindowEvent e)
		{
			tfMessage.requestFocus();
		}
	}
	
	class CloseTabButton implements ActionListener
	{
		public void actionPerformed( ActionEvent e )
		{
			int index = tbChatWindows.getSelectedIndex();
			if( index !=0 )
			{
				tbChatWindows.removeTabAt( index );
				messageWindows.removeElementAt( index );
				tabToClient.removeElementAt( index-1 );
				
				if( tbChatWindows.getTabCount() == 1 )
				{
					tabMenu.setEnabled( false );
					closeTabMenu.setEnabled( false );
					closeAllTabsMenu.setEnabled( false );
				}					
			}
		}
	}
	
	class CloseAllTabsMenu implements ActionListener
	{
		public void actionPerformed( ActionEvent e )
		{
			closeAllTabs();
		}
	}
	
	class ExitButton implements ActionListener
	{
		public void actionPerformed( ActionEvent e )
		{
			client.shutDown();
		}
	}
	
	class SendButton implements ActionListener
	{
		public void actionPerformed( ActionEvent e )
		{
			sendMessage();
			tfMessage.requestFocus();
		}
	}
	
	class SendMessage implements ActionListener
	{
		public void actionPerformed( ActionEvent e )
		{
			sendMessage();
		}
	}
	
	class SelectClient extends MouseAdapter implements MouseListener
	{
		public void mouseClicked(MouseEvent e)
		{
			if( !lstClients.isSelectionEmpty() )
			{
				if ( e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1 )
				{
					openNewTab( lstClients.getSelectedIndex() );
					client.sendChatRequest( lstClients.getSelectedIndex() );
				}
			}
		}
	}
	
	class ConfigureFMenu implements ActionListener
	{
		public void actionPerformed( ActionEvent e )
		{
			ConfigureServerInfo serverDialog = new ConfigureServerInfo();
		}
	}
	
	class AboutHlpMenu implements ActionListener
	{
		public void actionPerformed( ActionEvent e )
		{
			JOptionPane.showMessageDialog( client.window, "Fruit Cha(a)t Server" 
				+"\nVersion 0.7 \nThis software is distributed under the GPL Liscence",
				"About Fruit Cha(a)t", JOptionPane.INFORMATION_MESSAGE );
		}
	}
	
	class HelpHlpMenu implements ActionListener
	{
		public void actionPerformed( ActionEvent e )
		{
			/* 提供帮助*/
		}
	}
				
	class WebHlpMenu implements ActionListener
	{
		public void actionPerformed( ActionEvent e )
		{
			JOptionPane.showMessageDialog( client.window, "For free source code visist www.akbani.20m.com.", "Fruit Cha(a)t on the WEB", JOptionPane.INFORMATION_MESSAGE );
		}
	}
	
	class ConnectFMenu implements ActionListener
	{
		public void actionPerformed( ActionEvent e )
		{
			do
			{
				client.Name = JOptionPane.showInputDialog( client.window,"Enter Login Name ?");
			}
			while( (client.Name==null || client.Name.length()==0) );
			
			if( client.connectToServer() )
			{
				client.window.setTitle( "Fruit Cha(a)t Plate <--> " + client.Name );
				
				if( lstClients.getModel() != client.clientList )
				{
					lstClients.setModel( client.clientList );
				}
				
				connectFMenu.setEnabled( false );
				disconnectFMenu.setEnabled( true );			
				tfMessage.setEnabled( true );
				bSend.setEnabled( true );
				lstClients.setEnabled( true );
				((JTextArea)messageWindows.elementAt(0)).setText("");
				tfMessage.requestFocus();
			}
		}
	}
	
	
	class DisconnectFMenu implements ActionListener
	{
		public void actionPerformed( ActionEvent e )
		{
			client.disconnectFromServer( true );
			notifyDisconnect();
		}
	}

	class FocusMessageField extends FocusAdapter implements FocusListener
	{
	public void focusLost( FocusEvent fe )
	{
	if(!( fe.getOppositeComponent() instanceof JMenuItem ))
	{
				tfMessage.requestFocus();
				}
				}
				}
	*/
	//显示并且设置相应的配置
	class ConfigureServerInfo extends JDialog
	{
		JButton bSave = new JButton("Save");
		JButton bCancel = new JButton("Cancel");
		JLabel lbServer = new JLabel("Server Name : ");
		JTextField tfServerName = new JTextField(10);
		JLabel lbPort = new JLabel("Port No :            ");
		JTextField tfPortNo = new JTextField(6);
		
		ConfigureServerInfo()
		{
			super(client.window,"Configure Connection",true);
			
			Box buttonBox = Box.createHorizontalBox();
			buttonBox.add( Box.createHorizontalStrut(50) );
			buttonBox.add(bSave);
			//buttonBox.add( Box.createHorizontalStrut(10) );
			buttonBox.add(bCancel);
			
			Container jcp = this.getContentPane();
			jcp.setLayout( new FlowLayout(FlowLayout.LEFT) );
			jcp.add(lbServer);
			jcp.add(tfServerName);
			jcp.add(lbPort);
			jcp.add(tfPortNo);
			//jcp.add( commandBox );
			jcp.add( buttonBox );
			
			bSave.addActionListener( new SaveButton() );
			bCancel.addActionListener( new CancelButton() );
			
			client.getConfiguration();
			
			tfServerName.setText( client.serverAddress );
			tfPortNo.setText( Integer.toString( client.serverSocketNumber ) );
			
			this.setSize(230,115);
			
			//将对话框放置在中心位置
			Point position = client.window.getLocation();
			position.x = position.x + (client.window.getWidth()/2) - (this.getWidth()/2);
			position.y = position.y + (client.window.getHeight()/2) - (this.getHeight()/2);
			this.setLocation( position );
			
			this.setVisible(true);
			this.setResizable( false );			
		}
		
		class SaveButton implements ActionListener
		{
			public void actionPerformed( ActionEvent e )
			{
				client.setConfiguration( tfServerName.getText(), Integer.parseInt(tfPortNo.getText()) );
				dispose();
			}
		}
		
		class CancelButton implements ActionListener
		{
			public void actionPerformed( ActionEvent e )
			{
				dispose();
			}
		}
		
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -