Presentation is loading. Please wait.

Presentation is loading. Please wait.

Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes.

Similar presentations


Presentation on theme: "Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes."— Presentation transcript:

1 Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes

2 Solitaire Case Study (Budd's UOOPJ, Ch. 9) This is a set of slides to accompany chapter 9 of Timothy Budd's textbook Understanding Object-Oriented Programming with Java, Updated Edition (Addison-Wesley, 2000)

3 The Solitaire Game Good example of inheritance in action Constructed from classes for cards, card piles, and the game application

4 Class Card import java.awt.*; public class Card { // public constants for card dimensions // public constants for card dimensions public final static int width = 50; public final static int width = 50; public final static int height = 70; public final static int height = 70; // public constants for card suits // public constants for card suits public final static int heart = 0; public final static int heart = 0; public final static int spade = 1; public final static int spade = 1; public final static int diamond = 2; public final static int diamond = 2; public final static int club = 3; public final static int club = 3;

5 Class Card (continued) // constructors // constructors public Card (int sv, int rv) public Card (int sv, int rv) { s = sv; s = sv; r = rv; r = rv; faceup = false; faceup = false; } // mutators // mutators public final void flip() public final void flip() { faceup = ! faceup; faceup = ! faceup; }

6 Class Card (continued) // accessors public final int rank () { return r; return r;} public final int suit() { return s; return s;} public final boolean faceUp() { return faceup; return faceup;}

7 Class Card (continued) public final Color color() public final Color color() { if (faceUp()) if (faceUp()) if (suit() == heart || suit() == diamond) if (suit() == heart || suit() == diamond) return Color.red; return Color.red; else else return Color.black; return Color.black; return Color.yellow; return Color.yellow; } public void draw (Graphics g, int x, int y) { /*... */ } public void draw (Graphics g, int x, int y) { /*... */ } // internal data fields // internal data fields private boolean faceup; // card face exposed? private boolean faceup; // card face exposed? private int r; // card rank private int r; // card rank private int s; // card suit private int s; // card suit}

8 Notes on Class Card Class implements playing card abstraction Textbook code rearranged into our standard format import makes package java.awt available to programpart of Java API Variables and classes can be used before defined (except local variables in methods)

9 Notes on Class Card (continued) Java has no global variables, constants, or enumerated data types static data fields (i.e., class variables) used for global static data fields (i.e., class variables) used for global final data fields used for constants – assigned once, then not redefined final data fields used for constants – assigned once, then not redefined Three internal data fields Three internal data fields rank and suit are read-only – accessors but no mutators rank and suit are read-only – accessors but no mutators faceup can be modified – flip() mutator faceup can be modified – flip() mutator draw is complex method – accessor with side effects draw is complex method – accessor with side effects final methods – accessors rank(), suit(), faceup(), and color(), and mutator flip() final methods – accessors rank(), suit(), faceup(), and color(), and mutator flip() cannot be overridden in subclasses cannot be overridden in subclasses can be optimized – expanded inline like a macro – efficient but inhibits reuse! can be optimized – expanded inline like a macro – efficient but inhibits reuse! draw is not final – implementation may be somewhat platform dependent draw is not final – implementation may be somewhat platform dependent

10 Card Images See Figure 9.3 on page 145 of Budd's UOOPJ.

11 Method draw import java.awt.*; public class Card { //... //... public void draw (Graphics g, int x, int y) public void draw (Graphics g, int x, int y) { String names[] = {"A", "2", "3", "4", "5", "6", "7", "8", "9", String names[] = {"A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"}; "10", "J", "Q", "K"}; // clear rectangle, draw border // clear rectangle, draw border g.clearRect(x, y, width, height); g.clearRect(x, y, width, height); g.setColor(Color.blue); g.setColor(Color.blue); g.drawRect(x, y, width, height); g.drawRect(x, y, width, height); // draw body of card // draw body of card g.setColor(color()); g.setColor(color());

12 Method draw (continued) if (faceUp()) { g.drawString(names[rank()], x+3, y+15); g.drawString(names[rank()], x+3, y+15); if (suit() == heart) if (suit() == heart) { g.drawLine(x+25, y+30, x+35, y+20); g.drawLine(x+35, y+20, x+45, y+30); { g.drawLine(x+25, y+30, x+35, y+20); g.drawLine(x+35, y+20, x+45, y+30); g.drawLine(x+45, y+30, x+25, y+60); g.drawLine(x+25, y+60, x+5, y+30); g.drawLine(x+45, y+30, x+25, y+60); g.drawLine(x+25, y+60, x+5, y+30); g.drawLine(x+5, y+30, x+15, y+20); g.drawLine(x+15, y+20, x+25, y+30); g.drawLine(x+5, y+30, x+15, y+20); g.drawLine(x+15, y+20, x+25, y+30); } else if (suit() == spade) { } else if (suit() == spade) { g.drawLine(x+25, y+20, x+40, y+50); g.drawLine(x+40, y+50, x+10, y+50); g.drawLine(x+25, y+20, x+40, y+50); g.drawLine(x+40, y+50, x+10, y+50); g.drawLine(x+10, y+50, x+25, y+20); g.drawLine(x+23, y+45, x+20, y+60); g.drawLine(x+10, y+50, x+25, y+20); g.drawLine(x+23, y+45, x+20, y+60); g.drawLine(x+20, y+60, x+30, y+60); g.drawLine(x+30, y+60, x+27, y+45); g.drawLine(x+20, y+60, x+30, y+60); g.drawLine(x+30, y+60, x+27, y+45); } else if (suit() == diamond) { } else if (suit() == diamond) { g.drawLine(x+25, y+20, x+40, y+40); g.drawLine(x+40, y+40, x+25, y+60); g.drawLine(x+25, y+20, x+40, y+40); g.drawLine(x+40, y+40, x+25, y+60); g.drawLine(x+25, y+60, x+10, y+40); g.drawLine(x+10, y+40, x+25, y+20); g.drawLine(x+25, y+60, x+10, y+40); g.drawLine(x+10, y+40, x+25, y+20); } else if (suit() == club) { } else if (suit() == club) { g.drawOval(x+20, y+25, 10, 10); g.drawOval(x+25, y+35, 10, 10); g.drawOval(x+20, y+25, 10, 10); g.drawOval(x+25, y+35, 10, 10); g.drawOval(x+15, y+35, 10, 10); g.drawLine(x+23, y+45, x+20, y+55); g.drawOval(x+15, y+35, 10, 10); g.drawLine(x+23, y+45, x+20, y+55); g.drawLine(x+20, y+55, x+30, y+55); g.drawLine(x+30, y+55, x+27, y+45); g.drawLine(x+20, y+55, x+30, y+55); g.drawLine(x+30, y+55, x+27, y+45); }}

13 Method draw (continued) else { else { // face down // face down g.drawLine(x+15, y+5, x+15, y+65); g.drawLine(x+15, y+5, x+15, y+65); g.drawLine(x+35, y+5, x+35, y+65); g.drawLine(x+35, y+5, x+35, y+65); g.drawLine(x+5, y+20, x+45, y+20); g.drawLine(x+5, y+20, x+45, y+20); g.drawLine(x+5, y+35, x+45, y+35); g.drawLine(x+5, y+35, x+45, y+35); g.drawLine(x+5, y+50, x+45, y+50); g.drawLine(x+5, y+50, x+45, y+50); } }}

14 Notes on Method draw Displays the card on screen Parameter is current graphics context argument is object of class java.awt.Graphics argument is object of class java.awt.Graphics class Graphics in Java API provides many drawing primitives class Graphics in Java API provides many drawing primitives methods for printing bit-maps available for more sophisticated visuals methods for printing bit-maps available for more sophisticated visuals Constants such as Color.red and Color.black defined in class java.awt.Color draw is instance method – every card responsible for drawing itself

15 The Game See Figure 9.4 on page 145 of Budd's UOOPJ.

16 Class CardPile import java.awt.*; import java.util.Stack; import java.util.EmptyStackException; public class CardPile { // constructors // constructors public CardPile (int xl, int yl) public CardPile (int xl, int yl) { x = xl; x = xl; y = yl; y = yl; thePile = new Stack(); thePile = new Stack(); }

17 Class CardPile (continued) //mutators public final Card pop() { try { try { return (Card) thePile.pop(); return (Card) thePile.pop(); } catch (EmptyStackException e) { } catch (EmptyStackException e) { return null; return null; }} public void addCard (Card aCard) // sometimes overridden { thePile.push(aCard); thePile.push(aCard);} public void select (int tx, int ty) // sometimes overridden { /* do nothing */ }

18 Class CardPile (continued) // accessors public final Card top() { return (Card) thePile.peek(); } public final boolean isEmpty() { return thePile.empty(); } public boolean includes (int tx, int ty) // sometimes overridden { return x <= tx && tx <= x + Card.width return x <= tx && tx <= x + Card.width && y <= ty && ty <= y + Card.height; && y <= ty && ty <= y + Card.height;} public boolean canTake (Card aCard) // sometimes overridden { return false; } public void display (Graphics g) // sometimes overridden { g.setColor(Color.blue); g.setColor(Color.blue); if (isEmpty()) if (isEmpty()) g.drawRect(x, y, Card.width, Card.height); g.drawRect(x, y, Card.width, Card.height); else else top().draw(g, x, y); top().draw(g, x, y);}

19 Class CardPile (continued) // protected data fields // protected data fields // coordinates of the card pile // coordinates of the card pile protected int x; protected int x; // (x,y) is upper left corner // (x,y) is upper left corner protected int y; protected int y; // cards in the pile // cards in the pile protected Stack thePile; protected Stack thePile;}

20 Notes on Class CardPile Implementation of card deck abstraction – base class extended for specific behaviors Uses generic container Stack from Java API for pile of cards empty initially empty initially Stack operations implement Card operations – adapter pattern Stack operations implement Card operations – adapter pattern Cast objects back to Card when taken from stack Cast objects back to Card when taken from stack Uses global symbolic constants Card.width and Card.height – access to static fields using class name, not instance name (actually, either works) pop, top, and isEmpty implementation for subclasses -- final methods addCard, select, includes, canTake, and display part of abstraction, but implementation varies among subclasses protected data fields accessible by subclasses Instructor's comment: –protected data fields usually bad practice – trusts subclasses (perhaps in different package) to manipulate internal fields correctly – safer to provide appropriate protected mutators and accessors instead (perhaps final )

21 Informal Specification of CardPile's Non-final Methods Methods may need to be overridden to give the card deck the appropriate behaviors. addCard(c) –adds card c to the card pile select(x,y) –performs an action in response to mouse click at (x,y) includes(x,y) –determines whether (x,y) within boundary of the pile canTake(c) –determines whether the pile can take card c (according to the rules governing the pile) display(g) –displays the pile using graphics context g

22 Class SuitPile class SuitPile extends CardPile { // constructors public SuitPile (int x, int y) public SuitPile (int x, int y) { super(x, y); } { super(x, y); } // accessors // accessors public boolean canTake (Card aCard) public boolean canTake (Card aCard) // overrides parent // overrides parent { if (isEmpty()) { if (isEmpty()) return aCard.rank() == 0; return aCard.rank() == 0; Card topCard = top(); Card topCard = top(); return (aCard.suit() == topCard.suit()) return (aCard.suit() == topCard.suit()) && (aCard.rank() == 1 + topCard.rank()); && (aCard.rank() == 1 + topCard.rank()); }}

23 Notes on Class SuitPile Represents one of the (4) piles of cards at top of playing surface – built up in suit from Ace (1) to King (13) Keyword extends indicates inheritance from CardPile super indicates parent – in constructor used to call parent's constructor for initialization – first statement only Method canTake overridden by replacement – canTake if pile empty or card is next higher of same suit

24 Class DeckPile import java.util.Random ; class DeckPile extends CardPile { // constructors public DeckPile (int x, int y) public DeckPile (int x, int y) { // first initialize parent { // first initialize parent super(x, y); super(x, y); // then create the new deck, first put them into a local pile // then create the new deck, first put them into a local pile for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++) for (int j = 0; j <= 12; j++) for (int j = 0; j <= 12; j++) addCard(new Card(i, j)); addCard(new Card(i, j)); // then shuffle the cards // then shuffle the cards Random generator = new Random(); Random generator = new Random(); for (int i = 0; i < 52; i++) { for (int i = 0; i < 52; i++) { int j = Math.abs(generator.nextInt() % 52); int j = Math.abs(generator.nextInt() % 52); // swap the two card values // swap the two card values Object temp = thePile.elementAt(i); Object temp = thePile.elementAt(i); thePile.setElementAt(thePile.elementAt(j), i); thePile.setElementAt(thePile.elementAt(j), i); thePile.setElementAt(temp, j); thePile.setElementAt(temp, j); } } // mutators // mutators public void select(int tx, int ty) { public void select(int tx, int ty) { if (isEmpty()) return; if (isEmpty()) return; Solitaire.discardPile.addCard(pop()); Solitaire.discardPile.addCard(pop()); }}

25 Notes on Class DeckPile Represents the original deck of cards Uses super in constructor for basic initialization, new code for specific initialization Accesses static (class) methods – absolute value function Math.abs() Overrides method select by replacement – if pile nonempty, add top card to discard pile Java API Stack extends Vector – select uses the "ranked sequence" methods of Vector Instructor's comment: –Stack extending Vector is poor design in the Java API! Similarly, the choice of Stack is a questionable design. Better to just use Vector directly

26 Notes on Class DeckPile (continued) Accesses utility class java.util.Random to generate pseudo-random numbers Accesses static (class) variables to share single copies –Solitaire.discardPile –Author has only one discard pile, so made this class access that instance directly Instructor's comment: –Hard-coding of reference to static discard pile inhibits reusability of the deck –Probably better to pass discard deck to constructor of DeckPile, store reference, manipulate it

27 Notes on Class DeckPile (continued) Manipulates protected field thePile from parent class CardPile Possible alternatives to use of protected data fields: Add ( protected ?) "ranked sequence" get and set operations to CardPile abstraction? Add ( protected ?) "ranked sequence" get and set operations to CardPile abstraction? Add constructor or ( protected ?) set operation to CardPile that takes a sequence (vector, array, etc.) of cards to (re)initialize pile? get method? Add constructor or ( protected ?) set operation to CardPile that takes a sequence (vector, array, etc.) of cards to (re)initialize pile? get method? Add shuffle operation to CardPile abstraction? Add shuffle operation to CardPile abstraction?

28 Class DiscardPile import java.util.Random; class DiscardPile extends CardPile { // constructors // constructors public DiscardPile (int x, int y) public DiscardPile (int x, int y) { super (x, y); super (x, y); } // mutators // mutators public void addCard (Card aCard) public void addCard (Card aCard) { if (! aCard.faceUp()) if (! aCard.faceUp()) aCard.flip(); aCard.flip(); super.addCard(aCard); super.addCard(aCard); }

29 Class DiscardPile (continued) //mutators //mutators public void select (int tx, int ty) public void select (int tx, int ty) { if (isEmpty()) if (isEmpty()) return; return; Card topCard = pop(); Card topCard = pop(); for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++) if (Solitaire.suitPile[i].canTake(topCard)) { if (Solitaire.suitPile[i].canTake(topCard)) { Solitaire.suitPile[i].addCard(topCard); Solitaire.suitPile[i].addCard(topCard); return; return; } for (int i = 0; i < 7; i++) for (int i = 0; i < 7; i++) if (Solitaire.tableau[i].canTake(topCard)) { if (Solitaire.tableau[i].canTake(topCard)) { Solitaire.tableau[i].addCard(topCard); Solitaire.tableau[i].addCard(topCard); return; return; } // nobody can use it, put it back on our list // nobody can use it, put it back on our list addCard(topCard); addCard(topCard); }}

30 Notes on Class DiscardPile Represents the discard pile in a Solitaire game Constructor refines parent's constructor – uses super call in initialization select method overrides and replaces one in parent –checks whether topmost card can be played any suit pile or tableau pile addCard method overrides and refines one in parent –executes parent method ( super.addCard ), but also adds new behavior –flips card faceup when put on discard pile Hard-coded access to static variables for the (4) suit piles and (7) tableau piles –probably better to pass these to constructor, store references, and manipulate via local references

31 Class TablePile import java.util.Enumeration ; class TablePile extends CardPile { // constructors // constructors public TablePile (int x, int y, int c) public TablePile (int x, int y, int c) { // initialize the parent class { // initialize the parent class super(x, y); super(x, y); // then initialize our pile of cards // then initialize our pile of cards for (int i = 0; i < c; i++) { for (int i = 0; i < c; i++) { addCard(Solitaire.deckPile.pop()); addCard(Solitaire.deckPile.pop()); } // flip topmost card face up // flip topmost card face up top().flip(); top().flip(); }

32 Class TablePile (continued) // mutators public void select (int tx, int ty) { if (isEmpty()) return; if (isEmpty()) return; // if face down, then flip // if face down, then flip Card topCard = top(); Card topCard = top(); if (! topCard.faceUp()) { if (! topCard.faceUp()) { topCard.flip(); topCard.flip(); return; return; } // else see if any suit pile can take card } // else see if any suit pile can take card topCard = pop(); topCard = pop(); for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++) if (Solitaire.suitPile[i].canTake(topCard)) { if (Solitaire.suitPile[i].canTake(topCard)) { Solitaire.suitPile[i].addCard(topCard); Solitaire.suitPile[i].addCard(topCard); return; return; } // else see if any other table pile can take card } // else see if any other table pile can take card for (int i = 0; i < 7; i++) for (int i = 0; i < 7; i++) if (Solitaire.tableau[i].canTake(topCard)) { if (Solitaire.tableau[i].canTake(topCard)) { Solitaire.tableau[i].addCard(topCard); Solitaire.tableau[i].addCard(topCard); return; return; } // else put it back on our pile } // else put it back on our pile addCard(topCard); addCard(topCard);}

33 Class TablePile (continued) // accessors // accessors public boolean canTake (Card aCard) { public boolean canTake (Card aCard) { if (isEmpty()) if (isEmpty()) return aCard.rank() == 12; return aCard.rank() == 12; Card topCard = top(); Card topCard = top(); return (aCard.color() != topCard.color()) && return (aCard.color() != topCard.color()) && (aCard.rank() == topCard.rank() - 1); (aCard.rank() == topCard.rank() - 1); } public boolean includes (int tx, int ty) { public boolean includes (int tx, int ty) { // don't test bottom of card // don't test bottom of card return x <= tx && tx <= x + Card.width && y <= ty; return x <= tx && tx <= x + Card.width && y <= ty; } public void display (Graphics g) { public void display (Graphics g) { int localy = y; int localy = y; for (Enumeration e = thePile.elements(); e.hasMoreElements();) { for (Enumeration e = thePile.elements(); e.hasMoreElements();) { Card aCard = (Card) e.nextElement(); Card aCard = (Card) e.nextElement(); aCard.draw (g, x, localy); aCard.draw (g, x, localy); localy += 35; localy += 35; } } }

34 Notes on Class TablePile Represents one of the (7) tableau piles on the lower part of the playing surface Initialized with cards from deck – constructor argument gives number needed Initialized with cards from deck – constructor argument gives number needed Top card is face up Top card is face up Add card to empty pile only if King Add card to empty pile only if King Add card to nonempty pile only if opposite color to top and one rank lower Add card to nonempty pile only if opposite color to top and one rank lower Selection action moves any cards from this table pile to suit pile or another table pile Selection action moves any cards from this table pile to suit pile or another table pile Uses super in constructor for basic initialization, new code for specific initialization Methods select, canTake, includes, and display override and replace ones in parent Method display Uses java.util.Enumeration object returned by the Stack to iterate through the tableau pile Uses java.util.Enumeration object returned by the Stack to iterate through the tableau pile Displays each card slightly offset from the one below it Displays each card slightly offset from the one below it Accesses protected field thePile from parent class CardPile Accesses protected field thePile from parent class CardPile Perhaps define ( protected ?) elements() method in CardPile to return a pile- Enumeration object – to avoid protected fields Perhaps define ( protected ?) elements() method in CardPile to return a pile- Enumeration object – to avoid protected fields Another alternative: method to return cards in pile as sequence (e.g., array or vector) Another alternative: method to return cards in pile as sequence (e.g., array or vector)

35 The Game Class: Solitaire import java.awt.*; import java.awt.event.*; public class Solitaire { // public class variables for the various card piles of game static public DeckPile deckPile; static public DeckPile deckPile; static public DiscardPile discardPile; static public DiscardPile discardPile; static public TablePile tableau [ ]; static public TablePile tableau [ ]; static public SuitPile suitPile [ ]; static public SuitPile suitPile [ ]; // single array to alias all above piles -- aids polymorphism // single array to alias all above piles -- aids polymorphism static public CardPile allPiles [ ]; static public CardPile allPiles [ ];

36 The Game Class: Solitaire (continued) // application entry point static public void main (String[] args) { Solitaire world = new Solitaire(); Solitaire world = new Solitaire();} // constructors public Solitaire () { window = new SolitaireFrame(); window = new SolitaireFrame(); init(); init(); window.show(); window.show();}

37 The Game Class: Solitaire (continued) //mutators public void init () { // first allocate the arrays allPiles = new CardPile[13]; allPiles = new CardPile[13]; suitPile = new SuitPile[4]; suitPile = new SuitPile[4]; tableau = new TablePile[7]; tableau = new TablePile[7]; // then fill them in // then fill them in allPiles[0] = deckPile = new DeckPile(335, 30); allPiles[0] = deckPile = new DeckPile(335, 30); allPiles[1] = discardPile = new DiscardPile(268, 30); allPiles[1] = discardPile = new DiscardPile(268, 30); for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++) allPiles[2+i] = suitPile[i] = new SuitPile(15 + (Card.width+10) * i, 30); allPiles[2+i] = suitPile[i] = new SuitPile(15 + (Card.width+10) * i, 30); for (int i = 0; i < 7; i++) for (int i = 0; i < 7; i++) allPiles[6+i] = tableau[i] allPiles[6+i] = tableau[i] = new TablePile(15 + (Card.width+5) * i, Card.height + 35, i+1); = new TablePile(15 + (Card.width+5) * i, Card.height + 35, i+1);}

38 The Game Class: Solitaire (continued) // inner classes // inner classes private class SolitaireFrame extends Frame private class SolitaireFrame extends Frame { /* expanded later */ } { /* expanded later */ } // internal data fields // internal data fields private Frame window;// the application window private Frame window;// the application window}

39 Notes on Class Solitaire Class declares and allocates class ( static ) variables for piles of cards on playing surface Class sets up allpiles array to "alias" all other piles, regardless of subclass Control goes initially to class method main main creates an instance of Solitaire application (its only action) Solitaire constructor creates window for application, initializes the playing surface, and displays window SolitaireFrame is an inner class inner class (from the glossary to Budd's UOOPJ textbook): inner class (from the glossary to Budd's UOOPJ textbook): –a class definition that appears inside another class. Inner classes are allowed access to both the private data fields and the methods of the surrounding class. Inner classes are frequently used in building listener objects for handling events. SolitaireFrame manages the application window

40 Inner Class SolitaireFrame // part of Class Solitaire private class SolitaireFrame extends Frame private class SolitaireFrame extends Frame { private class RestartButtonListener implements ActionListener private class RestartButtonListener implements ActionListener { public void actionPerformed (ActionEvent e) public void actionPerformed (ActionEvent e) { init(); init(); window.repaint(); window.repaint(); } }

41 Inner Class SolitaireFrame (continued) private class MouseKeeper extends MouseAdapter { public void mousePressed (MouseEvent e) public void mousePressed (MouseEvent e) { int x = e.getX(); int x = e.getX(); int y = e.getY(); int y = e.getY(); for (int i = 0; i < 13; i++) for (int i = 0; i < 13; i++) if (allPiles[i].includes(x, y)) if (allPiles[i].includes(x, y)) { allPiles[i].select(x, y); allPiles[i].select(x, y); repaint(); repaint(); } }}

42 Inner Class SolitaireFrame (continued) public SolitaireFrame() public SolitaireFrame() { setSize(600, 500); setSize(600, 500); setTitle("Solitaire Game"); setTitle("Solitaire Game"); addMouseListener (new MouseKeeper()); addMouseListener (new MouseKeeper()); Button restartButton = new Button("New Game"); Button restartButton = new Button("New Game"); restartButton.addActionListener( restartButton.addActionListener( new RestartButtonListener()); new RestartButtonListener()); add("South", restartButton); add("South", restartButton); } public void paint(Graphics g) public void paint(Graphics g) { for (int i = 0; i < 13; i++) for (int i = 0; i < 13; i++) allPiles[i].display(g); allPiles[i].display(g); }}

43 Notes on Class SolitaireFrame GUI window for the Solitaire game application Extends java.awt.Frame class Event-driven program – system GUI manager in control, user code "called back" in response to GUI events SolitaireFrame constructor sets window size, title sets window size, title adds mouse listener "callback" code to respond to mouse events adds mouse listener "callback" code to respond to mouse events adds restart button at bottom of window ("South") and "callback" code to respond to button events adds restart button at bottom of window ("South") and "callback" code to respond to button events

44 Notes on Class SolitaireFrame (continued) Inner class MouseKeeper 's method mousePressed called on mouse click event determines which pile selected determines which pile selected performs select operation for that pile performs select operation for that pile note use of polymorphism action depends on pile type (i.e., on which subclass) repaints window repaints window Inner class RestartButtonListener method actionPerformed called on button event reinitializes game reinitializes game repaints window repaints window Method paint of SolitaireFrame called by GUI when frame needs to be displayed note use of polymorphism note use of polymorphism


Download ppt "Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes."

Similar presentations


Ads by Google