/** * @author Gerard Whyte * Alias: Gearoid De Faoite * Copyright (C) 2002 Gerard Whyte * * Created: 19/11/2002 * Last Modified: 14/08/2004 * * ChatClient uses RNAP App to provide a simple chat interface. * Individual ChatClients connect to a RNAP Server and messages are * passed between the ChatClients. * * v0.7 * */ import java.awt.*; import java.awt.event.*; import javax.swing.*; public class ChatClient extends RNAP_App { private static ChatClient client; private static JTextArea outputBox; // Output Screen private static JTextField inputBox; // Input Text Field private static JList userList; // User List. private static DefaultListModel listModel; // List of usernames. private static JScrollPane scrollPane; private static JDialog loginScreen; private static JTextField username; private static JPasswordField password; private static JTextField serverName; private static JTextField scriptName; private String user; private static String scriptURL; private static String rnapServer; /** * Starts the program by creating and initialising the client. * Control is passed to the client by init() and control is * specified by the client's run() method. */ public static void main( String args[] ) { try { UIManager.setLookAndFeel( UIManager.getCrossPlatformLookAndFeelClassName() ); } catch ( Exception e ) { } //Create the top-level container and add contents to it. JFrame frame = new JFrame("RNAP ChatClient"); frame.getContentPane().add( createComponents(), BorderLayout.CENTER); //Finish setting up the frame, and show it. frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { client.leave(); } }); frame.pack(); frame.setVisible(true); // Create a Dialog to ask for information on the server and login info.. loginScreen = new JDialog( frame, "Login Please", true ); loginScreen.getContentPane().add( createDialogContents() ); loginScreen.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { setServerInfo(); } }); loginScreen.pack(); loginScreen.setLocationRelativeTo( frame ); loginScreen.setVisible(true); } /** * Called after the client has been initialised. * Defines what the ChatClient does. */ public void run() { // Logs the user in with the given password. if ( login( username.getText(), new String( password.getPassword() ), "ChatClient" ) ) { // Set your username to send messages. user = username.getText(); // Send a message to everybody telling them you're here. sendMessage( null, new RNAP_Login( user, "0", "ChatClient" ) ); // Lose the dialog. loginScreen.dispose(); } // Something bad happened, better warn the user. else { JOptionPane.showMessageDialog( loginScreen, "Please check your username and password.", "Login Failed", JOptionPane.ERROR_MESSAGE); } } /** * Creates the contents of the Login Dialog. */ private static JComponent createDialogContents() { // The textfield where the name for the RNAP server is entered. JLabel serverBox = new JLabel( "Server Name: "); serverName = new JTextField( 10 ); // The textfield where the URL for the script, that gives info about // running RNAP servers, is entered. JLabel scriptBox = new JLabel( "Script Url: "); scriptName = new JTextField( 20 ); // The textfield where the username is entered. JLabel userBox = new JLabel( "Username: "); username = new JTextField( 10 ); // The password field where the password is entered. JLabel passBox = new JLabel( "Password: "); password = new JPasswordField( 10 ); // The button for logging in. JButton go = new JButton( "Login" ); go.setMnemonic( KeyEvent.VK_L); go.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { setServerInfo(); } }); // Create the panel that will hold all the components. JPanel pane = new JPanel(); GridBagLayout gridBag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); pane.setLayout( gridBag ); // Set the layout of the top half of the dialog. c.gridy = 0; c.fill = GridBagConstraints.NONE; c.anchor = GridBagConstraints.WEST; pane.add( serverBox, c ); pane.add( serverName, c ); pane.add( scriptBox, c ); pane.add( scriptName, c ); // Set the layout for the bottom half of the dialog. c.gridy = 1; pane.add( userBox, c ); pane.add( username, c ); pane.add( passBox, c ); pane.add( password, c ); pane.add( go, c ); return pane; } /** * Set the information for which server to connect to. */ private static void setServerInfo() { // Set the URL for the script. scriptURL = scriptName.getText(); // Make sure that the scriptURL has some sort of useful url. if ( scriptURL.equals("") ) scriptURL = "http://gerardwhyte.net/programs/tools/chatclient/database.php"; // Set the name of the RNAP server. rnapServer = serverName.getText(); // Make sure that the name of the server is possibly useful. if ( rnapServer.equals("") ) rnapServer = "chatclient"; // Make your client and start it up. Control passes to the run() // method in the ChatClient. client = new ChatClient(); client.initRNAP(); } /** * Create the contents of the window. */ private static JComponent createComponents() { // Output Screen where all the text is displayed. // It is inside a Scrolling pane. outputBox = new JTextArea( 30, 50 ); outputBox.setEditable(false); outputBox.setLineWrap(true); outputBox.setWrapStyleWord(true); scrollPane = new JScrollPane( outputBox, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER ); // User list contains a list of all connected users. listModel = new DefaultListModel(); userList = new JList( listModel ); userList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); userList.setSelectedIndex(0); JScrollPane scrollList = new JScrollPane( userList ); // Input box where the text is entered. inputBox = new JTextField( 50 ); inputBox.addKeyListener( new KeyListener() { // Looks after any keyboard events to do with the inputBox public void keyTyped(KeyEvent e) { } public void keyReleased(KeyEvent e) { } public void keyPressed(KeyEvent e) { int kc = e.getKeyCode(); switch ( kc ) { // If return is pressed, it sends a message if needed case KeyEvent.VK_ENTER: client.messageReady(); break; } } }); // Button used to send a message. JButton send = new JButton( "Send" ); send.setMnemonic( KeyEvent.VK_S); send.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { // Send a message if needed. client.messageReady(); } }); // Button used to quit application. JButton quit = new JButton( "Quit" ); quit.setMnemonic( KeyEvent.VK_Q); quit.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { client.leave(); } }); // Create the panel that will contain all the components. JPanel pane = new JPanel(); GridBagConstraints c = new GridBagConstraints(); pane.setLayout( new GridBagLayout() ); // Set the layout of the Output Screen. c.fill = GridBagConstraints.BOTH; c.weightx = 1.0; c.weighty = 1.0; c.gridx = 0; c.gridy = 0; pane.add( scrollPane, c ); // Set the layout of the User List. c.fill = GridBagConstraints.VERTICAL; c.weightx = 0.0; c.weighty = 1.0; c.gridx = 1; c.gridy = 0; pane.add( scrollList, c ); // Create a panel for the bottom line to help layout. JPanel bottomLine = new JPanel(); bottomLine.setLayout( new GridBagLayout() ); GridBagConstraints blc = new GridBagConstraints(); // Set the layout of the Input box on the bottom line. blc.fill = GridBagConstraints.HORIZONTAL; blc.weightx = 1.0; blc.gridx = 0; bottomLine.add( inputBox, blc ); // Set the layout of the Send button on the bottom line. blc.fill = GridBagConstraints.NONE; blc.weightx = 0.0; blc.gridx = 1; // Set the layout of the Quit button on the bottom line. bottomLine.add( send, blc ); blc.gridx = 2; bottomLine.add( quit, blc ); // Set the layout of the bottom line. c.fill = GridBagConstraints.HORIZONTAL; c.weightx = 1.0; c.weighty = 0.0; c.gridx = 0; c.gridy = 1; c.gridwidth = 2; pane.add( bottomLine, c ); return pane; } /** * Checks for a message and if there is one ready, sends it. */ private void messageReady() { // Check for a message. String inputMsg = inputBox.getText(); // If there is one, clear the input and send it. if ( !inputMsg.equals("") ) { inputBox.setText(""); // If there is no user in the list selected // send it to everybody. if ( userList.isSelectionEmpty() ) sendMessage( null, inputMsg ); // A person is selected, only send it to that user. else { String person = (String)userList.getSelectedValue(); sendMessage( person, inputMsg ); // Display it as a sent private message. addOutput( "-->" + person + " {" + inputMsg + "}\n" ); // Make sure nobody is selected. userList.clearSelection(); } } } /** * Parses the message that was received and decides what to do. */ public void messageReceived( String sender, String recipient, Object contents ) { // Check if the message is of type RNAP_Login RNAP_Login loginInfo = new RNAP_Login( "", "", "" ); String testCaseN = loginInfo.getClass().getName(); String contentsN = contents.getClass().getName(); // If it is, see if you want to add the user to the list. if ( contentsN.equals( testCaseN ) ) { loginInfo = (RNAP_Login) contents; if ( !sender.equals( user ) ) // No point in adding to the userlist unless you're a different user { if ( loginInfo.pass.equals( "0" ) && !listModel.contains( loginInfo.name ) ) // Make sure that you're supposed to add it and that it's not // already in the list. { // Better tell them about yourself. sendMessage( loginInfo.name, new RNAP_Login( user, "0", "ChatClient" ) ); listModel.addElement( loginInfo.name ); } // The user has left the building, remove it from the list. else if ( loginInfo.pass.equals( "1" ) ) { listModel.removeElement( loginInfo.name ); } } // Make sure nobody is selected after the messages is sent. userList.clearSelection(); } // You have a message!! Beep. Better display it. else { String temp = (String)contents; // It's a private message if ( user.equals( recipient) ) addOutput( "<--" + sender + " {" + temp + "}\n" ); // It's a public message else addOutput( "[" + sender + "] " + temp + "\n" ); } } /** * Add the message to the output screen */ private void addOutput( String output ) { outputBox.append( output ); } /** * Quit now! */ private void leave() { // You're leaving, better tell everybody else then. client.sendMessage( null, new RNAP_Login( client.user, "1", "ChatClient" ) ); System.exit(0); } /** * Gets the name of the RNAP Server. */ public String getServerName() { return rnapServer; } /** * Gets the URL for the script which tells you what servers are running */ public String getScriptURL() { return scriptURL; } }