import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; import java.net.*; import java.io.*; class PongClient extends Frame implements ActionListener, KeyEventDispatcher { volatile PongClient refThis; volatile Panel panLogin=new Panel(); volatile TextField txtUserName=new TextField(); volatile TextField txtServerAddress=new TextField(); volatile TextField txtServerPort=new TextField(); volatile Button btnLogin=new Button("Login"); volatile Panel panQueue=new Panel(); volatile List lstUsers=new List(5); volatile Button btnChallengeUser=new Button("Challenge User"); volatile Panel panPlay=new Panel(); volatile Button btnJoinQueue=new Button("Join Queue"); volatile PongCanvas canvasPong=new PongCanvas(); volatile ClientThread thrClient; public static void main(String args[]) { try { PongClient pFrame=new PongClient(); Dimension dimScreen=Toolkit.getDefaultToolkit().getScreenSize(); pFrame.setSize(dimScreen.width, dimScreen.height-40); pFrame.setVisible(true); } catch(Exception ex) { ex.printStackTrace(); } } PongClient() { super("Pong Client"); refThis=this; setIconImage(new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB)); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent we) { if(thrClient!=null) { try { //Attempt to send the close connection int to the server, it will only work if the user has already connected thrClient.serverDOS.writeInt(PongConstants.CLOSE_CONNECTION); thrClient.serverDOS.flush(); } catch(Exception ex) { } } System.exit(0); } }); //Add event handler for keyboard key press events KeyboardFocusManager manager=KeyboardFocusManager.getCurrentKeyboardFocusManager(); manager.addKeyEventDispatcher(this); Panel tempPan=new Panel(); tempPan.setLayout(new GridLayout(4, 1)); Panel tempPanA=new Panel(); tempPanA.setLayout(new GridLayout(1, 2)); tempPanA.add(new Label("User Name:")); tempPanA.add(txtUserName); tempPan.add(tempPanA); Panel tempPanB=new Panel(); tempPanB.setLayout(new GridLayout(1, 2)); tempPanB.add(new Label("Server Address:")); tempPanB.add(txtServerAddress); tempPan.add(tempPanB); Panel tempPanC=new Panel(); tempPanC.setLayout(new GridLayout(1, 2)); tempPanC.add(new Label("Server Port:")); tempPanC.add(txtServerPort); tempPan.add(tempPanC); Panel tempPanD=new Panel(); tempPanD.add(btnLogin); btnLogin.addActionListener(this); tempPan.add(tempPanD); panLogin.setLayout(new BorderLayout()); panLogin.add("North", tempPan); panLogin.add("Center", new Label("")); add("Center", panLogin); panQueue.setLayout(new BorderLayout()); panQueue.add("North", new Label("Users:")); panQueue.add("Center", lstUsers); Panel tempPan2=new Panel(); tempPan2.add(btnChallengeUser); btnChallengeUser.addActionListener(this); panQueue.add("South", tempPan2); panPlay.setLayout(null); panPlay.add(btnJoinQueue); btnJoinQueue.addActionListener(this); panPlay.add(canvasPong); } public void actionPerformed(ActionEvent ae) { Object evSource=ae.getSource(); if(evSource==btnLogin) { String strUserName=txtUserName.getText(); if(strUserName.length()==0) { txtUserName.setText("User name required."); try { Thread.sleep(3000); } catch(Exception ex) { } txtUserName.setText(""); return; } String strServerAddress=txtServerAddress.getText(); if(strServerAddress.length()==0) { txtServerAddress.setText("Server address required."); try { Thread.sleep(3000); } catch(Exception ex) { } txtServerAddress.setText(""); return; } String strServerPort=txtServerPort.getText(); if(strServerPort.length()==0) { txtServerPort.setText("Server port required."); try { Thread.sleep(3000); } catch(Exception ex) { } txtServerPort.setText(""); return; } int intServerPort=-1; try { intServerPort=Integer.parseInt(strServerPort); } catch(Exception ex) { txtServerPort.setText("Digits only."); try { Thread.sleep(3000); } catch(Exception ex2) { } txtServerPort.setText(strServerPort); return; } try { //Create a socket for communicating with the server represented by the server address and server port Socket serverSocket=new Socket(strServerAddress, intServerPort); DataInputStream serverDIS=new DataInputStream(serverSocket.getInputStream()); DataOutputStream serverDOS=new DataOutputStream(serverSocket.getOutputStream()); //Send the chosen String strUserName to the server serverDOS.writeInt(strUserName.length()); serverDOS.writeBytes(strUserName); serverDOS.flush(); //Receive an int which tells the client whether or not the chosen user name has been accepted int intServerResponse=serverDIS.readInt(); if(intServerResponse==PongConstants.USER_NAME_REJECTED) { txtUserName.setText("User name rejected. Try a different name."); try { Thread.sleep(4000); } catch(Exception ex) { } txtUserName.setText(strUserName); return; } //Receive data for populating the list of challengeable users int intNumberOfUsers=serverDIS.readInt(); lstUsers.removeAll(); for(int i=0;i0) { //If the length of strWinner is greater than 0 then display the winner message instead of drawing the pong elements String strWins=strWinner+" Wins"; FontMetrics fMetr=graph.getFontMetrics(); int intWinsWidth=fMetr.stringWidth(strWins); int intWinsHeight=fMetr.getHeight(); graph.drawString(strWins, dimCanvas.width/2-intWinsWidth/2, dimCanvas.height/2+intWinsHeight/2); return; } synchronized(PongConstants.syncAll) { Color clrPrev=graph.getColor(); graph.setColor(Color.black); //Draw the northern edge graph.fillRect(0, 0, dimCanvas.width, intPongEdgeWidth); //Draw the southern edge graph.fillRect(0, dimCanvas.height-intPongEdgeWidth, dimCanvas.width, intPongEdgeWidth); graph.setColor(Color.red); //Draw the user's slider graph.fillRect(0, intUserLeftSliderPosition, intPongSliderWidth, intPongSliderHeight); //Draw the AI's slider graph.fillRect(dimCanvas.width-intPongSliderWidth, intUserRightSliderPosition, intPongSliderWidth, intPongSliderHeight); graph.setColor(Color.green); //Draw the ball graph.fillOval(intBallX-intPongBallWidth/2, intBallY-intPongBallHeight/2, intPongBallWidth, intPongBallHeight); } } } }