Revision: 438 http://skycastle.svn.sourceforge.net/skycastle/?rev=438&view=rev Author: zzorn Date: 2008-04-03 15:16:52 -0700 (Thu, 03 Apr 2008) Log Message: ----------- Moved previous 3D chat client to a 'hardcoded' pacakge. Removed Paths: ------------- trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatClient.java trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatInputHandler.java trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatOutputHandler.java trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatUserHandler.java trunk/skycastle/modules/client/src/main/java/org/skycastle/client/Simple3DClient.java Deleted: trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatClient.java =================================================================== --- trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatClient.java 2008-04-03 22:14:54 UTC (rev 437) +++ trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatClient.java 2008-04-03 22:16:52 UTC (rev 438) @@ -1,590 +0,0 @@ -/* ========================================================================= - * - * This file is part of Skycastle. - * - * Skycastle is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Skycastle is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with Skycastle; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ========================================================================= */ - -package org.skycastle.client; - -import com.sun.sgs.client.ClientChannel; -import com.sun.sgs.client.ClientChannelListener; -import com.sun.sgs.client.SessionId; -import com.sun.sgs.client.simple.SimpleClient; -import com.sun.sgs.client.simple.SimpleClientListener; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.math.BigInteger; -import java.net.PasswordAuthentication; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.Random; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Chat client. This client connects to the SGS Skycastle server and processes chat messages on a channel. Until we have - * implemented a real chat protocol, the client understands the following special messages. - * <p/> - * From server: - * <p/> - * JOIN [sessionId] [nickname] - User with nickname and sessionId has joined the chat. - * <p/> - * QUIT [sessionId] [nickname] - User with nickname and sessionId has left the chat. - * <p/> - * From client: - * <p/> - * NICK [newNickname] - User has changed nickname (TODO: this is very sloppy, with no protection whatsoever against - * duplicates). - * <p/> - * TODO: - * <p/> - * The channel-based chat has some issues since the communication is effectively client-to-client, even though the - * server acts as the hub for dispatching messages.. It is difficult to enforce any rules and protect clients from - * invalid messages. The state of the network may be difficult to keep consistent across clients (for example, when - * mapping sessions to nicknames. Each client has to do its own validity checking and enforce unique nicknames.). See - * also SkycastleServerListener. - */ -public class ChatClient - implements SimpleClientListener, ClientChannelListener -{ - - //====================================================================== - // Private Fields - - /** - * The random number generator for login names. - */ - private final Random random = new Random(); - - //====================================================================== - // Non-Private Fields - - /** - * The {@link SimpleClient} instance for this client. - */ - protected final SimpleClient simpleClient; - - /** - * Username. A placeholder until the system can handle actual user accounts. - */ - protected String username = ""; - - /** - * Map that associates a channel name with a {@link ClientChannel}. - */ - protected final Map<String, ClientChannel> channelsByName = - new HashMap<String, ClientChannel>(); - - /** - * Map that associates a session ID with a nickname. - */ - protected final Map<SessionId, String> nicknamesById = - new HashMap<SessionId, String>(); - - /** - * Handler for chat messages that should be displayed. - */ - protected ChatOutputHandler outputHandler = null; - - /** - * Handler for chat user events. - */ - protected ChatUserHandler userHandler; - - //====================================================================== - // Public Constants - - /** - * The name of the general chat channel: '{@value #GENERAL_CHAT}' - */ - public static final String GENERAL_CHAT = "General"; - - /** - * The name of the host property. - */ - public static final String HOST_PROPERTY = "skycastle.host"; - - /** - * The default hostname. - */ - public static final String DEFAULT_HOST = "localhost"; - - /** - * The name of the port property. - */ - public static final String PORT_PROPERTY = "skycastle.port"; - - /** - * The default port. - */ - public static final String DEFAULT_PORT = "1139"; - - /** - * The message encoding. - */ - public static final String MESSAGE_CHARSET = "UTF-8"; - - //====================================================================== - // Private Constants - - /** - * The version of the serialized form of this class. - */ - private static final long serialVersionUID = 1L; - - /** - * The {@link Logger} for this class. - */ - private static final Logger logger = - Logger.getLogger( ChatClient.class.getName() ); - - //====================================================================== - // Public Methods - - //---------------------------------------------------------------------- - // Constructors - - /** - * Create a new chat client. - */ - public ChatClient() - { - simpleClient = new SimpleClient( this ); - // TODO: Placeholder until we have something real. - setUsername( "guest-" + random.nextInt( 1000 ) ); - } - - - /** - * Create a new chat client. - * - * @param initOutputHandler Handler for chat messages to be displayed. - */ - public ChatClient( ChatOutputHandler initOutputHandler, - ChatUserHandler initUserHandler ) - { - this(); - outputHandler = initOutputHandler; - userHandler = initUserHandler; - } - - //---------------------------------------------------------------------- - // ClientChannelListener Implementation - - /** - * {@inheritDoc} - * <p/> - * This is called when a message arrives on a channel. - */ - public void receivedMessage( ClientChannel channel, - SessionId sender, - byte[] message ) - { - String msg = decodeString( message ); - logger.log( Level.INFO, "Channel message: [" + channel.getName() - + ", " + sender + "] " + msg ); - if ( outputHandler != null ) - { - if ( sender != null ) - { - // Message from client. - /* Do some quick and dirty server message handling until we - have implemented a real chat protocol. */ - String clientName = nicknamesById.get( sender ); - if ( clientName != null ) - { - /* Change nickname. - NICK <nickname> */ - /* ----- This doesn't work well yet ----- // - if (msg.startsWith("NICK")) - { - final String[] parts = msg.split(" "); - if (parts.length >= 2) - { - String newNick = parts[1]; - nicknamesById.put(sender, newNick); - getChatOutputHandler().appendChatOutput(null, - clientName + " changed nickname to " - + newNick + "."); - getChatUserHandler().removeChatUser(clientName); - getChatUserHandler().addChatUser(newNick); - } - } else - // ----- */ - getChatOutputHandler().appendChatOutput( clientName, msg ); - } - else - { - getChatOutputHandler().appendChatOutput( null, - "UNNAMED-client: " + msg ); - } - } - else - { - // Message from server. - receivedMessage( message ); - } - } - } - - - /** - * {@inheritDoc} - * <p/> - * This is called when the user leaves a channel. - */ - public void leftChannel( ClientChannel channel ) - { - channelsByName.remove( channel.getName() ); - logger.log( Level.INFO, "Left channel: " + channel.getName() ); - // TODO: Let the user know. - } - - //---------------------------------------------------------------------- - // ServerSessionListener Implementation - - /** - * {@inheritDoc} - * <p/> - * This is called when the user joins a channel. - */ - public ClientChannelListener joinedChannel( ClientChannel channel ) - { - channelsByName.put( channel.getName(), channel ); - logger.log( Level.INFO, "Joined channel: " + channel.getName() ); - // TODO: Let the user know. - return this; - } - - - /** - * {@inheritDoc} - * <p/> - * This is called when the client receives a message from the server. - */ - public void receivedMessage( byte[] message ) - { - String msg = decodeString( message ); - logger.log( Level.INFO, "Message from server: " + msg ); - /* Do some quick and dirty server message handling until we - have implemented a real chat protocol. */ - if ( msg.startsWith( "JOIN" ) ) - { - /* Let users know that a client has joined the chat. - JOIN <sessionId> <nickname> */ - final String[] parts = msg.split( " " ); - if ( parts.length >= 3 ) - { - SessionId senderId = - SessionId.fromBytes( decodeHexString( parts[ 1 ] ) ); - nicknamesById.put( senderId, parts[ 2 ] ); - getChatOutputHandler().appendChatOutput( null, parts[ 2 ] - + " joined the chat." ); - getChatUserHandler().addChatUser( parts[ 2 ] ); - } - } - else if ( msg.startsWith( "QUIT" ) ) - { - /* Let users know that a client has left the chat. - QUIT <sessionId> <nickname> */ - final String[] parts = msg.split( " " ); - if ( parts.length >= 3 ) - { - SessionId senderId = - SessionId.fromBytes( decodeHexString( parts[ 1 ] ) ); - String victim = nicknamesById.get( senderId ); - if ( victim != null ) - { - nicknamesById.remove( senderId ); - getChatOutputHandler().appendChatOutput( null, - victim + " left the chat." ); - getChatUserHandler().removeChatUser( parts[ 2 ] ); - } - } - } - else - { - getChatOutputHandler().appendChatOutput( null, - "Server: " + msg ); - } - } - - - /** - * {@inheritDoc} - * <p/> - * This is called when reconnection is attempted. - */ - public void reconnecting() - { - logger.log( Level.INFO, "Reconnecting." ); - // TODO: Let the user know. - } - - - /** - * {@inheritDoc} - * <p/> - * This is called on a successful reconnect. - */ - public void reconnected() - { - logger.log( Level.INFO, "Reconnected successfully." ); - // TODO: Let the user know. - } - - - /** - * {@inheritDoc} - * <p/> - * This is called when the user is disconnected. - */ - public void disconnected( boolean graceful, String reason ) - { - logger.log( Level.INFO, "Disconnected (" + graceful + ", " + reason - + ")." ); - // TODO: Let the user know. - } - - //---------------------------------------------------------------------- - // SimpleClientListener Implementation - - /** - * {@inheritDoc} - * <p/> - * Returns dummy credentials where user is "guest-<random>" and the password is "guest." - */ - public PasswordAuthentication getPasswordAuthentication() - { - logger.log( Level.INFO, "Logging in as " + username ); - // TODO: Let the user know. - String password = "guest"; - return new PasswordAuthentication( username, password.toCharArray() ); - } - - - /** - * {@inheritDoc} - * <p/> - * This is called on a successful login. - */ - public void loggedIn() - { - logger.log( Level.INFO, "Logged in successfully." ); - // TODO: Let the user know. - } - - - /** - * {@inheritDoc} - * <p/> - * This is called on a failed login. - */ - public void loginFailed( String reason ) - { - logger.log( Level.WARNING, "Login failed (" + reason + ")!" ); - // TODO: Let the user know. - } - - //---------------------------------------------------------------------- - // Other Public Methods - - /** - * Send a message to the general chat. - * - * @param message Message to be sent. - */ - public void send( String message ) - { - ClientChannel channel = channelsByName.get( GENERAL_CHAT ); - if ( channel != null ) - { - try - { - channel.send( encodeString( message ) ); - } - catch ( IOException e ) - { - logger.log( Level.WARNING, "Could not send message on channel: " - + GENERAL_CHAT ); - } - } - else - { - logger.log( Level.WARNING, "Client is not joined to channel: " - + GENERAL_CHAT ); - } - } - - - /** - * Set the handler for chat output. - */ - public void setChatOutputHandler( ChatOutputHandler handler ) - { - outputHandler = handler; - } - - - /** - * Get the handler for local chat output. - * - * @return Handler for local chat output. - */ - public ChatOutputHandler getChatOutputHandler() - { - return outputHandler; - } - - - /** - * Set the handler for chat user events. - */ - public void setChatUserHandler( ChatUserHandler handler ) - { - userHandler = handler; - } - - - /** - * Get the handler for chat user events. - * - * @return Handler for chat user events. - */ - public ChatUserHandler getChatUserHandler() - { - return userHandler; - } - - - /** - * Get username. - */ - public String getUsername() - { - return username; - } - - - /** - * Set username. - * - * @param newUsername Username. - */ - public void setUsername( String newUsername ) - { - username = newUsername; - } - - //====================================================================== - // Protected Methods - - /** - * Initiates asynchronous login to the SGS server specified by the host and port properties. - */ - protected void login() - { - String host = System.getProperty( HOST_PROPERTY, DEFAULT_HOST ); - String port = System.getProperty( PORT_PROPERTY, DEFAULT_PORT ); - - try - { - Properties connectProps = new Properties(); - connectProps.put( "host", host ); - connectProps.put( "port", port ); - simpleClient.login( connectProps ); - } - catch ( Exception e ) - { - e.printStackTrace(); - disconnected( false, e.getMessage() ); - } - } - - - /** - * Encodes a {@code String} into an array of bytes. - * - * @param s the string to encode - * - * @return the byte array which encodes the given string - */ - protected static byte[] encodeString( String s ) - { - try - { - return s.getBytes( MESSAGE_CHARSET ); - } - catch ( UnsupportedEncodingException e ) - { - throw new Error( "Required character set " + MESSAGE_CHARSET - + " not found", e ); - } - } - - - /** - * Decodes an array of bytes into a {@code String}. - * - * @param bytes the bytes to decode - * - * @return the decoded string - */ - protected static String decodeString( byte[] bytes ) - { - try - { - return new String( bytes, MESSAGE_CHARSET ); - } - catch ( UnsupportedEncodingException e ) - { - throw new Error( "Required character set " + MESSAGE_CHARSET - + " not found", e ); - } - } - - - /** - * Encode an array of bytes into a hexadecimal string. - * - * @param bytes The bytes to be encoded. - * - * @return The encoded string. - */ - protected static String encodeHexString( byte[] bytes ) - { - BigInteger bi = new BigInteger( bytes ); - return bi.toString( 16 ); - } - - - /** - * Decode a hexadecimal string into an array of bytes. - * - * @param source The string to be decoded. - * - * @return The decoded string. - */ - protected static byte[] decodeHexString( String source ) - { - BigInteger bi = new BigInteger( source, 16 ); - return bi.toByteArray(); - } - -} Deleted: trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatInputHandler.java =================================================================== --- trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatInputHandler.java 2008-04-03 22:14:54 UTC (rev 437) +++ trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatInputHandler.java 2008-04-03 22:16:52 UTC (rev 438) @@ -1,33 +0,0 @@ -/* ========================================================================= - * - * This file is part of Skycastle. - * - * Skycastle is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Skycastle is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with Skycastle; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ========================================================================= */ - -package org.skycastle.client; - -/** - * Handler for chat text entered by the local user. - */ -public interface ChatInputHandler -{ - /** - * Process a line of chat input. - * @param chatMessage Text of the chat message. - */ - public void processChatInput(String chatMessage); -} Deleted: trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatOutputHandler.java =================================================================== --- trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatOutputHandler.java 2008-04-03 22:14:54 UTC (rev 437) +++ trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatOutputHandler.java 2008-04-03 22:16:52 UTC (rev 438) @@ -1,35 +0,0 @@ -/* ========================================================================= - * - * This file is part of Skycastle. - * - * Skycastle is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Skycastle is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with Skycastle; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ========================================================================= */ - -package org.skycastle.client; - -/** - * Handler for chat text recieved from other users. - */ -public interface ChatOutputHandler -{ - /** - * Append a line of chat output. - * - * @param who User from which the chat message has been received. - * @param chatMessage Text of the chat message. - */ - void appendChatOutput( String who, String chatMessage ); -} Deleted: trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatUserHandler.java =================================================================== --- trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatUserHandler.java 2008-04-03 22:14:54 UTC (rev 437) +++ trunk/skycastle/modules/client/src/main/java/org/skycastle/client/ChatUserHandler.java 2008-04-03 22:16:52 UTC (rev 438) @@ -1,42 +0,0 @@ -/* ========================================================================= - * - * This file is part of Skycastle. - * - * Skycastle is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Skycastle is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with Skycastle; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ========================================================================= */ - -package org.skycastle.client; - -/** - * Handler for chat user events. Classes which implement this interface handle events that pertain to users of the chat, - * such as adding a user to the chat or removing a user from the chat. - */ -public interface ChatUserHandler -{ - /** - * Add a user to the chat. - * - * @param who User to be added. - */ - void addChatUser( String who ); - - /** - * Remove a user from the chat. - * - * @param who User to be removed. - */ - void removeChatUser( String who ); -} Deleted: trunk/skycastle/modules/client/src/main/java/org/skycastle/client/Simple3DClient.java =================================================================== --- trunk/skycastle/modules/client/src/main/java/org/skycastle/client/Simple3DClient.java 2008-04-03 22:14:54 UTC (rev 437) +++ trunk/skycastle/modules/client/src/main/java/org/skycastle/client/Simple3DClient.java 2008-04-03 22:16:52 UTC (rev 438) @@ -1,550 +0,0 @@ -/* ========================================================================= - * - * This file is part of Skycastle. - * - * Skycastle is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * Skycastle is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License along - * with Skycastle; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * ========================================================================= */ - -package org.skycastle.client; - -import com.jme.app.SimpleGame; -import com.jme.bounding.BoundingBox; -import com.jme.image.Texture; -import com.jme.input.*; -import com.jme.math.Vector3f; -import com.jme.renderer.ColorRGBA; -import com.jme.renderer.Renderer; -import com.jme.scene.Controller; -import com.jme.scene.Node; -import com.jme.scene.SceneElement; -import com.jme.scene.shape.Box; -import com.jme.scene.state.LightState; -import com.jme.scene.state.TextureState; -import com.jme.util.TextureManager; -import com.jmex.awt.swingui.JMEDesktop; - -import javax.swing.*; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Simple 3D client. A simple 3D client for Skycastle. This version displays a chat window and a rotating box in the - * background. The client is based on the SimpleGame game skeleton provided by the jME (this will probably change in - * the future). Chat messages are processed by handlers which can be set using the setChatInputHandler() and - * setChatOutputHandler() methods. setChatUserHandler() is used to specify the user event handler, which at this time - * handles adding and removing user names from the list. Right now, everything is handled by the Simple3DClient itself. - */ -public class Simple3DClient - extends SimpleGame - implements ChatInputHandler, ChatOutputHandler, ChatUserHandler -{ - - //====================================================================== - // Non-Private Fields - - /** - * The color to be used as background color for the desktop. This is completely transparent right now. - */ - protected static final Color DESKTOP_BACKGROUND_COLOR = new Color( - 0, 1, 0, 0.0f ); - - /** - * Keyboard look input handler. - */ - protected KeyboardLookHandler lookHandler; - /** - * Scene node for the GUI. - */ - protected Node guiNode; - /** - * JME desktop on which the GUI will be shown. - */ - protected JMEDesktop desktop; - /** - * Frame containing the chat UI. - */ - protected JInternalFrame chatFrame; - /** - * Text field used for chat input. - */ - protected JTextField chatInput; - /** - * Text pane used for chat output. - */ - protected JTextPane chatOutput; - /** - * List model for the chat user list. - */ - protected DefaultListModel chatUserListModel; - /** - * List view used for the chat user list. - */ - protected JList chatUserList; - /** - * Handler for incoming local chat messages. - */ - protected ChatInputHandler chatInputHandler; - /** - * Handler for chat messages that should be displayed. - */ - protected ChatOutputHandler chatOutputHandler; - /** - * Handler for chat user events. - */ - protected ChatUserHandler chatUserHandler; - /** - * Chat client. - */ - protected ChatClient chatClient; - - //====================================================================== - // Private Constants - - private static final Logger LOGGER = Logger.getLogger( Simple3DClient.class.getName() ); - - //====================================================================== - // Public Methods - - //---------------------------------------------------------------------- - // Main Method - - /** - * Start everything. - */ - public static void main( String[] args ) - { - LOGGER.log( Level.INFO, "Skycastle 3D Client starting up." ); - - // Do not show logging output below the WARNING level (JME outputs a lot of debugging info at INFO level). - // This way the console output is a bit more relevant. - LOGGER.setLevel( Level.WARNING ); - - Simple3DClient client = new Simple3DClient(); - client.start(); - } - - //---------------------------------------------------------------------- - // ChatInputHandler Implementation - - /** - * Process a line of input from the chat text field. This gets called in the Swing thread when the enters a line of - * chat text. Implemented from ChatInputHandler. - * - * @param chatMessage Text of the chat message. - */ - public void processChatInput( String chatMessage ) - { - // Print to the console and show in chat output window. - LOGGER.log( Level.INFO, "chat: " + chatMessage ); - getChatOutputHandler().appendChatOutput( chatClient.getUsername(), - chatMessage ); - chatClient.send( chatMessage ); - } - - //---------------------------------------------------------------------- - // ChatOutputHandler Implementation - - /** - * Append a line of chat text to the chat output area. Implemented from ChatOutputHandler. - * - * @param who User from which the chat message has been received. - * @param chatMessage Text of the chat message. - */ - public void appendChatOutput( String who, String chatMessage ) - { - // Show in chat output window. - if ( who != null ) - { - chatOutput.setText( chatOutput.getText() + "\n" - + "<" + who + "> " + chatMessage ); - } - else - { - chatOutput.setText( chatOutput.getText() + "\n" + chatMessage ); - } - } - - //---------------------------------------------------------------------- - // ChatUserHandler Implementation - - /** - * Add a user to the chat. - * - * @param who User to be added. - */ - public void addChatUser( String who ) - { - boolean found = false; - int i = 0; - while ( !found - && ( i < chatUserListModel.size() ) ) - { - if ( chatUserListModel.elementAt( i ).equals( who ) ) - { - found = true; - } - else - { - i++; - } - } - if ( found ) - { - LOGGER.log( Level.WARNING, "User '" + who + "' is already in the list!" ); - return; - } - chatUserListModel.addElement( who ); - } - - - /** - * Remove a user from the chat. - * - * @param who User to be removed. - */ - public void removeChatUser( String who ) - { - boolean found = false; - int i = 0; - while ( !found - && ( i < chatUserListModel.size() ) ) - { - if ( chatUserListModel.elementAt( i ).equals( who ) ) - { - found = true; - } - else - { - i++; - } - } - if ( found ) - { - chatUserListModel.removeElementAt( i ); - } - else - { - LOGGER.log( Level.WARNING, "User '" + who + "' is not in the list!" ); - } - } - - //---------------------------------------------------------------------- - // Other Public Methods - - /** - * Set up key bindings. - */ - public void initKeyBindings() - { - /* Remove some keybindings established by BaseSimpleGame, since they - are needed for chatting. - TODO: Find a more elegant solution. Maybe bind/rebind depending on - focus, or handling these during update. - Eventually, we may also need to implement our own base game - class. - */ - KeyBindingManager.getKeyBindingManager().remove( "toggle_pause" ); - KeyBindingManager.getKeyBindingManager().remove( "step" ); - KeyBindingManager.getKeyBindingManager().remove( "toggle_wire" ); - KeyBindingManager.getKeyBindingManager().remove( "toggle_lights" ); - KeyBindingManager.getKeyBindingManager().remove( "toggle_bounds" ); - KeyBindingManager.getKeyBindingManager().remove( "toggle_normals" ); - KeyBindingManager.getKeyBindingManager().remove( "camera_out" ); - KeyBindingManager.getKeyBindingManager().remove( "mem_report" ); - - // Bind the BaseSimpleGame functions to other keys. - KeyBindingManager.getKeyBindingManager().set( "toggle_pause", KeyInput.KEY_F4 ); - KeyBindingManager.getKeyBindingManager().set( "step", KeyInput.KEY_F5 ); - KeyBindingManager.getKeyBindingManager().set( "toggle_wire", KeyInput.KEY_F6 ); - KeyBindingManager.getKeyBindingManager().set( "toggle_lights", KeyInput.KEY_F7 ); - KeyBindingManager.getKeyBindingManager().set( "toggle_bounds", KeyInput.KEY_F8 ); - KeyBindingManager.getKeyBindingManager().set( "toggle_normals", KeyInput.KEY_F9 ); - KeyBindingManager.getKeyBindingManager().set( "camera_out", KeyInput.KEY_F10 ); - KeyBindingManager.getKeyBindingManager().set( "mem_report", KeyInput.KEY_F11 ); - } - - - /** - * Set the handlers for chat events. - * - * @param inputHandler Handler for chat input entered by the local user. - * @param outputHandler Handler for chat message sto be displayed. - * @param userHandler Handler for chat user events. - */ - public void setChatHandlers( ChatInputHandler inputHandler, - ChatOutputHandler outputHandler, ChatUserHandler userHandler ) - { - setChatInputHandler( inputHandler ); - setChatOutputHandler( outputHandler ); - setChatUserHandler( userHandler ); - } - - - /** - * Set the handler for local chat input. - */ - public void setChatInputHandler( ChatInputHandler handler ) - { - chatInputHandler = handler; - } - - - /** - * Get the handler for local chat input. - * - * @return Handler for local chat input. - */ - public ChatInputHandler getChatInputHandler() - { - return chatInputHandler; - } - - - /** - * Set the handler for chat output. - */ - public void setChatOutputHandler( ChatOutputHandler handler ) - { - chatOutputHandler = handler; - } - - - /** - * Get the handler for local chat output. - * - * @return Handler for local chat output. - */ - public ChatOutputHandler getChatOutputHandler() - { - return chatOutputHandler; - } - - - /** - * Set the handler for chat user events. - */ - public void setChatUserHandler( ChatUserHandler handler ) - { - chatUserHandler = handler; - } - - - /** - * Get the handler for chat user events. - * - * @return Handler for chat user events. - */ - public ChatUserHandler getChatUserHandler() - { - return chatUserHandler; - } - - //====================================================================== - // Protected Methods - - /** - * Create the UI. Create the elements of the Swing UI. - */ - protected void initUI() - { - /// JME part of the GUI creation. - guiNode = new Node( "gui" ); - guiNode.setRenderQueueMode( Renderer.QUEUE_ORTHO ); - - desktop = new JMEDesktop( - "desktop", - display.getWidth(), - display.getHeight(), - input - ); - guiNode.attachChild( desktop ); - desktop.getLocalTranslation().set( - display.getWidth() / 2, - display.getHeight() / 2, 0 - ); - - // AWT/Swing part of the GUI creation. - desktop.getJDesktop().setBackground( DESKTOP_BACKGROUND_COLOR ); - - chatFrame = new JInternalFrame( "Chat" ); - chatFrame.setLocation( 10, 10 ); - chatFrame.setResizable( true ); - Container contentPane = chatFrame.getContentPane(); - contentPane.setLayout( new BorderLayout() ); - - chatOutput = new JTextPane(); - chatOutput.setPreferredSize( new Dimension( 400, 300 ) ); - chatOutput.setEditable( false ); - chatOutput.setText( "Welcome to Skycastle!" ); - - final JScrollPane scrollPane = new JScrollPane( chatOutput ); - - chatUserListModel = new DefaultListModel(); - - chatUserList = new JList( chatUserListModel ); - chatUserList.setPreferredSize( new Dimension( 80, 300 ) ); - - final JSplitPane splitPane = new JSplitPane( - JSplitPane.HORIZONTAL_SPLIT, - chatUserList, - scrollPane - ); - - chatInput = new JTextField(); - chatInput.addActionListener( - new ActionListener() - { - - public void actionPerformed( ActionEvent e ) - { - getChatInputHandler().processChatInput( - chatInput.getText() ); - chatInput.setText( "" ); - } - - } - ); - - contentPane.add( splitPane, BorderLayout.CENTER ); - contentPane.add( chatInput, BorderLayout.SOUTH ); - - chatFrame.setVisible( true ); - chatFrame.pack(); - - desktop.getJDesktop().add( chatFrame ); - } - - - /** - * Create the 3D scene. In this case, this is just the rotating box. - */ - protected void create3DScene() - { - final Vector3f axis = new Vector3f( 1, 1, 0.5f ).normalizeLocal(); - final Box box = new Box( "Box", - new Vector3f( -5, -5, -5 ), - new Vector3f( 5, 5, 5 ) - ); - - box.setModelBound( new BoundingBox() ); - box.updateModelBound(); - box.setLocalTranslation( new Vector3f( 0, 0, -10 ) ); - box.setLightCombineMode( LightState.OFF ); - - TextureState ts = display.getRenderer().createTextureState(); - ts.setEnabled( true ); - ts.setTexture( TextureManager.loadTexture( - Simple3DClient.class.getClassLoader().getResource( - "org/skycastle/client/data/skycastle.png" ), - Texture.MM_LINEAR, - Texture.FM_LINEAR ) - ); - box.setRenderState( ts ); - box.addController( - // Controller which rotates the box. - new Controller() - { - - private static final long serialVersionUID = 1L; - - public void update( float time ) - { - box.getLocalRotation().fromAngleNormalAxis( - timer.getTimeInSeconds(), axis ); - } - - } - ); - - rootNode.attachChild( box ); - } - - - /** - * Initialize the chat client. - */ - protected void initChatClient() - { - /* Use this Simple3DClient for handling chat output and user events. */ - chatClient = new ChatClient( this, this ); - chatClient.login(); - } - - - /** - * Initialize game. Overridden from SimpleGame. - */ - protected void simpleInitGame() - { - display.setTitle( "Skycastle 3D Client" ); - display.getRenderer().setBackgroundColor( ColorRGBA.black ); - - // Set up the keyboard look handler. - input = new InputHandler(); - lookHandler = new KeyboardLookHandler( cam, 50, 1 ); - input.addToAttachedHandlers( lookHandler ); - // Some changes to the BaseSimpleGame keyboard bindings. - initKeyBindings(); - - // Set up GUI, static 3D scene and chat client. - initUI(); - create3DScene(); - initChatClient(); - - // Handle chat input messages as well as chat output and user events. - setChatHandlers( this, this, this ); - - // Always show the the GUI. - guiNode.setCullMode( SceneElement.CULL_NEVER ); - guiNode.setLightCombineMode( LightState.OFF ); - guiNode.updateRenderState(); - guiNode.updateGeometricState( 0, true ); - MouseInput.get().setCursorVisible( true ); - } - - - /** - * Update hook. Overridden from SimpleGame. - */ - protected void simpleUpdate() - { - // Ignore keyboard events if the chat input field has the focus. - if ( chatFrame.getFocusOwner() != chatInput ) - { - lookHandler.setEnabled( true ); - } - else - { - lookHandler.setEnabled( false ); - } - } - - - /** - * Render hook. Overridden from SimpleGame. - */ - protected void simpleRender() - { - display.getRenderer().draw( guiNode ); - } - -} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.