FileDocCategorySizeDatePackage
Player.javaAPI DocExample12790Tue Dec 12 18:58:42 GMT 2000bingo.player

Player

public class Player extends JPanel implements ActionListener, BallListener, ItemListener

Fields Summary
protected PlayerParameters
params
protected static boolean
DEBUG
protected ControlPane
controlPane
protected GameStatusLabel
gameStatusLabel
protected LightBoardPane
lightBoardPane
protected JCheckBox
beepButton
protected static int
SMALLPAD
protected static int
BIGPAD
static String
register
static char
registerKey
static String
clear
static char
clearKey
static String
beep
static char
beepKey
static String
gameStatusTitle
static String
windowTitle
private static Toolkit
toolkit
Registrar
registrar
int
numCardWindows
CardWindow[]
cardWindows
protected Ticket
ticket
protected PlayerQueue
playerQueue
Constructors Summary
public Player()


      
	super(false);
	params = new PlayerParameters();

	playerQueue = new PlayerQueue(this);

	controlPane = new ControlPane(this);

        // status from the game
	JPanel statusPane = new JPanel(false);
	statusPane.setBorder(
		BorderFactory.createTitledBorder(
		    gameStatusTitle));
	statusPane.setLayout(new BoxLayout(statusPane, BoxLayout.Y_AXIS));

        gameStatusLabel = new GameStatusLabel();
	gameStatusLabel.setAlignmentX(0.0f);
	statusPane.add(gameStatusLabel);
        lightBoardPane = new LightBoardPane(0);
	lightBoardPane.setAlignmentX(0.0f);
	statusPane.add(lightBoardPane);

	//Choose where the app beeps whenever a ball arrives.
	beepButton = new JCheckBox(beep);
	beepButton.setSelected(params.getShouldBeep());
	beepButton.setMnemonic(beepKey);
	beepButton.addItemListener(this);
	beepButton.setAlignmentX(0.0f); 
	statusPane.add(beepButton);

	setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
	controlPane.setAlignmentX(0.0f); //left align
        add(controlPane);
	statusPane.setAlignmentX(0.0f); //left align
        add(statusPane);

	//XXX hack to turn off old-style event handling:
	//XXX add any kind of listener to this component
	//XXX 1.1 only, I think
	addContainerListener(new ContainerAdapter(){});

	// Get current status.
	playerQueue.postEvent(new StatusRequestEvent(this));

	// Initialize the toolkit.
	toolkit = Toolkit.getDefaultToolkit();
    
Methods Summary
voidIWon(CardWindow cw)
Requests that handleIWonEvent be called from player queue thread.

	playerQueue.postEvent(new IWonEvent(this, cw));
    
public voidactionPerformed(java.awt.event.ActionEvent e)

        String factoryName = null;

	String command = e.getActionCommand();
        if (command == register) {
	    params.setNames(controlPane.nameField.getText(),
	                    controlPane.hostField.getText());
	    //We didn't used to do the following, since seed isn't
	    //a saved property, but the alternative (doing
	    //invokeAndWait when you really need the value)
	    //might be prone to deadlock.
	    params.setSeed(Long.parseLong(controlPane.seedField.getText()));
	    playerQueue.postEvent(new RegisterEvent(this));
	} else if (command == clear) {
	    clearGame();
        } else {
	    int numCards;
	    try {
		numCards = Integer.parseInt(command);
	        params.setNumCards(numCards);
	    } catch (Throwable exc) {
		//Ignore the action since we don't understand it.
	    }
	}
    
public voidballCalled(BingoBall b)
BallListener method.

	final BingoBall ball = b; //for use in inner class
	if (ball.getNumber() != BingoBall.GAME_OVER) {
	    SwingUtilities.invokeLater(new Runnable() {
	        public void run() {
                    lightBoardPane.displayNewBall(ball);
	            if (params.getShouldBeep()) {
			toolkit.beep();
		    }
	        }
	    });
	}
    
private voidclearGame()

	ticket = null;
	for (int i = 0; i < numCardWindows; i++) {
	    cardWindows[i].dispose();
	}
	controlPane.reset();
	lightBoardPane.clear();
    
public static voidfatalError(java.lang.String message, java.lang.Exception e)

        e.printStackTrace();
        System.err.println(message);
        System.err.println("Exiting.....");
        System.exit(-1);
    
voidhandleIWonEvent(IWonEvent event)

	if (registrar == null) {
            showServerStatus("This player isn't connected to a server: "
                             + "can't tell a server you won.");
	    return;
        }

	try {
	    Answer a = registrar.BINGO(ticket.ID, event.getCard());
	    if (a.didIWin) {
                showDialog(event.getCardWindow(),
		 	   "You won!");
            } else {
		showServerStatus(a.message);
                showDialog(event.getCardWindow(),
                           "You didn't win.");
            }
        } catch (RemoteException e) {
	    //...show status?
	    System.err.println("RMI Exception when "
			       + "informing server of win.");
	}
    
voidhandleRegisterEvent(RegisterEvent event)

	if (registrar == null) {
	    lookUpRegistrar(params.getHostname()); 
	}
	if (registrar == null) {
	    return;  //XXX should do this with an exception instead.
	}

	if (ticket == null) {
	    long seed = params.getSeed(); 
	    lookUpRegistrar(params.getHostname()); 

	    //Get the ticket.
	    try {
	        ticket = registrar.mayIPlay(params.getName(),
			   	            params.getNumCards(),
					    seed);
	    } catch (java.rmi.ConnectException exc) {
	        if (DEBUG) {
	            System.err.println("Not connected to Bingo server.");
	            System.err.println("registrar = " + registrar);
	        }
	        //XXX Update status?  We aren't connected to the Bingo
	        //XXX server, but rmiregistry is running.
		return;
	    } catch (Exception exc) {
	        System.err.println("Unexpected exception on register attempt.");
	        exc.printStackTrace();
	        //XXX Update status?  
		return;
	    }

	    //React to registration results.
	    try {
	        if (ticket.ID != Ticket.DENIED) {
		    numCardWindows = ticket.cards.length;
		    final Player player = this;
		    SwingUtilities.invokeLater(new Runnable() {
			    public void run() {
			        controlPane.didRegister();
				repaint();
				//XXX Should delay the following
				//XXX (so there's feedback when you
				//XXX register)?
		                for (int i = 0; i < numCardWindows; i++) {
			            cardWindows[i] = new
				            CardWindow(ticket.cards[i],
					               player);
			            cardWindows[i].pack();
			            cardWindows[i].setVisible(true);
		                }
			    }
		        });
        	    try {
	    	        new BallListenerThread(this).start();
        	    } catch (java.io.IOException e) {
	                if (DEBUG) {
	                    System.err.println("IOException on "
			                       + "BallListenerThread "
					       + "creation/startup.");
        	        }
		    }
	        } else { 
		    showServerStatus(ticket.message);
		    ticket = null;
	        }
	    } catch (NullPointerException exc) {
	        System.err.println("NullPointerException; probably "
			           + "ticket was null");
	    } catch (Exception exc) {
	        System.err.println("Unexpected exception on register attempt.");
	        exc.printStackTrace();
	    }
	}
    
voidhandleStatusRequestEvent(StatusRequestEvent event)

	lookUpRegistrar(params.getHostname()); 
	if (registrar != null) {
	    String statusText = "";
	    try {
                statusText = registrar.whatsHappening();
	    } catch (java.rmi.ConnectException exc) {
		if (DEBUG) {
		    System.err.println("Not connected to Bingo server.");
		    System.err.println("registrar = " + registrar);
		}
		//XXX Update status?  We aren't connected to the Bingo
		//XXX server, but rmiregistry is running.
	    } catch (Exception exc) {
		System.err.println("Unexpected exception on status request.");
                exc.printStackTrace();
		return;
	    }
	    showServerStatus(statusText);  //safe from any thread
	}
    
public voiditemStateChanged(java.awt.event.ItemEvent e)

	if (e.getStateChange() == ItemEvent.SELECTED) {
	    params.setShouldBeep(true);
	} else {
	    params.setShouldBeep(false);
	}
    
private voidlookUpRegistrar(java.lang.String host)

	if (registrar != null) 
	    return;

	try {
	    registrar = (Registrar)Naming.lookup("//"
	                + host + "/Registrar");
	} catch (java.rmi.NotBoundException exc) {
	    if (DEBUG) {
	        System.err.println("Couldn't find BINGO Server running on host "
			           + host + ".");
	        System.err.println("RMI seems to be running fine."); 
	    }
	    //XXX Advise them to start up BINGO server.
	} catch (java.rmi.UnmarshalException exc) {
	    System.err.println("Unmarshal exception on host "
			       + host + ".");
	    System.err.println("Try recompiling everything and starting over?");
	    System.err.println("registrar = " + registrar);
	    //XXX Advise the user?  Fatal error?
	} catch (java.rmi.ConnectException exc) {
	    if (DEBUG) {
	        System.err.println("RMI isn't running on "
				   + host + ".");
	 	System.err.println("Or maybe it is, but it "
				   + "started after this program.");
	    }
	    //XXX Update status?  We aren't connected to the Bingo
	    //XXX server, but rmiregistry is running.  I think.
	} catch (java.rmi.UnknownHostException exc) {
	    System.err.println("Unknown host: "
			       + host);
	    //XXX Update status?  Ask user to enter another host and retry?
	} catch (java.rmi.ConnectIOException exc) {
	    System.err.println("Couldn't get to host "
			       + host + ".");
	    //XXX Update status?  We might have had a network glitch.
	} catch (Exception exc) {
	    System.err.println("Unexpected exception when "
			       + "trying to find registrar.");
	    System.err.println("Exception type: "
			       + exc.toString());
            exc.printStackTrace();
	}
    
public static voidmain(java.lang.String[] args)

	JFrame frame = new JFrame(windowTitle);

	frame.addWindowListener(new WindowAdapter() {
		public void windowClosing(WindowEvent e) {
		    System.exit(0);	//XXX
		}
	    });

	Player player = new Player();
	frame.getContentPane().add("Center", player);
	frame.pack();
	frame.setVisible(true);
    
public voidnoMoreBalls()
BallListener method.

	controlPane.gameOver();  //safe from any thread
	showServerStatus("Game Over."); //safe from any thread
    
protected voidprocessEvent(java.awt.AWTEvent event)

        if (event instanceof StatusRequestEvent) {
            if (DEBUG) {
                System.out.println("Player processEvent received StatusRequestEvent");
            }      
            handleStatusRequestEvent((StatusRequestEvent)event);
        } else if (event instanceof RegisterEvent) {
            if (DEBUG) {
                System.out.println("Player processEvent received RegisterEvent");
            }      
            handleRegisterEvent((RegisterEvent)event);
        } else if (event instanceof IWonEvent) { 
            if (DEBUG) {
                System.out.println("Player processEvent received IWonEvent");
            }      
            handleIWonEvent((IWonEvent)event);
        } else {
	    super.processEvent(event);
	}
    
protected voidshowDialog(CardWindow cw, java.lang.String status)

	final String statusText = status;
	final CardWindow cardWindow = cw;
	SwingUtilities.invokeLater(new Runnable() {
	    public void run() {
		cardWindow.showStatusDialog(statusText);
	    }
	});
    
public voidshowServerStatus(java.lang.String message)

	if (gameStatusLabel != null) {
	    final String msg = message; //so we can access it in inner class
	    SwingUtilities.invokeLater(new Runnable() {
		    public void run() {
	    		gameStatusLabel.setText(msg);
		    }
		});
	} else {
	    System.err.println("Player.gameStatusLabel is null, "
			       + "so couldn't say: "
			       + message);
	} 

	if (DEBUG) {
	    System.out.println("showServerStatus: " + message);
	}