/** * FILE: Stable.java * AUTHOR: Ivan J Leichtling * INERNET: ivan@columbia.edu * * This file defines the main stable marraige applet. */ import java.util.*; import java.applet.*; import java.awt.*; import java.net.*; public class Stable extends Applet { int iCouples; Vector vMen; Vector vWomen; boolean fNotAllEngaged; Enumeration e; int state; Button bStep, bRun, bReset; TextArea taSpew; public void init() { String s_Clip; if( null != (s_Clip = getParameter( "SOUND" ) ) ) { AudioClip ac = getAudioClip( getDocumentBase(), s_Clip ); ac.loop(); } iCouples = getParam( "COUPLES", getParam( "MESSAGEWIDTH", 60 ) ); vWomen = new Vector(); vMen = new Vector(); taSpew = new TextArea( 6, 60 ); taSpew.setEditable( false ); for(int i = 1; i <= iCouples; i++ ) { vWomen.addElement( new Woman( getParam( "Woman" + i, "Woman " + i ), taSpew ) ); } for(int i = 1; i <= iCouples; i++ ) { vMen.addElement( new Man( getParam( "Man" + i, "Man " + i ), taSpew ) ); } reset(); initUI(); repaint(); } public void initUI() { setBackground( Color.pink ); setForeground( Color.black ); GridBagLayout gbl = new GridBagLayout(); GridBagConstraints gbc = new GridBagConstraints(); setLayout( gbl ); /* // The label at the top Label l_Title = new Label( "Stable Marraige", Label.CENTER ); l_Title.setFont( new Font( "Helvetica", Font.BOLD, 18 ) ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridheight = 2; gbl.setConstraints( l_Title, gbc ); add( l_Title ); */ // Labels for Columns of Buttons Label l_Women = new Label( "Women", Label.CENTER ); Label l_Men = new Label( "Men", Label.CENTER ); Insets insetW = new Insets( 1, 30, 1, 60 ); Insets insetM = new Insets( 1, 60, 1, 30 ); gbc.gridwidth = GridBagConstraints.RELATIVE; gbc.gridheight = 1; gbc.insets = insetW; gbc.anchor = GridBagConstraints.WEST; gbl.setConstraints( l_Women, gbc ); add( l_Women ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.anchor = GridBagConstraints.EAST; gbc.insets = insetM; gbl.setConstraints( l_Men, gbc ); add( l_Men ); // Columns of Buttons Enumeration enWomen = vWomen.elements(); Enumeration enMen = vMen.elements(); gbc.fill = GridBagConstraints.NONE; for( int i = 0; i < iCouples; i++ ) { gbc.gridwidth = GridBagConstraints.RELATIVE; gbc.insets = insetW; gbc.anchor = GridBagConstraints.WEST; PersonButton pbW = new PersonButton( (Woman)enWomen.nextElement() ); gbl.setConstraints( pbW, gbc ); add( pbW ); gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.insets = insetM; gbc.anchor = GridBagConstraints.EAST; PersonButton pbM = new PersonButton( (Man)enMen.nextElement() ); gbl.setConstraints( pbM, gbc ); add( pbM ); } Panel pButtons = new Panel(); GridBagLayout gblB = new GridBagLayout(); GridBagConstraints gbcB = new GridBagConstraints(); pButtons.setLayout( gblB ); bStep = new Button( "Step" ); bRun = new Button( "Run" ); bReset = new Button( "Reset" ); gbcB.gridwidth = 1; gbcB.insets = new Insets( 1, 3, 1, 3 ); gbcB.anchor = GridBagConstraints.CENTER; gblB.setConstraints( bStep, gbcB ); pButtons.add( bStep ); gbcB.gridwidth = 1; gblB.setConstraints( bRun, gbcB ); pButtons.add( bRun ); gbcB.gridwidth = GridBagConstraints.REMAINDER; gblB.setConstraints( bReset, gbcB ); pButtons.add( bReset ); gbc.anchor = GridBagConstraints.CENTER; gbc.insets = new Insets( 2, 6, 0, 6 ); gbl.setConstraints( pButtons, gbc ); add( pButtons ); pButtons.show(); gbc.fill = GridBagConstraints.HORIZONTAL; gbl.setConstraints( taSpew, gbc ); add( taSpew ); } public void reset() { Random rand = new Random(); rand.setSeed( new Date().getTime() ); Enumeration en = vMen.elements(); while( en.hasMoreElements() ) { Person p = (Person) en.nextElement(); p.reset(); Vector v = (Vector) vWomen.clone(); p.randomPrefs( v, rand ); } en = vWomen.elements(); while( en.hasMoreElements() ) { Person p = (Person) en.nextElement(); p.reset(); Vector v = (Vector) vMen.clone(); p.randomPrefs( v, rand ); } taSpew.setText( "" ); fNotAllEngaged = true; e = null; state = 1; repaint(); /* This duplicate code has been added as a bug fix. */ en = vMen.elements(); while( en.hasMoreElements() ) { Person p = (Person) en.nextElement(); p.reset(); Vector v = (Vector) vWomen.clone(); p.randomPrefs( v, rand ); } en = vWomen.elements(); while( en.hasMoreElements() ) { Person p = (Person) en.nextElement(); p.reset(); Vector v = (Vector) vMen.clone(); p.randomPrefs( v, rand ); } repaint(); } public void printAllPrefs() { Enumeration en = vMen.elements(); while( en.hasMoreElements() ) { Person p = (Person) en.nextElement(); p.printPrefs(); } en = vWomen.elements(); while( en.hasMoreElements() ) { Person p = (Person) en.nextElement(); p.printPrefs(); } } public void step() { switch( state ) { case 1: if( fNotAllEngaged ) { fNotAllEngaged = false; e = vMen.elements(); state = 2; } else { state = 4; printCouples(); bRun.disable(); bStep.disable(); } break; case 2: if( e.hasMoreElements() ) { Man m = (Man) e.nextElement(); if( !m.getEngaged() ) { m.propose(); fNotAllEngaged = true; } else { step(); } } else { e = vWomen.elements(); state = 3; } break; case 3: if( e.hasMoreElements() ) { Woman w = (Woman) e.nextElement(); if( w.hasSuitors() ) { w.decide(); } else { step(); } } else { state = 1; } break; case 4: break; } repaint(); } public void findMatches() { while( state != 4 ) { step(); } } public void printCouples() { Enumeration en = vMen.elements(); while( en.hasMoreElements() ) { Man m = (Man) en.nextElement(); m.print( m.getName() + " is engaged to " + m.getFiancee().getName() ); } } public void paint( Graphics g ) { Enumeration enum = vMen.elements(); while( enum.hasMoreElements() ) { Man m = (Man)enum.nextElement(); if( m.getEngaged() ) { g.setColor( Color.red ); Point pM = m.getButton().location(); Dimension dM = m.getButton().size(); Point pF = m.getFiancee().getButton().location(); Dimension dF = m.getFiancee().getButton().size(); g.drawLine( pM.x, pM.y + (dM.height / 2 ), pF.x + dF.width, pF.y + (dF.height / 2 ) ); } else if( m.getProposed() ) { g.setColor( Color.blue ); Point pM = m.getButton().location(); Dimension dM = m.getButton().size(); Point pF = m.getPossible().getButton().location(); Dimension dF = m.getPossible().getButton().size(); g.drawLine( pM.x, pM.y + (dM.height / 2 ), pF.x + dF.width, pF.y + (dF.height / 2 ) ); } } } public boolean handleEvent( Event evt ) { switch( evt.id ) { case Event.ACTION_EVENT: if( evt.target == bReset ) { bRun.disable(); bStep.disable(); reset(); bRun.enable(); bStep.enable(); return( true ); } else if( evt.target == bRun ) { bRun.disable(); bStep.disable(); while( 4 != state ) { step(); } return( true ); } else if( evt.target == bStep ) { // bRun.disable(); // bStep.disable(); step(); // bRun.enable(); // bStep.enable(); return( true ); } default: return( super.handleEvent( evt ) ); } } private String getParam( String s, String use ) { if( null == (s = getParameter( s ) ) ) { return( use ); } return( s ); } private int getParam( String s, int i ) { try { return Integer.parseInt( getParameter( s ) ); } catch( NumberFormatException ex ) { return i; } } public String getAppletInfo() { return( "This applet designed and destroyed by:\n" + "Ivan J Leichtling\n" + "ivan@columbia.edu\n" ); } public String[][] getParameterInfo() { String[][] s = new String[5][3] ; s[0][0] = "SOUND"; s[0][1] = "File"; s[0][2] = "Au file to play in the background"; s[1][0] = "COUPLES"; s[1][1] = "Integer"; s[1][2] = "A number of couples to create"; s[2][0] = "MAN#"; s[2][1] = "String"; s[2][2] = "the name of man #"; s[3][0] = "WOMAN#"; s[3][1] = "String"; s[3][2] = "the name of woman #"; s[4][0] = "MESSAGEWIDTH"; s[4][1] = "Integer"; s[4][2] = "the width (in characters) of the text box which displays output"; return( s ); } }