Java – Objects First

:
An Introduction to Computer Programming using Java and BlueJ

Copyright 2008-10 Rick Gee

Table of Contents
Table of Contents ................................................................................................................................... i Preface to the reader.............................................................................................................................. 1 To students ........................................................................................................................................ 1 To teachers ........................................................................................................................................ 3 To everyone ....................................................................................................................................... 5 Acknowledgements ............................................................................................................................... 6 Notes ..................................................................................................................................................... 7 Chapter 0 – Introduction ....................................................................................................................... 9 Learning objectives ........................................................................................................................... 9 What is computer science?................................................................................................................ 9 Hardware ........................................................................................................................................... 9 Software .......................................................................................................................................... 10 Programming languages.................................................................................................................. 11 Summary ......................................................................................................................................... 12 Chapter 1 – Classes and objects – identity, state, and behaviour ........................................................ 13 Learning objectives ......................................................................................................................... 13 Introduction ..................................................................................................................................... 13 Definitions....................................................................................................................................... 13 Classes............................................................................................................................................. 15 The Student class ............................................................................................................................ 17 Class diagrams ............................................................................................................................ 17 Datatypes..................................................................................................................................... 19 The Professor class ......................................................................................................................... 20 Tradeoffs of storing the name as one field versus several .............................................................. 21 Behaviours ...................................................................................................................................... 23 A first look at Java .......................................................................................................................... 23 Documentation ............................................................................................................................ 25 Programming Style – documentation.......................................................................................... 25 Class declaration ......................................................................................................................... 26 Programming Style – class names .............................................................................................. 26 Instance variables ........................................................................................................................ 26 Programming Style – instance variables ..................................................................................... 27 Constructor(s) ............................................................................................................................. 27 Programming Style – constructors .............................................................................................. 29 Getters and setters ....................................................................................................................... 30 Programming Style – getters and setters ..................................................................................... 31

toString........................................................................................................................................ 31 Programming Style – toString .................................................................................................... 33 Creating another class, the College ................................................................................................. 33 Summary ......................................................................................................................................... 35 Exercises ......................................................................................................................................... 36 Chapter 2 – Introducing BlueJ ............................................................................................................ 37 Learning objectives ......................................................................................................................... 37 Introduction ..................................................................................................................................... 37 BlueJ ............................................................................................................................................... 37 Creating a new project ................................................................................................................ 38 Virtual machines and bytecode ................................................................................................... 41 Testing the Student class ............................................................................................................. 42 Inspecting an object .................................................................................................................... 43 Unit testing - definition ............................................................................................................... 46 Unit testing with BlueJ................................................................................................................ 47 Unit testing – the results ............................................................................................................. 52 Smoke testing .................................................................................................................................. 53 The Professor class ......................................................................................................................... 54 The College class ............................................................................................................................ 54 Summary ......................................................................................................................................... 54 Exercises ......................................................................................................................................... 55 Chapter 3 – Making decisions............................................................................................................. 59 Learning objectives ......................................................................................................................... 59 The if statement............................................................................................................................... 59 Boolean algebra .......................................................................................................................... 59 Boolean algebra – an example .................................................................................................... 61 A revised toString method .......................................................................................................... 62 Using the Java documentation ................................................................................................ 62 Programming style – if statements .............................................................................................. 64 Simpler tests .................................................................................................................................... 65 More complicated tests ................................................................................................................... 66 Summary ......................................................................................................................................... 69 Exercises ......................................................................................................................................... 70 Chapter 4 – Inheritance ....................................................................................................................... 73 Learning objectives ......................................................................................................................... 73 Abstract classes ............................................................................................................................... 73 The Person class .......................................................................................................................... 74 toString in an abstract class..................................................................................................... 75 The Person class, continued ........................................................................................................ 77 The Student class – a derived class ............................................................................................. 78 The Professor class ..................................................................................................................... 79 Summary ......................................................................................................................................... 79 Exercises ......................................................................................................................................... 80 Chapter 5 – An Address class.............................................................................................................. 83 Learning objectives ......................................................................................................................... 83

ii

Introduction ..................................................................................................................................... 83 Adding an address ........................................................................................................................... 83 The Address class ........................................................................................................................ 84 The Address class – the code ...................................................................................................... 85 The Address class – the code – in detail ..................................................................................... 86 The Address class – getters and setters ....................................................................................... 88 Person uses Address .................................................................................................................... 88 Making copies (cloning) ............................................................................................................. 89 The Address class – unit testing .................................................................................................. 91 Testing Address cloning .............................................................................................................. 92 The reserved word null ............................................................................................................... 92 The College class and addresses ..................................................................................................... 93 Summary ......................................................................................................................................... 94 Exercises ......................................................................................................................................... 95 Chapter 6 – Dates ................................................................................................................................ 97 Learning objectives ......................................................................................................................... 97 Introduction ..................................................................................................................................... 97 How old is a person? ....................................................................................................................... 97 Dates ........................................................................................................................................... 98 Details about calendars ............................................................................................................... 98 The MyDate class – a simplification .......................................................................................... 99 Programming style – a skeleton for a class ........................................................................... 100 Primitive types ...................................................................................................................... 100 Digression ............................................................................................................................. 101 The MyDate class – the code .................................................................................................... 101 The MyDate class – unit tests ................................................................................................... 103 Using MyDate objects............................................................................................................... 104 Simplifying the class diagram ................................................................................................... 105 Retirement of a professor .......................................................................................................... 106 Retirement of a professor - unit tests ........................................................................................ 107 Programming style – common errors ............................................................................................ 109 Summary ....................................................................................................................................... 110 Exercises ....................................................................................................................................... 111 Chapter 7 – Collections, part 1 ......................................................................................................... 113 Learning objectives ....................................................................................................................... 113 Life is complicated ........................................................................................................................ 113 Collections the college model contains......................................................................................... 114 The Java Collections Framework.................................................................................................. 116 A set .............................................................................................................................................. 117 A collection of professors ............................................................................................................. 118 HashSet ......................................................................................................................................... 119 Generic collections........................................................................................................................ 120 Programming style .................................................................................................................... 121 HashSet<Professor>...................................................................................................................... 121 The equals method .................................................................................................................... 122 The hashCode method............................................................................................................... 123

iii

How many items are in a set? ....................................................................................................... 124 What are the elements in the set? .................................................................................................. 124 Traversing a collection with a for loop ..................................................................................... 125 Adding a professor ........................................................................................................................ 125 Cloning a professor ................................................................................................................... 127 Removing a professor ................................................................................................................... 128 Traversing a collection with an iterator and a while loop ......................................................... 128 Another collection of professors – the department ....................................................................... 130 Listing all the professors ........................................................................................................... 131 The Singleton pattern ................................................................................................................ 132 Listing all the professors, continued ......................................................................................... 133 Collection of departments ............................................................................................................. 134 Collection of students ................................................................................................................... 135 Summary ....................................................................................................................................... 135 Exercises ....................................................................................................................................... 136 Chapter 8 – Collections, part 2 ......................................................................................................... 139 Learning objectives ....................................................................................................................... 139 Introduction ................................................................................................................................... 139 A collection of courses .................................................................................................................. 139 The Course class ........................................................................................................................... 139 Course – unit tests ..................................................................................................................... 140 Formatting the output ................................................................................................................ 140 A collection of courses, continued ................................................................................................ 142 The Section class........................................................................................................................... 142 Set? List? ............................................................................................................................... 142 What is a section? ..................................................................................................................... 144 The Singleton pattern revisited ..................................................................................................... 146 Listing a collection in order .......................................................................................................... 147 Comparable ............................................................................................................................... 147 Comparators .............................................................................................................................. 148 Unit testing the comparator ....................................................................................................... 150 Alternative versions of the comparator ..................................................................................... 151 Producing an alphabetical list of professors ................................................................................. 151 The for-each statement, revisited .............................................................................................. 152 BlueJ revisited........................................................................................................................... 153 Producing a professor list in numeric order .................................................................................. 154 Passing a Comparator to a method............................................................................................ 154 Registering students in sections .................................................................................................... 156 Producing an alphabetic class list ................................................................................................. 157 The for-each statement, revisited .............................................................................................. 158 Producing a class list in numeric order ......................................................................................... 159 Students enrol in sections.............................................................................................................. 160 Summary ....................................................................................................................................... 160 Exercises ....................................................................................................................................... 161 Chapter 9 – Collections, part 3 ......................................................................................................... 163 Learning objectives ....................................................................................................................... 163

iv

Introduction ................................................................................................................................... 163 The Meeting class ......................................................................................................................... 163 Instance variables ...................................................................................................................... 164 Behaviours ................................................................................................................................ 164 Time arithmetic ......................................................................................................................... 164 Section uses Meeting .................................................................................................................... 166 The if statement, revisited ..................................................................................................... 168 Creating the collection of Meeting objects ............................................................................... 169 Section uses Meeting – displaying the times ................................................................................ 170 Arrays ........................................................................................................................................ 171 StringBuffer .............................................................................................................................. 172 Adjusting to different colleges .................................................................................................. 173 Another for loop ........................................................................................................................ 175 Processing all the meetings ........................................................................................................... 175 Manipulating StringBuffers .......................................................................................................... 176 Placing data in StringBuffers .................................................................................................... 176 Converting numbers to day of the week ................................................................................... 178 Processing second and subsequent meetings ............................................................................ 179 A lot of code .............................................................................................................................. 179 Programming Style ....................................................................................................................... 182 Course contains Section ................................................................................................................ 183 Mark, and Student contains Mark ................................................................................................. 184 Professor contains Section ............................................................................................................ 185 Summary ....................................................................................................................................... 185 Exercises ....................................................................................................................................... 187 Chapter 10 - Collections, part 4 ........................................................................................................ 189 Learning objectives ....................................................................................................................... 189 Introduction ................................................................................................................................... 189 Grade Average ............................................................................................................................... 189 When to calculate an average ................................................................................................... 189 Weighted average ...................................................................................................................... 190 The transcript method - original version ................................................................................... 190 Knowing when a semester changes .......................................................................................... 191 Transcript – a skeleton for changes ........................................................................................... 191 When the semester changes ...................................................................................................... 192 Integer division ..................................................................................................................... 193 When the semester remains the same ....................................................................................... 194 The declarations ........................................................................................................................ 194 The overall average ................................................................................................................... 194 The transcript String – problems and deficiencies .................................................................... 195 The String class and its methods ............................................................................................... 195 Details of split ....................................................................................................................... 196 Details of indexOf and lastIndexOf ...................................................................................... 197 Reversing a String ..................................................................................................................... 197 Palindromes............................................................................................................................... 198 The transcript String – reordering ............................................................................................. 199

v

The transcript String – problems and deficiencies, continued .................................................. 201 Summary ....................................................................................................................................... 203 Exercises ....................................................................................................................................... 204 Chapter 11 - Exceptions .................................................................................................................... 205 Learning objectives ....................................................................................................................... 205 Definition ...................................................................................................................................... 205 Examples ....................................................................................................................................... 206 Runtime and nonruntime exceptions ............................................................................................ 207 Creating and throwing exceptions ................................................................................................ 208 Catching exceptions ...................................................................................................................... 212 CloneNotSupportedException .................................................................................................. 212 Bad input data ........................................................................................................................... 213 Summary ....................................................................................................................................... 213 Exercises ....................................................................................................................................... 214 Chapter 12 – Persistence, part 1 ........................................................................................................ 215 Learning objectives ....................................................................................................................... 215 Warning to the reader .................................................................................................................... 215 Why persistence? .......................................................................................................................... 215 External devices ............................................................................................................................ 216 Streams .......................................................................................................................................... 216 Persistence via object serialization ............................................................................................... 217 Object serialization - Address ................................................................................................... 217 Object serialization – MyDate .................................................................................................. 221 Object serialization – Meeting and Mark.................................................................................. 221 Object serialization – Person, Student, Professor ..................................................................... 221 Object serialization – some subtleties ....................................................................................... 221 Object serialization – creating writeObject and readObject methods ....................................... 222 Object serialization – Section and Student ............................................................................... 224 Object deserialization – Section and Student............................................................................ 226 Programming style .................................................................................................................... 228 Object serialization – Section and Student, revisited................................................................ 228 Object serialization – Professor ................................................................................................ 228 Object serialization – College ................................................................................................... 228 Summary ....................................................................................................................................... 229 Exercises ....................................................................................................................................... 230 Chapter 13 – Persistence, part 2 ........................................................................................................ 231 Learning objectives ....................................................................................................................... 231 Persistence via XML ..................................................................................................................... 231 A Digression - Scalable Vector Graphics ...................................................................................... 231 Using an XMLEncoder - no collections ................................................................................... 232 Using an XMLDecoder - no collections ................................................................................... 234 Using an XMLEncoder - with a collection ............................................................................... 237 Using an XMLDecoder - with a collection ............................................................................... 242 Programming Style ................................................................................................................... 243 Using XML – summary ............................................................................................................ 243

vi

...........................................................................................Creating a GUI – Data entry screens.............................................................................................................................................................................................. 258 The label Bindings .................................................................................................................................................................. 247 Learning objectives ......................................................................................................................................... 244 Persistence via traditional files .................................................................................................................... 267 vii ..................................................................................................................................... 266 Create a mnemonic ..... 249 Installing the RelativeLayout layout manager .... 244 Exercises ............................................................................................................ 254 Making the JFrame visible ............................................................................................... 247 GUI ........................................................................................................................................................... 247 Warning to the reader ............................................................... 265 Cancel button ....................................................................................................................................................................................... 261 Displaying the frame ................................................................................................... 262 Keep it visible ........................... 256 Explaining the code................................................ 251 Creating a data entry screen ...............................................................................................................................................................................................................Persistence via databases ............................................................................................................................................... 265 Add the button and its bindings to the frame ............................................................................................................................................................................................................ 249 Layout managers ...................................................................................... 262 Create the frame ....................................... 265 Create the button .......................................................................................................................................................... part 1 ..................................... and ActionListeners ........................................ 257 The layout manager...................................................................................................................................................................... 244 Summary .................................................... 263 Displaying the frame ................................................................................................................................................................................................................................................... 266 ActionEvents................................................................................................................................................................................ 266 The OK Button ...................................................................................................................................................................... 266 The default button ........................ 258 The other labels ...................................................................................... 262 Position and size the frame ................................................... 263 Answering some questions ......................................................... 263 Buttons ...................................................................................................... 257 BindingFactory .......................................................................................................... 252 Import statements ...... 261 Summarizing building a data entry screen .................................................................................................................................................................................... 260 Textfields................................ 248 Some HCI considerations ........................................................................................ 257 The labels ............................. 253 Creating the JFrame ............................. 260 Other textfields.......................... 263 Exit ........... 257 The JFrame..................................................................................................................................................................................................................................................................................................................................................................... 262 Make it visible............................................................................ 252 How the data entry screen should appear ...................................................................................................... 265 Create the button‘s bindings............................... 261 Done!.................................................................................... 266 Button action ................................... 247 Introduction ...... 245 Chapter 14 ...........................................................................................................................................................................................................................................................................................................................................................

................. 279 Create a column of panels ................ 299 Learning objectives .... 274 Exercises .... 279 Create the three panels ........................................................... 270 Verifying the day of the month ........................... 283 Arrays ....................................................................................................................................................................................................................................................................................................................................................... 282 The meetings .............................................................................................................................. 297 Chapter 16 ................................................................................................ 277 Introduction ................................................................................................................................................................... 284 Create the middle panel................................................................................................................................................................................. 267 Linking an ActionListener to a JButton .......................................................................................................................... 289 ActionListeners for radio buttons .................................................................................................................... continued ................................................................................................................................................................ 270 Verifying year and month............................................................................ 293 Which layout manager should we choose? ............................................................................................................................................. 295 Summary ............................ 299 viii ................................... 282 Labels ................................................................................................................................................................................................................ 296 Exercises .................................................................................................................................................................... part 2 ........................................................................................................................................................................................Creating a GUI – Data entry screens....... 291 ActionListeners for checkboxes ......................................................................... 268 Behind the Cancel Button .......................................................................................................................................................................................................... 277 Learning objectives ....................................................................... 281 Decorate the panel..................................................................................................................... 267 What does an ActionListener do.....................................................................Creating an ActionListener ..................................................................................................................................................... 287 InputVerifiers . 267 What does an ActionListener do? .............................................................. 292 Decorate the middle panel ......................................................................................................................................... 293 Button ActionListeners .................................. 293 The bottom panel ...................... 285 ButtonGroup ..................................................................................................... 294 Summarizing building a data entry screen ........................................... 285 Radio buttons .... 275 Chapter 15 ......................................................................................................................................................................................................................................................................................................................................................................................................................... 281 Create the middle panel .................................................................................................. 295 Some general comments on data entry .......................................... 294 Done!.......................................................................................... 277 Create the frame ................................................................................... continued? ................................................................ 287 Placing the arrays in the frame..........Creating a GUI – Menus ............................... 286 Checkboxes . 286 An array of radio buttons .............................................................................................................................................................................................................................................................................................................................................................................................................. 286 An array of textfields ..... 269 Editing data ............................................................................................................................................... 280 Place boxes in the panel ................................................................................................................................................................ 274 Summary ..... 272 Data entry for other classes ................................... 277 Building the Section data entry screen.................................................... 279 Populate the top panel ....................................................

..................................................................................................................................................................................................................................................... 311 Running an applet .................................................................................................................................................................................................. 336 Creator pattern ............................................. 309 Exercises .............................................................................................................................................................................. 308 Conclusion .......................... 320 Hello world .................................................................................................... 308 Summary ....... 300 Accessibility........................................................... 322 Canadian flag .................................................................................................................................. 333 Learning objectives .. 300 Implementing the menu ......................................................................................................... 327 Chapter 18 – Design Patterns .................... 333 Introduction ............................................................................................. 335 Marker interface pattern ........... 299 Definitions................................................................................................................................................................. 336 Low Coupling ....... 311 Learning objectives ................................................................................................................................................................................. 311 Creating an applet ............................................................ 312 An applet (as created by BlueJ) under the microscope .............................. 318 destroy ............................. 305 Definition .................................................................................................. 310 Chapter 17 .................................. 299 Designing the menu system ...........................................................................................................................................................................................................................Introduction ............................................................................... 325 Summary ............................................................................................................................................................................................................................... 304 Help .................................................................... 303 Completing the menu .................................................................................................................................................................................................................. 336 High Cohesion .............................................................................................................................. 321 A problem........... 317 start ......................................................................................................................................................................... 317 stop ................................ 303 Performing actions ............................................ 305 Steps to follow ......................................................................................................................................................................................................................................................................................................... 323 Creating HTML to run an applet.........................................................................................Applets ........................................................ 305 Internationalization .................................................................................................................................................................................................................................................................................................................................................................. 323 A quick introduction to HTML .......................................................................................................................................................................................................................................................................................... 311 Introduction ................................................................................. 337 ix .................................................................................................... 319 getAppletInfo ....... 326 Exercises ............................................................................................................................................................................................................................................................... 333 Interface pattern .............. 307 Who did the translation? ............................................................................................................................................................................................................. 318 paint................................................................................................................................................................................................................. 314 init ..................................................................................................................................................................................... 299 Creating the menus ...................................................................................................................................................................................................................................................................... 322 Squares .. 319 getParameterInfo ............................................................................................................................................................................................................................................ 305 The Java statements to make the magic happen .......

...................................................................... 349 Converting a rational number to a double.......................................................... 343 Learning objectives .................... 353 Learning objectives ............................................................................ 340 Exercises ........ 349 Arithmetic operations and complex numbers ............................................................................................................................................................................................................................................................................................................................................................................................................................................. 349 What if ints are not big enough? ..........Fibonacci .................................Mathematical examples ........ 354 Sample greatest common divisor calculations .....................................................................Fibonacci........................................ 337 Delegation ..................................................... 343 The java.............................................................Observer or Event listener ............................................................................................................................................................................ 348 Subtracting....................................................................................................lang.................................................................................................................................................................... 361 Dynamic programming .....................................................Mathematical methods .....................................Math package ................................................................... 349 Complex numbers ........................................................................... 343 Introduction ........................................................................................................................................................................................... 344 Rational numbers ....................... 362 Storing the data ..................................... 359 A Formula! ................... 339 Summary ................................................................................................ continued .............................................................................................. 341 Chapter 19 ................................................................................ 356 Iterative Fibonacci method .......................... 338 Model-view-controller (MVC) ........................................ and dividing rational numbers ................................................. 338 Lazy initialization pattern . 364 Deserializing the data ............................................................ 362 Serializing the data ................................................................................................................................................................................................................................................................................................................................. 353 Introduction ............. 344 BigInteger................................................... 357 Recursive Fibonacci method ..................................................................................................................... 360 The Ackermann function........................................................ 343 BigInteger .....................................................................................Fibonacci.. 354 A recursive greatest common divisor method ......................................................................................... 345 Adding rational numbers.................................................................................................... 355 Fibonacci numbers ............................................. 338 Singleton pattern ............................................................................................................................................ 365 Storing the data – Ackermann function ......................................................................................... 357 The factorial function .............. 350 Implementing ComplexNumber ............................................................................................ 350 Summary ...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... 361 Recursive implementation of the Ackermann function ...................................................................................... 351 Chapter 20 ............................................... 360 Recursive choose method ........ 337 Factory ......... 350 Exercises ..................................................................................................................... 348 Inverting a rational number ...................... 365 x ................................................................................................................................................................................................... 353 Greatest common divisor (gcd) ..................................................................................................................................................................................................... 358 The choose function . 361 Definition of the Ackermann function .......................................... multiplying.................................................................................................................................................................................................................

.......... 391 Lab Assignment 4 ................ 388 Lab Assignment 3 ........................................................................ 401 xi ...................................................................... 377 References ..........................Getting to know you .............. 374 Summary .................... 399 Index ................................................................Threads.......................... 369 Threads ................... 369 Threads and Swing .................. 369 Introduction .................Teams and Leagues ........................................................................................... 396 Lab Assignment 7 ..................................... and other topics ....................................... 366 Summary ............................... 380 Appendix 1 – Sample lab assignments ......................... 387 Lab Assignment 2 ....................................................................................Data Entry Screens ................................................................. 381 Lab Assignment 0 ...................Serializing the data – Ackermann function ....... 397 Subsequent lab assignments ...........................................................................................................................................................................................................................................................................................................................................................................................................definition .............................................................................. 373 Input and output .................................... 370 Inner classes .................................................................................... 393 Lab Assignment 5 ................................. 372 public static void main(String[] args) ....................................................................................................................... 382 Lab Assignment 1 ....................................................... 369 Learning objectives .................... 379 Online references ......................................................................... 381 Introduction .........................................................................................Mathematics I ............................................................................................................................................................................................................................................................. 368 Chapter 21 ............................................................................... 379 Printed Reference materials ....................................................................................................................................................................................................................................................... 367 Exercises ............................................................................................................................................................................. 375 Exercises ...........................................................................................Mathematics II .......................... 376 In Conclusion ................ 394 Lab Assignment 6 .....................................................................................................................................................................................Reporting ..... 371 Refactoring .....................................................................................................................................................................................................................................................................................................................................Players ........................................................................................................................................................................................... 366 Deserializing the data – Ackermann function .....................................................................................And now for something completely different ....................

so they can see the advantages of objects. or with a small amount of computer resources. of computer science involves using a computer to solve a problem. and does it correctly. easy-to-read. You can test a program and it may produce what you thought it would. easy-to-read. Tested means that you can trust the results the program produces. and together. Tested to ensure requirements means that the program does what it is supposed to do. but does it 1 . but not all. then how can you improve or change it? How can you fix it if it contains an error? We will use tools called Checkstyle and PMD to help us meet these goals. It allows us to save the tests and reuse them whenever we make a change to the programs. Reflecting these ideas. but wait until you‘ve had a chance to look at this one. In this book we gloss over some of the details of how the program you write is translated into something which the computer can carry out. as early as possible. not another Java textbook! Perhaps that‘s a valid comment. efficient. To students What is computer science? How does this textbook help you study computer science? Much. By ―good‖. But a detailed discussion of efficiency is beyond the scope of this course. If you or someone else cannot understand what you have written. We emphasize unit testing using a tool named JUnit. well-documented. a program may work faster when you give it more memory. Efficient means that the program carries out its task quickly. Clear. and we focus on how to write good programs. or a better solution becomes available. this is not just another Java book. and well-documented go together. you have failed in creating something which can be used. and tested to ensure they meet the requirements.Preface to the reader Oh no. instruction which the computer performs. This is because programs are continually changing. The instructions to solve the problem are written as a program or programs. Often these two characteristics are in conflict. I also believe that students should use a large application as an example. which allows us to test each portion of the program separately. The problem they are solving changes. Can someone else read your program and understand what it does? If not. we mean clear. There is a lot of discussion amongst teachers about when to introduce objects in Java. perhaps on the first day of an introductory course. I feel that objects should be introduced early.

Mac OS. This is a modern language which I find very enjoyable and easy to use. Since there are limits on how many students a professor can teach at one time (the college has a goal of having no large classes). we need a way to save large amounts of data. We will use a tool called BlueJ to help us integrate all these features – the Java language. A course is a collection of related topics. perhaps all taught by the same professor. January through April. A section of a course offered in one semester is different from a section of a course offered in a different semester. Java is a good language with which to start. what some call post-secondary education and others call tertiary education. The semesters run from September through December. when there are many students wanting to take a course there may be a number of different sections of the course being offered. where the students study material on their own and present their discoveries to the rest of the class. where the professor teaches and the students participate by listening and asking questions. Some are best taught using seminars. 2 . or seminars. JUnit testing. Checkstyle. the professors teach students who are enrolled in sections of courses. we use the Java language. The academic year is divided into three portions. In order to complete a program of study. Some courses are best taught using lectures. you can use computers running Linux. A significant part of learning Java is becoming familiar with the documentation describing these libraries. perhaps taught by different professors. The language itself is very simple. To model this college. or Windows. since Java will run on many different operating systems. the Java libraries. There are many other languages available so you will need to learn many languages during your career in computing. it is a constant reminder of what you can produce using Java. labs. Some courses may be offered in two or three semesters. and gains much of its power from libraries which people have created to carry out specialised tasks.produce what it should? We don‘t have a tool to test that it meets the requirements. This is a measure of the popularity of Java and the various types of programs it is used to create. The example is a North American college. Some courses use a mix of two or all of these. but we will be very careful in ensuring we do meet them. For much of this book. Some are best taught using labs. and the professors provide assistance. and May through August. there are meeting times associated with each. Whether a course uses lectures. Most importantly. called semesters. The number of libraries is truly amazing. we use one example. it is available online. perhaps resulting in a diploma or a degree. with marks being awarded for each attempt. Since BlueJ is written in Java. When we write programs. and PMD. Students sign up to take many different courses. students may take a course more than once. At this college. where the students are doing predefined activities.

I have also used the RelativeLayout manager for designing GUIs. other competitors have appeared. and other competitors were not yet available. rather than one large example. Note that I do assume you have used computers before and are familiar with some of the terminology. but the version included serves to introduce the idea of unit testing.2 as it was the most recent stable version at the time.1. Java 6 has become available. In checking all the code in this textbook.Some have suggested that an introductory textbook like this should use many small examples. One thing which caused many of them some difficulty is the use of one large project to form the examples in this book. Of course. To see this textbook published. To teachers Like many textbooks. Java 5 was the most powerful version of Java available at the time. When I began writing. I hope you enjoy the approach I have used here. I do not assume any programming experience. the problem is that it is very easy to write small problems using objects. I have used version 2. it should be understandable even if you are not interested in sports. I agree with the latter perspective. Also in the preface to students. In the time it has taken to complete this book. using one example in the lab assignments also caused similar concern. the labs involved the records you keep when watching birds. so I decided to create my own.5. Another time the course was taught. I have used the Creative Commons approach. In the preface to students I have explained the project for the benefit of those who are not familiar with the way a North American college or university works. BlueJ does not include the most-recent version of JUnit. this one arose out of a perceived need. I addressed the question of one large example instead of several small ones. some small and some large. Newer versions offer support for team work. Since then other versions have become available. I have not included a discussion of that aspect in this textbook.3 (the most-recent version at the time) along with the Checkstyle and PMD extensions. and I wanted to do it objects-first. I hope you find it interesting. The lab assignments included in the appendix also include a large project. But others have suggested that the way to see the benefits of objects is to see them in a large project. The competition was between editions. I wanted to teach an introductory programming course using Java. The exercises at the end of each chapter include other examples. 3 . Although it is based on a sports league. Basically. My reviewers have given me much interesting feedback. I could not find a textbook that met my needs. Since then. but it would make a valuable addition to the course. I used BlueJ version 2. but it does not appear to affect anything here.

I have used this textbook with a small group of students and with a larger group. Other colleagues have used the textbook with large groups of students. but because they were not objects-first people. starting with mathematics. related to the environment and follow-up course. instead of teaching the ACM courses CS1 and CS2. it covers all the material in CS1 plus a little of CS2. I have used this textbook as the basis of a two-semester course. ―<that topic>‖ could be persistence. My reviewers have also asked why is <that topic> included. All of those chapters are not dependent on the rest of the book. But should you be using this textbook for a two-semester course.but the objects are not crucial to success. Like this. They had some difficulty. We find that the material in this book is adequate for about 80% of a two-semester course. and there are chapters. or your preferences. to be followed by a data structures course. patterns. That is. Depending on the reviewer. However. Other brief sections which present interesting but non-essential material are shown with a grey background. For the rest of the course we use material specific to Okanagan College. except that there is some persistence in the mathematical chapters but you could omit that too. and/or mathematics. Notice that after a while I find I have exhausted the North American college example of ideas. Thus I need a language which forces everything to be an object (Java almost meets that requirement). which can be appreciated by students learning to program for the first time. you could write the small programs without using objects if you wished. in the example in the textbook. applets. The team work features of BlueJ would be an ideal supplement. Thus. GUIs. At that point we look at some other examples. which you could omit without disturbing the integrity of the course. be prepared to supplement it towards the end of the second semester. That is. should you prefer. you may wish to omit any or all of those topics. and in the lab assignments. we cover the content in three semesters. not because of the class size. mentioned above. That is. But I believe that using objects is an important way of designing your software. or I need a project which is so large that you must use objects. 4 . depending on the length of your course. the students. I have taken the second approach. this textbook is more than adequate for a one-semester course. I have included them because I feel they are important topics. so I want to force people to use objects.

in many ways. I hope it meets your needs. I hope I have those powers. please contact me. I am Canadian.To everyone Thank you for purchasing this book.com/welcometochiasmus. BC Canada rgee at okanagan dot bc dot ca p.chiasmus. Yes.‖ This is a quotation which I found at http://www.shtml. and the examples are. Canadian. 5 . positive or negative. and especially if you find any errors or omissions or unclear sections. so the spelling in this book is Canadian.s. Rick Gee Okanagan College Kelowna. Should you have any comments. and familiar things new. Remember that Dr Samuel Johnson said ―The two most engaging powers of an author are to make new things familiar.

Jeff Carpenter. Neesha Jaswal. and my students. Alex Saunders. BC Originally completed summer 2008 Revised summer 2010 6 . Kurtis Lewke. I‘d like to thank Rob McArthur and his students for their patience and assistance with version 2. I would like to thank the reviewers who provided me with interesting and challenging feedback. Andrew Faraday. Sergey Raspopov. and Brandon Potter for their patience and assistance with version 1. Daren Ling. Rick Gee Kelowna. Jay Olson. Fraser Wozny. I would also like to thank my students. Mike Tribe. Nicholas Goertz. Cory Ingram. and Paul York for their patience and assistance with version 3. Jonathan Gaudet. I‘d like to thank Peter Kossowski and his students. Kevin Koehler. Sarah Fredericks. Maria Nemes. Chris Hollman. Patrick McCallen. Claire Bemben.Acknowledgements I‘d like to thank my colleagues Rob McArthur (Okanagan College) and Joseph Fall (Capilano University) for their help in the writing of the examples in this textbook. Philip Pereboom. Chase Marsh.

Java snippets.3. The first time a word is defined. This is additional material. While interesting. Similarly Person is a class but a person is a member of the human species. The occasional paragraph is shown with a light-grey background. Thus.Notes Statements in the Java language are shown using this font. Address is the name of a class we create but address is the place a person lives.5. which expands on the material nearby. it is shown in italics. the material is not crucial. are also shown using this font. Student is a class but a student is a person. Professor is a class but a professor is a person. including variable and class names referred to in the body of the text. 7 . and Section is a class but a section is a specific offering of a course. Standard Edition. and have been run through BlueJ 2. All the examples used assume the Java 2 Platform.

8 .

Information is ―the result of 9 . you will be able to:     Describe hardware Describe software Name a few programming languages Say why the author believes Java is the appropriate language to use to introduce programming What is computer science? Computer science is not the study of computers themselves. Perhaps we should call it ―computing science‖. but a computer can function as an MP3 player. Let‘s have a quick look at those terms. about which I assume you already know something. These instructions come via programming. we need to understand hardware. Thus. Some define hardware as the parts of a computer you can hit when something goes wrong. solutions which often use computers. or PDA) is not a computer.) An address book (a personal digital assistant. a computer may perform various tasks. European institutions often use the word informatics. To study computer science. Hardware Hardware is the parts of a computer which you can touch. software. Depending on the programming. A smartphone is a computer. (The word data comes from the Latin language. Computer science is the study of the use of computers in various parts of life. To understand computers. Data is the things we know or are given. the study of computing. Some universities and colleges have done that. Older cell phones are not computers. we need to understand how to design solutions to problems. The hardware is capable of responding to instructions on how to do a task. both commercial and non-commercial. an MP3 player is not a computer. meaning ―given.‖) Data includes the students who have enrolled in a course and the marks they have earned. that would be computer engineering. A computer transforms data into information. and programming. but a computer can function as a telephone (with the addition of a microphone and speakers. since it performs only one task.Chapter 0 – Introduction Learning objectives By the end of this chapter. but a computer can function as an address book.

UNIX. Modern computers often have many CPUs (called cores). although when you have multiple CPUs (or cores) you can use a slower speed.‖ (http://www. calendar.). It all depends on what programming can be done for the computer. abbreviated MHz) but is now measured in gigahertz (billions. 10 . Hardware – the parts of a computer which you can touch. When you get an operating system. The keyboard for a Macintosh computer has an ―Apple‖ key. browser. of cycles per second. Second. His name has been adopted as the unit to measure frequency. This includes an operating system (a version of Windows. ROM is more expensive than RAM. and hence more powerful. the more RAM your computer contains the better. the faster the CPU. Software Every computer has some programming available for it. This is the part of the computer which carries out the instructions given by a program. with the CPU giving each a portion of its time.htm) For example. The operating system allows other programs to run. There are many different layouts for keyboards (Where is the backspace key?) depending on the manufacturer of the keyboard and many different special keys.  Read-only Memory (ROM) – a portion of memory which uses a battery to retain its contents when the power to the computer is turned off. Solaris. etc.orafaq. it often comes with some other programs – word processing. often much less. The marks students earn can be transformed into semester averages.processing. Heinrich Rudolf Hertz was a German physicist in the late 1800‘s.  Random Access Memory (RAM) – used to store data while a program is running. the better.  Mouse or trackball – used for input. programs. often on one chip. various utility programs. In general. clicking buttons or selecting items from a menu. information which will in turn become data for determining which scholarships students win. The reason you want more memory is twofold. ROM is used for things like configuration information. 1 hertz = 1 oscillation of a wave per second. Mac OS. and a boot program.  Monitor – the screen on which output from a program is displayed. This output may be text or graphics. The speed of the CPU used to be measured in megahertz (millions of cycles per second. We will use the mouse quite extensively to control BlueJ. so you will have less ROM than RAM. you can run larger. RAM was measured in kilobytes (KB).  Keyboard – used for input. and a few games.com/glossary/faqglosi. or information. for example. In the old days. Then memory became cheaper and computers contained megabytes (MB) or gigabytes (GB) of memory. or thousands of millions. abbreviated GHz). This includes:  Central Processing Unit (CPU) – the brains of the computer. the raw data about the students in a class can be transformed into a class list. which is executed when the power is first turned on. manipulating and organizing data in a way that adds to the knowledge of the person receiving it. you can have more programs in memory simultaneously. In general. Linux. First.

personal computers. How do you know that the author is reliable? In general. 11 . I have found that the articles about computer science are reliable and I will quote many of them in the material that follows. perhaps one to track the inventory in your warehouse. When you learn your first programming language. Or perhaps you will want to create programs to help you write more programs. and to run programs. Why Java? It‘s a language commonly used today. Perhaps you want to create a game. You may have heard of BASIC. Programming languages Programming is done using a variety of languages. or to track the hours worked by employees and pay them.wikipedia. These platforms include mainframes. What is a paradigm? It‘s a way of thinking about what you are doing. to make backup copies of them. it allows you to do many different tasks and thus has applicability in a wide variety of domains (different areas of programming – games. to locate files you have created. and Visual Basic. Today there are many languages in common use – including Java. Why are there so many different programming languages? Because they were designed to serve special purposes. C++. C#. These are all programming languages which have been used in the past and continue to be used. you need a programming language and the ability to use it.You will be using some parts of the operating system in your labs. It is a powerful language. For those tasks. it‘s good to start with an easier one. and mobile devices. C. It‘s the set of practices that define a discipline during a particular period of time. in a variety of styles. and student registration are examples) on a variety of platforms. (And yes. Pascal.) Pascal was developed in 1970 as a language for teaching people how to program. C was developed in 1972 for use with the UNIX operating system. You may also want to create new programs. in which the entries in the encyclopaedia are written by people like you and me. Java is a language that uses a popular programming paradigm. object-oriented programming.org/wiki/Paradigm) Wikipedia is an online encyclopaedia. That is. to some degree. That means there is a certain risk in using Wikipedia as a source. etc. Or you may need the money to hire someone who does. database. its predecessor language was called B. so I have chosen Java. and is being used more and more as time goes by. BASIC (an acronym formed from the phrase Beginner‘s All-purpose Symbolic Instruction Code) was designed in 1963 as a tool for teaching people to program. (http://en.

hardware. That is one of the topics in chapter 1. hopefully better. and programming are combined to create instructions to control a computer. Summary In computing. software. the dominant paradigm is object-oriented. a paradigm is a way of creating programs. At one time. using a particular programming paradigm. ways of doing things. paradigms change as people develop different. Java supports the object-oriented paradigm. Over time. 12 . Now.In programming. using popular techniques which allow you to create ―good‖ programs. The instructions are expressed in a programming language. the paradigm was ―structured programming‖. Perhaps we should define what we mean by object-oriented.

so you‘ll want to take it slowly. but not always the datatypes necessary to describe the real-world data. Definitions When you write a program. and behaviour Learning objectives By the end of this chapter. Then we discuss how to write a class. The programming language you use will allow you to create new datatypes. constructor. the tool we will use to test the programming that we create.Chapter 1 – Classes and objects – identity. state. setter Create constructors. getters. getter. you will be able to:          Define class Define object Draw a class diagram Implement simple classes in Java Define method. the tool we will be use to help us in our modelling and our coding. and implement. a toString method Introduction This chapter contains a lot of material. and how we model them. Finally. Data in the real world comes in many different types. we use what we have learned to create a second class. First we discuss what objects and classes are. Depending on the language you are using. Then we look at BlueJ. In object-oriented programming. Then we look at JUnit. you will have different datatypes provided to you. we create new datatypes by creating new classes and using the classes to create objects. you provide the instructions which tell the computer how to process pieces of data. and setters Describe some primitive datatypes and some datatypes represented by classes Document Java code Describe the purpose of. 13 .

A system involving college registration will need other objects. and you may incur library fines. Many of the houses in those subdivisions look alike. you earn marks in courses. Each course the college offers is an object. Thus we have a definition of a class – a blueprint for creating objects – which makes more sense now than when we first proposed it. All students have things in common. We need to explore the concepts of object and class more fully before we can understand the definitions. When two objects are related in some way. like a mathematical function. Similarly. This idea of a blueprint also works in other areas as well. they are made from the same blueprint. One object may participate in many associations. are an object in a system involving college registration. There are many student objects enrolled at Okanagan College. the word class has a very specific meaning – a blueprint for creating objects. and student number. rather than just creating objects. or imaginary. But think about this for a moment. Whenever you find things having common features. And look at some of the new subdivisions being built around our cities. we say there is an association between the objects. All these objects have some things in common. the word object has a very specific meaning – an object is an instance of a class. There is an association between a student and a section. of something in which we are interested. so there can be associations between one object and another. You receive a final mark in each course you take. For example. like name. So what is an object? Since we are talking about computer programming. 14 . A student registers in a section. they don‘t really tell us anything. implemented using a computer language and stored in a computer. and a section is an object. an object is a representation. This ―something‖ may be real.In computing. a student number. Many of the floors of the building have the same layout. But those definitions are circular. and an address. they each have a name. Many of the apartments have the same layout. address. They were all made from the same blueprint. you create a blueprint for creating objects. you are registered in sections. Each section has an association with a course. like a person or a piece of furniture. Think of a new building containing apartments (flats). They each have associations with sections of a course. You. They are all made from the same blueprint. There are many students at a college. all are objects. a student.

one which I have reserved for code in the Java language. we could consider the room itself. In computing. like tell you about its state). It has a room number and a capacity. A Room class could represent a room. A statement in English is a complete thought. Looking for other objects in the room. These usually are statements. a title. Java is not a pure OO language but it comes close. And we have a definition of an object – an instance of a class. This indicates that we may be implementing the Room class in Java. but they are different apartments. and behaviours (the things it can do. several apartments may have the same layout. some of the units are identical and some are mirror-images of each other.In the building in which I have recently purchased a home. They have a description. an object has an identity (its name). the chairs. 15 . What other classes can we identify in this room? Well. and an author. Classes We have identified ―student‖ as a class whose objects are in this room. A pure object-oriented language lets you use only the OO style. we could consider the desks. All your textbooks have an ISBN. The word code means the instructions we write in Java. But they are built from the same blueprint. It allows you to create classes and objects. A Textbook class could represent a textbook. This is because of its roots in the C language. state (including the owner and the colour of the front door). In the construction examples above. depending on the application. An OO language is one which supports OO programming (OOP). and behaviours (who owns the house? Is it owner-occupied?) So what is object-oriented (OO) programming? It is a programming style (a paradigm) which uses classes and objects. Note that I have shown the name Room in a different typeface. it has state (the values which it knows). As we will see. C++ is not a pure OO language. They may have serial numbers attached. for example). and the tables themselves. They too have identities (apartment number 307. A Furniture class could represent them. state (the names of the occupants). there are a few things in Java that are not objects. Smalltalk is a pure OO language. A statement in Java is a complete instruction to the computer. and behaviours (what is the rent and when was it last paid?) Houses have identities (the street address).

A Professor class could represent a professor.‖ This was the idea that if there was a nuclear war. The weather is becoming more changeable. etc.Your professor represents a class. without knowing the consequences of these changes. So where do we start when we want to model these real-world classes? Why do we want to model real-world classes in a computer? Perhaps we would like to be able to determine the effects on our institution if we reduced the class size. we may actually try something like this if a large volcano erupts. Most people believe this is having an effect on climate and weather. Your professor has a name and an employee number. So how do we make models using the Java language? 16 . the same way you have a name and a student number. for example) which they have never seen before. they had to create a new word for the American Robin! We appear to be making some serious changes to the world. Well. and reduce much of the plant growth. Some experiments are not so simple. When Mount Pinatubo erupted in June 1991. this is not something we would like to do in the real-world to see what would happen. Most glaciers are melting. The Inuit of the Canadian Arctic are seeing birds (the American Robin. whether they are in the mountains. Those questions are relatively simple. the resulting explosions would throw so much dust into the atmosphere that the amount of sunlight reaching the surface of the Earth would be reduced significantly. Again. methane. or the Antarctic. we have been adding large amounts of greenhouse gases (carbon dioxide. we did see a cooling effect but only for a short time. Plants are blooming earlier than previously seen.) Once we have identified the classes. Would it not have been better to make a model and do the experiments there? When I first began teaching. So we are surrounded by objects and can use our language to determine the classes from which they are instantiated (created as instances. the Arctic. we will go on and identify the associations between them. To add an environmental note. This would lower the temperature. and we could do the experiment in the real world.) to the atmosphere during the past 250 years. there was some discussion about ―nuclear winter. How many more sections of courses would we need to offer? Do we have enough classrooms? A model would help answer those questions.

we will use the Java programming language. When the name of a class includes several words. a picture is supposed to be worth 1000 words. let‘s consider the UML representation of a Student class. This subsection is optional in the UML but is obviously necessary when you translate the diagrams into Java. One. the pieces of data which an object contains). we might have a DepartmentStore class. We will model these two types of people with Student and Professor classes. When we use words. a class is represented by a rectangle. We don‘t know its attributes. two. What standard am I using for the name of a class? Right. There are no Indonesian island jokes of which I am aware. in a different example. But we usually need to know more about the class. The second subsection of the rectangle contains the attributes (the names of the data items.The Student class Let‘s begin with the people in the room. Class diagrams We need to be able to describe these two classes. There are many coffee jokes associated with Java. All that we know about the class is its name.) In the UML. 17 . or three subsections. We identified two types of people in the room (not male and female!). this is an English word that makes programmers think ―class‖. Notice the word ―type‖. This subsection is optional in the UML but is obviously necessary when you want to translate the diagrams into Java. will be used for drawing diagrams. however. using some language. whose values we mentioned earlier. Thus. called the Unified Modelling Language (the UML). This represents a class. These are the behaviours we mentioned earlier. including JavaBeans and the coffee cup logo. We don‘t know its methods. student and professor. Thus. In this course we will use two languages. the class name is a singular noun and its first letter is capitalised. displaying one. each is capitalised. It can be represented simply as follows. (Note that Java is also an island in Indonesia and a synonym for coffee. and it contains the name of the class. The first subsection always appears. after all. The third subsection of the rectangle contains the names of the methods the class supports.

Is it a problem that BlueJ only offers simplified UML diagrams? It would be a problem were we developing a commercial product. which will be unique. Thus a Student object will have attributes named studentNumber and studentName. Every Student object has a name and a number. the attribute names consist of English words. but it doesn‘t seem to be a problem for our project. Their numbers may have been reused two or more times so information on two or more employees would be combined. Similar diagrams may be created with a BlueJ extension called PMD. If an attribute name contains several words. Java coding standards specify that attribute names do not begin with a capital letter. an object instantiated from the Student class. 18 . We have already mentioned that a student has a name and a student number. showing the attributes is Note that BlueJ apparently does not allow this form of the class symbol. then the second and subsequent words are capitalised. available at http://horstmann. In a previous career. everyone needs a number. Thus. Since names are not unique. The Registrar‘s Office at my college is responsible for ensuring that the student numbers are unique. Remember that a Student class is simply a blueprint. so they can be shown in the Student class diagram. As English is my native language.com/violet. These are two different attributes of every Student object.Consider the attributes of a Student object. her student number is never reused. describing what a Student object knows and can do. I worked for a company which reused employee numbers. as each of you do. the UML notation of the Student class. There is nothing to stop you from using words in your native language to create attribute names. no other student will have that number. That caused many problems when you looked at historical data for employees who were no longer with the company. Part of that responsibility is to ensure that once a student has graduated. These class diagrams are created by a free UML editor called Violet. we‘ll look at it later.

this datatype can represent it faithfully.Datatypes What type of data do we use to store the studentNumber and studentName? Everything stored in a computer is stored as patterns of 0s and 1s. a bit is the smallest unit of memory. You might suspect that the encoding came from the United States and you would be correct. some punctuation symbols. is not officially included. To do that. As we noted above. described at http://www. 010. plus a few other letters. These include a byte which contains 8 bits (256 values which. 01.‖ Binary means you only have two choices (usually 0 and 1) and digit refers to the individual parts of a number. an int which contains 32 bits (representing integers from -2147483648 to 2147483647). that word is not necessarily the best for the situation. four different values. byte and short 19 . then a byte can represent 256 different values. 100. That is apparently enough to represent all Earthly languages. All of these could be used to store studentNumber as long as we know they are large enough (contain enough digits). seven bits can represent 128 different values. this does not represent letters in many other alphabets. 10. 101. six bits can represent 64 different values. Similarly. the digits from 0 through 9. represent integers from -128 to 127). and 111. when interpreted as numbers. when interpreted as numbers. When you collect eight bits and treat them together. If you have three bits. If we can create the character. The encoding of these 256 values came from the American Standard Code for Information Interchange (ASCII). 011. 001. as one byte. Fortunately. If you have two bits. four bits can represent 16 different values. encoded using the Unicode standards. which are not objects. The word bit is an abbreviation for ―binary digit. five bits can represent 32 different bits. Just because we use a particular word to describe something. What about studentNumber? One of the problems of the English language is its ambiguity. Klingon. In general. you can represent 2n different values. when you have n bits.unicode. and a long which contains 64 bits (representing integers from -263 to 263 – 1). uses 16 bits to represent individual characters. Java does support many different types of numbers. we need to group the bits into a larger unit. The Unicode standard. However. Hence the emphasis on English. If you have one bit. and 11. called bits. and eight bits can represent 256 different values. Everything is stored as a collection of bits. an invented language used in the Star Trek television series and movies. you can represent 00. Java has a number of primitive datatypes. Having 256 possible values allows us to represent all the letters of the English alphabet. represent integers from -32768 to 32767). Java has a datatype named String which contains characters. a short which contains 16 bits (which. At first glance you would assume studentNumber is a number. you can represent 000. eight different values.org. 110. then you can represent only the values 0 and 1.

At least we know the studentNumber does not contain decimal points. since student numbers at Okanagan College contain nine digits. We‘ll explore that commonality later in this chapter. Thus a Student object has two attributes. We‘ll note for the moment that these two diagrams reflect a certain commonality. so we could just store it as a String as we did with the name of the student. both of which are of type String. Not only do we see the name of the class. Java also has datatypes called float and double. 20 . Now the more-complete UML Student representation is as follows. but is studentNumber really a number? A good guideline in deciding whether something called a number is a number or is something else is to ask the question ―Is it going to be used in mathematical calculations?‖ If so. to store numbers containing decimal points. since studentName is obviously a String.are not long enough. The Professor class What is the corresponding UML representation for the Professor class? Recall that a professor also has a number and a name. This discussion of numeric datatypes is interesting. Thus int and long contain enough digits. we see the names of the attributes and their datatypes. you should store it as some type of number. But a studentNumber will probably not be used in calculations.

That may seem to be a straight-forward task. but that is actually his family name. The part before the space will give us the given name. Perhaps we need to write a letter that begins ―Dear Jane‖. In this case. the last name at the end. or Dave.Tradeoffs of storing the name as one field versus several We discussed how to represent names and numbers-that-are-not-numbers earlier. a possible algorithm is ―start at the beginning of the string and look for the first space. and it‘s a well-known algorithm. Not all Alberts like to be called Albert. in a finite amount of time. The most important questions relate to how we will need the name. 21 . To get around the fact that breaking a name into its constituent parts is challenging (if not impossible). Will we always use the whole name? Will we sometimes use the parts of the name separately? I would argue that it is safest to assume we will sometimes need the whole name. Of course. we should consider what other name-related fields we should include. An algorithm is a series of instructions to solve a problem. Thus the algorithm will say that Yang Changji has a first name of Yang. using a finite amount of space. Cholmondley David Smith may prefer to be called David. A similar algorithm (having similar problems) may be used to find the last. the part after the space will give us the family name. and sometimes the parts of the name.‖ Does that algorithm really solve the problem? What about Manfred von Richthofen (whose family name is von Richthofen). but let‘s revisit that discussion and look a little more closely at how to represent a name most efficiently. we would need to split it up whenever we needed the parts. (Cholmondley is pronounced Chumly. or maybe the name will be represented as ―Doe. let‘s have a preferredName attribute. Not all people like to be called by their given name. Both first names and last names may be hyphenated.‖ This algorithm expects the string containing the name to have the first name at the beginning of the string. there is also the problem of hyphenated names.) I use some software that uses my full name when it says goodbye. Perhaps a ―preferred name‖ should be there. or family. If we store the name as one field. It appears we have a flaw in our logic. that‘s too formal for my taste. described below. they may prefer Al or Bert or Bertie. Does that algorithm really solve the problem? What about Billy Bob Thornton (whose given name is Billy Bob)? Our algorithm does not give the correct answer! Many Asian names don‘t satisfy the conditions of the algorithm. ―To identify the family name. Jane‖. just start at the end and work forward until we find the first blank. Since we are modifying our design. we should store the first and family names separately. So. name. Perhaps we need to create a transcript for ―Jane Doe‖. The family name is given first instead of last. using attributes firstName and familyName.

There may even be times when a person‘s middle name is required, so let‘s have a middleName attribute. If our program is to be useful in other cultures, we may wish to just use the attributes name1, name2, and name3 and let the user of the program decide what to enter in each. In addition, there will be times when a person‘s full name is required, so we‘ll store it as well, but only for use when the full name is necessary. I will, at least temporarily, use the word student as part of the attribute names for a Student, and professor as part of the attribute names for a Professor. Thus the UML diagrams for our Student and Professor classes look like this.

When we create instances of these classes (a Student object or a Professor object), these objects contain the parts of the name. When we have several different objects, students as an example, each object will contain a student number, unique to the objects. In each object, the student number will be contained in an attribute called studentNumber but, since the objects will each have separate identities, it is no problem that studentNumber occurs in each. Note that while we have used the term ―attribute‖, an equivalent term is instance variable. Each instance of the class (each object) has the same attributes, and the value of those attributes can change, or be variable. Hence the term ―instance variable‖ is a reasonable one. But how do we tell the object what those values are? How do we retrieve those values when we need them?

22

Behaviours
Recall that an object has identity (the name we give the object), state (the values it contains), and behaviours (the things it can do.) First of all, we note that ―things‖ is not a very precise word. I would like to define behaviours as ―the messages to which an object responds.‖ We will send a ―This is your given name attribute value. Remember it.‖ message to a Student object and then we can, at some later time, send a ―Please tell me your given name.‖ message to that object and it will return the value it remembered. In Java, methods receive the messages and respond appropriately. This idea of sending messages to an object is a powerful one, and we can extend it to sending messages to a class, in particular, a message like ―Create an object of your class, and here are the attribute values you need.‖ Most classes contain a method, called a constructor, which responds to this message. It will take all the attributes you supply, process them appropriately, and then return an object for the program to use. Similarly we will need messages to remember (or set) each of the individual attributes (one message per attribute.) These messages are called setters. The values we provide to be remembered are attached to the message through parameters. Another name for these methods is mutators. They change, or mutate, the value an attribute contains. We also need messages to retrieve the values of each of the individual attributes (one message per attribute). These messages are called getters. Another name for these methods is accessors. They access attributes. Constructors, getters, and setters are usually not shown in the third subsection of a class symbol, the area where methods are shown. Later on, we will see a special type of class, a JavaBean. For these classes, there is a constructor which takes no parameters, and a setter for every attribute. To make and populate such an object, first use the constructor to create an object whose attributes have some default values. Then use the setters to specify the values you want. For now, our constructors will take parameters. Once we have the ability to create an object, we should have the ability to display it, to be sure that it has been created correctly. Every object needs to be displayed, so the class needs a method, usually called toString. This method converts an object to a human-readable form suitable for display, perhaps through printing. We‘ll see the code (remember that code is computer-speak for anything written in a programming language.) for this method in the next section of this chapter.

A first look at Java
So now we have a diagram which describes what a Student class contains and what it does. Computers generally don‘t know how to interpret diagrams, so we must somehow translate this diagram into Java code.

23

Here‘s part of the code for the Student class. It‘s followed by an explanation of the individual statements.
/** * A Student * @author Rick * @version Summer 2008, 2009, 2010 */ public class Student { private String studentNumber; private String studentFirstName; private String studentMiddleName; private String studentLastName; private String studentPreferredName; private String studentFullName; /** * @param studentNumber 9-digit student * number assigned by the college * @param studentFirstName Student First Name * @param studentMiddleName Student Middle Name * @param studentLastName Student Last Name * @param studentPreferredName Student preferred * name or nickname * @param studentFullName Student legal name */ public Student(String studentNumber, String studentFirstName, String studentMiddleName, String studentLastName, String studentPreferredName, String studentFullName) { this.studentNumber = studentNumber; this.studentFirstName = studentFirstName; this.studentMiddleName = studentMiddleName; this.studentLastName = studentLastName; this.studentPreferredName = studentPreferredName; this.studentFullName = studentFullName; } //end constructor /** * @return student number */ public String getStudentNumber() { return studentNumber; } /** * @param student number */ public void setStudentNumber(String studentNumber) {

24

this.studentNumber = studentNumber; } } // end class

Let‘s examine this code in detail, starting with the documentation. Documentation The class begins with some documentation, comments you make to read at a later time, and comments which will be visible to anyone viewing the code for your class. These comments typically explain the purpose of the code and give some information about its contents. In a Java class, the documentation section begins with /** and ends with */. If you have done any programming before, you may be used to /* to begin a multi-line comment, and */ to end it. While that style still is acceptable, there is a utility program named javadoc which will process your Java program and identify the comments, as long as they are preceded by /** and followed by */ Once it has identified the documentation, it formats it into a readable, useful, form. Normally the first block of comments in a class will contain information about the class. It should include such information as the author (using the @author tag) and the date the class was originally written, along with a revision history (using the @version tag). Details on writing comments for the javadoc utility program are available at http://java.sun.com/j2se/javadoc/writingdoccomments/index . It is important that you follow these standards for writing comments since javadoc is accessible via BlueJ and you want your documentation to appear as professional as possible. Important points to note are the following. o Documentation for a class must appear immediately before the class header. Any import statements, which we will see later, must appear before the class documentation. o Documentation for a method must appear immediately before the method header. The description of the method is the first complete sentence in the documentation, determined by a punctuation symbol like a period. o Documentation for the parameters to the method, or the value returned, may extend over several lines, if necessary. You may be used to writing single-line comments that begin with //. As you can see above, anything on the same line after // becomes a comment. Programming Style – documentation Style is a way of expressing something, or the appearance of something. If you search the web using the three words programming style Java, you will find many sources that provide the way to write Java programs. Throughout this book we will include small sections describing

25

appropriate style issues and, more importantly, we will use generally-accepted good style. Since style is important, we will enforce good style by using a tool called Checkstyle. Documentation is made a little easier when we use BlueJ as it generates some skeleton documentation you for every class and method it creates. That is, it gives you the beginning of the documentation. It gives some ideas of what your documentation should say. As noted above, for every class, you should provide a description of the class (what it represents). You should also provide a ―revision history‖, who wrote the class and when, plus a description of the changes made by whom and when. Following the class documentation, we begin to see Java statements. Class declaration The class header says public class Student. This marks the first line of the class itself, giving the name of the class (Student), and an indication (the word public) that it can be used by methods outside the class. Of course it must be used by others; that‘s the whole point of having classes! Other people don‘t need to reinvent your work. Yes, there are private classes and we will use some ourselves, but they are relatively rare. The body of the class, including its instance variables and methods, are enclosed in a pair of braces, sometimes called ―curly brackets.‖ Whether you place the opening brace on the same line as the name of the class is the subject of discussion in some circles. It doesn‘t really matter. Programming Style – class names Class names are nouns, generally single (not plural) nouns. Thus we could have a class names Textbook; we would not have a class named Textbooks. Be careful with your class names; there are some words in English which are singular but end in the letter ―s‖. For example, Player, Team, and League are all acceptable class names. Statistics may be an acceptable class name, since the word statistics may be plural or singular, and statistic may not be a meaningful word, depending on the situation. Remember that class names always begin with a capital letter. If the class name contains several words, all are capitalised, for example DepartmentStore. Instance variables Looking back at the code, we have six statements allocating memory for the six data items (instance variables) that each object contains.
private String studentNumber; private String studentFirstName; private String studentMiddleName; private String studentLastName; private String studentPreferredName;

26

private String studentFullName;

Each of these lines is a separate Java statement. A Java statement ends with a semi-colon (;). A Java statement may extend over more than one line, but it must eventually end with a semicolon. Each student has a number and name(s). Note that all these instance variables are declared private. The only way the outside world may access these variables is via the getters and setters which we examine below. Remember that the name of an instance variable begins with a lowercase letter. If the name actually contains several words, the second and subsequent ones are usually capitalised. studentNumber is a good example of this. After identifying these instance variables as appropriate for a name, I read (in The Globe and Mail, a newspaper published in Toronto, Canada, on, 2006-08-16) about the inhabitants of Norfolk Island. Descendants of the Bounty mutineers, there are very few family names represented on the island. The phonebook for Norfolk Island includes nicknames for the inhabitants. Perhaps we should include a nickname attribute! Programming Style – instance variables All of these instance variables are of datatype String. That is they are instances of the String class; thus they are objects! The name you choose to give an object should be meaningful. That is, the name should convey some idea of the object‘s purpose or role. If so, then you do not need to provide documentation of what the object represents. For example, studentNumber really needs no further documentation (although you may provide it should you wish), while an instance variable named x does need further documentation. Constructor(s) Continuing our examination of the Java code, we see that the instance variables are followed by a constructor. We know it is a constructor not just because the documentation says so but because it has the same name as the class. This constructor is executed whenever we need to create a new Student object. A constructor uses the values we provide as parameters to initialize the instance variables for each object we create.

27

Within a constructor, my programming style is to use the name of the attribute as the name of the parameter. That leads to statements like
this.studentNumber = studentNumber;

which means, in English, take the value provided as a parameter (studentNumber) and save it (the equals sign) in another location. The reserved word this means ―the current object‖. Thus, this.studentNumber refers to the studentNumber attribute (or instance variable) within the current object; that is where the value in the parameter is saved. It is possible to have many constructors in a class, as long as they have different parameters, different that is in type or in number. You cannot have two constructors, both with two Strings as parameters. But you could have one constructor with two Strings, and another constructor with a String and an int as parameters. Perhaps all you know about a Student is the student number and name, but you don‘t have the preferredName; the student will provide that later. A second constructor could then be the following.
public Student(String studentNumber, String studentFirstName, String studentMiddleName, String studentLastName, String studentFullName) { this.studentNumber = studentNumber; this.studentFirstName = studentFirstName; this.studentMiddleName = studentMiddleName; this.studentLastName = studentLastName; this.studentFullName = studentFullName; this.studentPreferredName = “”; } //end constructor

Since we don‘t know the preferred name, we simply remember an empty String, signified by the consecutive double quotation marks, with no characters between them. Recall that we said earlier that a method is Java‘s way of handling messages. If you send a message, you must identify the receiver, and we will see how to do that later. You must also identify the message. Part of the message is its name but part is its parameters. If you ask a friend for dinner, that is a part of the message. The rest of the message involves the choice of the restaurant and the time at which you would like to meet. The name of the restaurant and the time are parameters, the variable parts of the message. When we send a message to create an object, we usually provide the values the instance variables are to assume. These values are the parameters. We have seen several assignment statements, the ones using the equals sign, which transfer the values of the parameters into the values of the instance variables, and we have had a simple explanation of how that statement works. But what does it really mean to say this.studentFullName = studentFullName;? Start with the names of the variables. When a computer stores data, it uses its memory. Each memory location is assigned a unique address. You could write programs that use those

28

addresses, but it is very difficult to keep the addresses straight in your mind, so today we use an association between names that we understand and the numbers of memory locations. The process of translating our program from Java into something the computer can understand directly (the addresses) is called compiling. The program we use to do this compiling is called a compiler. The Java compiler is called javac. Of course, the ―c‖ part of its name stands for ―compiling‖, and the ―java‖ part stands for, well, Java. When we write our program, we use names for the variables we wish to use. The compiler establishes a correspondence between the names we use and the numeric addresses the computer knows. An object requires a block of memory, a collection of memory locations. The block of locations is referred to using the address of the first location in the block. An object has an address, and so do each of its instance variables. So too do each of its methods. Thus, when we refer to the variable this.studentFirstName, we are referring to the variable studentFirstName within the current object. Java‘s shorthand for ―the current object‖ is this. Thus, this.studentFirstName refers to a specific area of memory within the memory the computer has allocated to the current object.
studentFirstName (without the this) is another, different, variable. It represents the name which we provide to the constructor. studentFirstName is a different area of memory from this.studentFirstName.

So now we have two areas of memory that are involved in this assignment statement, a statement which calculates a value and assigns it to a variable. Now consider the equals sign. In mathematics, an equals sign means that the values on the two sides of the equals sign are identical. In computing, an equals sign is an instruction to make a copy of the memory associated with the variable name on the right of the equals sign and copy it to the variable on the left hand side. After that copy is complete, the two areas of memory contain identical values. In fact this is not strictly true. If we were to look inside a String, we would find that it contains an address of memory. If you go to that address in memory, you will find the actual contents of the String. When we say
this.studentFullName = studentFullName;

we are actually saying that the address contained in this.studentFullName should become the same as the address contained in studentFullName. We will see this in the exercises to this chapter when we inspect the objects we create. Programming Style – constructors Giving the constructor and the class the same name is not just style, it‘s one of the rules of the language.

29

all correctly documented. it must be declared public (allowing the method to be called from outside the class). One way to learn how to program is to look at what others have done. studentNumber = inStudentNumber. /** * @return student number */ public String getStudentNumber() { return studentNumber. the instance variables. and see how they have done it. Depending on which style is chosen you see statements like this. and open-source projects. Continuing our examination of the class. Thus it is appropriate to say ―you may see. The body of the getter is very simple. In this example. we have one getter. We know that a method is a getter because its name begins with ―get‖. and the constructor.‖ Sources of programs to read are other textbooks. It is left as an exercise to the reader to provide the other getters.You do not need to follow my style of naming the parameters and instance variables identically. By using this style. or studentNumber = aStudentNumber. Getters and setters So far we have seen the class header. Having the parts of the class in this order is a very common standard. A third style which you may see is to precede each parameter with a specific letter or phrase. you may write _studentNumber = studentNumber. magazines. though not part of the language. but it is a very common style and other styles may confuse other programmers (including your professor) with whom you work. We need one getter for each instance variable. } Getters return a value to wherever the method was called. A different style which you may see is that instance variable names all begin with an underscore. and you should follow it. The Java statement to return a value from a method is simply the word return followed by the value. It must provide a datatype describing the value returned. we find the getters and setters. As such. 30 .

studentNumber = studentNumber. with its first letter capitalized. We need one setter for each instance variable. Setters do not return a value to wherever the method was called. all correctly documented. We‘ll see an example of this momentarily. Here it is. will have some documentation.‖ /** * @param student number */ public void setStudentNumber(String studentNumber) { this. The method name is toString. the name of a getter method always begins with the word get and the name of a setter method always begins with the word set. so it must specify a void datatype. Getters and setters. Given their names. a method which allows us to display the contents of an object. The end of the method name is the name of the attribute being manipulated.Finally. in this 31 .). like all methods. The parameter list. All the methods we write will have a visibility modifier (the ones we have seen are public and private). the datatype of the value to be returned (or void when nothing is being returned). } A setter must be declared public (allowing the method to be called). the parameter list (which may be empty. though. It is left as an exercise to the reader to provide the other setters. } Note the structure of this method and how it compares to the discussion above. /** * @return a Student. The datatype returned is a String. and the body of the method. toString Earlier we mentioned the toString method. the name of the method. We know that a method is a setter because its name begins with ―set. this documentation may be quite minimal. The visibility is public. we have one setter. as a String */ public String toString() { return ″Student number: ″ + studentNumber + ″ Student name: ″ + studentFullName + ″ (″ + studentPreferredName + ″)″ . Programming Style – getters and setters As noted above.

into a long String) several shorter Strings. If there is nothing between the quotation marks. Those four parts make up the method header. where we specify the value. is empty. this one being the value of the instance variable studentNumber. 32 . Once the complete String is available. This is followed by the method body. That is. the value of the instance variable studentPreferredName. Note that this Java statement illustrates the idea that a statement may extend over many lines in your editor. return ″Student number: ″ + studentNumber + ″ Student name: ″ + studentFullName + ″ (″ + studentPreferredName + ″)″ . or add to the beginning of an existing String. it is returned to the method which asked for it. two are descriptions of what the instance variable represents. the opening and closing double quotation marks for a string literal must be on the same line. The String which will be our result is getting longer. the plus sign is known as the concatenation operator. Three are the values of instance variables. The plus sign (+) indicates that what you have so far (a description) is to be followed by another String. The concatenation symbol is the plus sign. and then a closing brace. and a closing brace. We will do that in parentheses after the full name. Since it is returning a String. When used with Strings. and a closing parenthesis. opening brace. and some are just punctuation. ″Student number: ″ is a description. toString continues by adding an opening parenthesis. In this example.case. method body. The name toString is a name that has been adopted by many classes. Since we wish to be able to call this method from elsewhere. and we continue constructing the final result. Note its similarity to the structure of a class. its return type must be String. we combine seven Strings. but without the quotation marks. It describes the value the method will send back to the method which called this one. you have an empty string. as we saw earlier. it needs to be public. all of the work is done in the statement which begins return. That value is built by concatenating (putting together. enclosed in double quotation marks. However. Note that sometimes you prepend. One String followed by another one is still a String. followed by the class body. In this case. one after the other. which is followed by an opening brace. Thus. It is an example of a string literal. as we append (add to the end) items. Perhaps it would be nice to show the preferred name since it may not be obvious. a literal may not extend over more than one line. First appears the class header. containing whatever text you would like to display. It will appear as typed. Next we append another description ―Student name:‖ and the value of the instance variable studentFirstName. All methods have this structure: method header. then an opening brace. closing brace.

but we won‘t use it for now. What is the appropriate datatype for the telephone number of the college? Since we‘re not going to do any calculations with the ―number‖. there is no question about it being a String. of course. including the mailing address of the college. its phone number. Yes. In other cases. Creating another class. and the URL of its website. this time to model the college itself. As we progress through this book. In some cases. // build the String by concatenation return result. Thus we will be able to ask any object to display itself in a form we can read. a String is adequate here. there is only a return statement in this method. the College Now that you have seen how to create and test classes.Programming Style – toString All classes will have a toString method. If we wish the telephone number to be formatted with parentheses and hyphens. the only instance variables are the name of the college. the first attempt at creating a College class could be /** * * @author rick * @version november 2006 */ public class College { // name and contact information private String name. a list of the students it enrols. the people it employs. there is a URL class in the Java libraries. // start with an empty string String result = “”. we‘ll add other instance variables. and the courses it offers. What is the appropriate datatype for the name of the college? A String. What are the instance variables we need? For now. the method may look like this. let‘s create another one. Thus. private String phoneNumber. too. we‘ll model the college very simply. What is the appropriate datatype for the URL of the college‘s website? It too is a String. 33 .

} public String getHomePage() { return homePage. the process to create this code is as follows. String phoneNumber. its instance variables Identify its behaviours.name = name. String homePage) { this. } public void setPhoneNumber(String phoneNumber) { this. } public void setName(String name) { this. its methods Implement the constructor Implement the toString method Implement the getters and setters 34 . o o o o o o Identify the name of the class Identify its state.phoneNumber = phoneNumber.phoneNumber = phoneNumber.homePage = homePage. } public void setHomePage(String homePage) { this. } // name and contact information methods public String getName() { return name. } public String getPhoneNumber() { return phoneNumber. } } As mentioned above.homePage = homePage.name = name. } public String toString() { return name + '\n' + phoneNumber + '\n' + homePage.private String homePage. this. this. // constructor public College(String name.

and the toString method. We needed to talk about constructors. we will look at that feature when we need it. Now we need to see how to communicate our program to a computer. setters. we needed to speak about modelling and Java in this chapter. If we need some special feature of language to build that model.Summary That‘s it for your introduction to Java. Thus. getters. 35 . My approach to teaching programming is to discuss a model of something and then build the model.

setters. Furniture. Implement a Door class.Exercises 1. 36 . you will need to use int (or double) and boolean variables. As an additional complication. What modifications would we need to make in our College class to use the URL class? One simple class to model is a door. So is a digital camera. 4. and thickness. we have mentioned several other classes we could develop. a digital photograph. and toString. Complete the Professor class. Complete the setters for the Student class. 7. Choose one of those classes and identify the attributes it could contain. The URL for the documentation is given in the chapter. In this chapter. or an MP3 file. Complete the getters for the Student class. 2. Choose one of these classes. height. including getters. What datatypes are appropriate? Why did you choose those datatypes? Explore the online documentation for the URL class. Consider some other real-world classes which you may have seen. An automobile is suitable. 6. you may wish to model whether the hinge is on the left or the right. For a good solution. These included Room. It is either open or closed. What is its name? What are its attributes? What are its behaviours? 5. and Building. 3. A door has width.

you will be able to:       Start BlueJ Use BlueJ to create a class diagram Use BlueJ‘s editor to create and modify classes Use BlueJ‘s Object Inspector to examine objects Define unit tests Use BlueJ to create and run unit tests Introduction So now we have some source code. A program is designed to be executed by a computer. Testing is crucial to ensuring that your code works correctly. There are many tools which will allow us to communicate with the computer. We will use one called BlueJ. so we must have a way of communicating the program to the computer. The computer can not directly understand Java statements. and by indenting statements according to standards. Having it included in the environment is very important.  A tool for creating and testing classes. This IDE provides us with many tools:  An editor which understands the syntax (the grammar or the rules) of the Java language. the editor helps by colouring reserved words.  A link to a Java compiler. BlueJ BlueJ is an integrated development environment (IDE) which we will be using. You use the editor to type the statements in your program. By understanding the rules of the Java language. by showing you matching braces and parentheses.) 37 . A compiler is a program which translates Java statements into something the computer can understand. for a Student class. BlueJ draws class diagrams but none of the other diagrams which are included in the UML.Chapter 2 – Introducing BlueJ Learning objectives By the end of this chapter.  A simple UML diagramming tool.  A debugger (which we can use to fix hard-to-find errors. written in Java.

or o Right-click a blank area of the class diagram and choose New Class. Creating a new project Start BlueJ. ―Here. Tell the reader (someone who does not know anything about this project) all he/she needs to know. That is. you will need to install BlueJ and Java on your personal computer. press N (either uppercase or lowercase). To place a class on the class diagram. BlueJ allows a space in the name of the project. and places that file on it. Each project is stored in a separate folder on your computer. The project skeleton that BlueJ creates already contains one file. described in the next paragraph. choose Edit. and the first few lines of it tell you its purpose. BlueJ displays a class diagram. New Class. If your operating system allows a space in the name of a folder. press and hold down the key. Give the project a meaningful name. choose Project from the main menu. and release . so you may decide to double-click it to see what it contains. release N. If you wish to do some work in Java elsewhere. If you are doing your programming at a college or a university. you have several choices. and New Project from the drop-down menu. That task is included as an exercise at the end of this chapter. The title on the window containing the class diagram is the name BlueJ followed by a colon and the name of your project. You choose the precise location when you create the project. or o From the column of buttons to the left of the class diagram. or o Press +N.‖ Then it identifies some headings under which you can insert information for the reader. 38 .An integrated development environment provides access to all these tools through one common interface. you can continue to create a new project. The icon for the file looks like a piece of paper. Once BlueJ and Java are installed. This is the beginning of the documentation you will be creating. choose New Class. o From the main menu. the New Class dialogue appears. The file is a project ―readme‖ file. you should describe your project. BlueJ will probably have been installed on the computers you will be using. Whichever you choose.

in this case Student. it‘s good to know which have been compiled and which have not. The class displays diagonal lines as a visual reminder that it has not been compiled. But later on. and are making changes to several of them. Note that Java requires that class names contain no spaces. is to capitalize each word of the class name which contains more than one word. You could use underscores to separate individual words in a class name. Since it hasn‘t been compiled.Type the name of the class. when you have many classes. but the standard. Right now. as we have seen. we can‘t use any of its features.) BlueJ updates its class diagram. that‘s fine since we don‘t know how to compile it. and click Ok (or press . 39 .

On the Editor tab. Look at what you have typed. or unexpected colours. After you have entered the declarations for the instance variables. The double quotation mark in programming is ″ and the same mark is used at the beginning and end of all strings. Click the Compile button to both save and compile the class. so you‘ll see more errors after you fix one than you had before. It can display different aspects of the language in different colours. choose Tools from the main menu. click the question mark in the lower-right corner of the BlueJ window. possibly checking ―Make backup of source files‖ also. fix them. If you don‘t see the error. Obvious errors will make themselves obvious by unexpected indenting. the documentation and Java statements it contains. and search-and-replace. an opening parenthesis is (. Enter the Java code for the Student class which we seen above. If you have forgotten your punctuation symbols. we‘ll need them later. right. Are there any obvious errors? If so. the compiler will find them and BlueJ will highlight (in yellow) the line containing the first one. Sometimes one error will cause many others. In typesetting there are two double quotation marks. Remember that the editor allows you to cut-and-paste. so don‘t worry about fixing every error at the same time. A closing parenthesis is ). and the constructor. some documentation. you‘ll soon reduce the number of errors to zero. These are particularly useful when entering similar methods. If you have made any errors. There are a number of advantages to using an IDE. When you type an opening double quotation mark. Sometimes one error will hide another. I leave mine that way.To see the contents of a class. Don‘t forget getters and setters for each instance variable you created. An opening brace is { and a closing brace is }. When you have no more errors. the IDE will momentarily highlight the matching opening one. Keep what you need. uncheck the appropriate combo boxes. then Preferences from the drop-down menu. continue entering the other getters and setters. stop. delete the rest. fix it and compile again. Since the IDE knows the language you are using it can make intelligent decisions about indenting. the declaration of an instance variable and a method.click the class and choose Open Editor (or double-click the class. and BlueJ will offer some hints about what the error may be. Save (or press +S) to save your work. If you wish to suppress these helpful features (why would you want to?). an opening one ― and a closing one ‖. But never fear. If you see the error immediately. Don‘t delete the first few blank lines. 40 . When you first run BlueJ.) BlueJ provides you with a skeleton of a class. When you type a closing parenthesis or brace. the screen will show red characters until you type the closing double quotation mark. IDEs can also match parentheses and braces. you will find that most of the combo boxes are checked. Click Class.

or Project. When you are finished typing. sometimes I do the reverse. It depends on the style you (and your teacher) prefer. Assuming you haven‘t left (or you have returned and opened the project again. Open Project. This saves your work but does not compile it.Enter the toString method as well. one in the window where you have entered the class. A main principle behind Java is that you can write a program on one type of machine and have it run on others. choose Class. I usually list the toString method after the getters and setters. Note that there are two Compile buttons. and one in the main BlueJ window. and save all the classes you have open. Nor does the order in which you list the methods. without change. And sometimes I list a getter followed by its setter.java file) into the instruction set of the virtual machine (stored in a . 41 . I list the constructors. Now all your work has been saved should you need to leave. Save from the menu in the window containing your class. This normally makes it difficult to run a program on one type of CPU when it was designed for another.class file). Open Recent). Save from the menu in the main BlueJ window. you translate from the Java statements themselves (stored in a . or vice versa. The order in which you list the declarations of the instance variables does not matter. These instruction sets are very complicated and depend on the design of the CPU your computer is using. Virtual machines and bytecode Every type of computer uses its own instruction set for the commands it executes. click the Compile button again. Later on we will have many classes open at the same time. Following the instance variables. This Java virtual machine is just a program which pretends to be a computer running its own language. This miracle works because there is a virtual machine involved. It doesn‘t matter which one you click. using Project. Sometimes I list all the getters and then all the setters. Then I list the getters and setters. When you compile a Java class. It translates the instructions output by the Java compiler (known as bytecode) into the appropriate instruction set of the host computer. Then it may be more efficient to choose Project.

First. you can develop Java programs using a Macintosh computer. Testing the Student class Recall that the methods in the Student class (and the class itself) needed to be declared public so that some other methods can use them. and toString. In the old days that was quite a thrill. Compile. student1 is acceptable for now. you can do that too. simply click the name of the constructor. Remove.wikipedia. plus Open Editor. and run it on a PC running Windows. you need to specify the name of the object. in the background. For now. We will explore those options later. Well. Yes. Now. simply right-click the Student class in the class diagram. The reference to ―lifting the curtain‖ comes from the movie The Wizard of Oz. however. cannot be used until we have created an object.org/wiki/Clarke's_three_laws) I use magic in that sense. you run the constructor. an object. however it‘s not such a big deal. By clicking the name of the constructor. as an example. The noted science fiction author Arthur C. For now. 42 . Then you need to specify the parameters the constructor expects. Later we will lift the curtain and see what is in the background. BlueJ takes care of the details by magic.‖ (http://en. Clarke said that ―Any sufficiently advanced technology is indistinguishable from magic. separated by a line. The getters and setters. The benefit of using a tool like BlueJ is that we don‘t need to create any of these other methods right now. and. Both are done through the window shown below. A menu appears showing the public methods of the class. Recall that a constructor allows you to create an instance of the class. it‘s not really magic. but you can change it if you wish. Inspect. The big deal is to develop on a Macintosh and then run on an IBM mainframe using the Linux operating system.Due to this virtual machine. Create Test Class. It is highlighted because it is the only method which you can call now.

We can see this.Remember that all the values being passed to the constructor are Strings. it appears in the object tray at the bottom of the BlueJ window. Inspecting an object Recall that in the previous chapter we talked about the meaning of the equals sign. Remember that you can use an empty string (―‖) to represent a value you do not know or do not wish to provide. you may use an empty string for any or all of the parameters. See how the result changes depending on whether or not there is a preferred name. Choose Inspect from the menu which appears. Click Ok when you have specified all the parameters. at least one of which does not have a preferred name. It shows the values you specified for the parameters. right-click it in the object tray and execute one of its methods. so should be enclosed in double quotation marks. At the moment. Create a couple more students. Do they produce the correct answer? If not. Be sure to execute the toString method for the Student objects you created. Once BlueJ has created an object. Were you like me and you specified you own name? Or were you more creative? 43 . now that we have objects on the object tray. Try some experiments with them. fix them so they do produce the correct answer. To experiment with an object. The Object Inspector window appears. Note that the documentation you placed at the beginning of the method appears in this dialogue. Right-click an object. to guide you in providing parameter values. Try executing some of the getters and setters you wrote. and how one string contains the address of another.

I‘ll assume we left studentNumber highlighted.Highlight any of the six instance variables by clicking them. In a similar way. The other contains the actual characters. at how Java represents a String. We see that the String actually has two instance variables of its own. or the address of. The first (length) is the number of characters in the String. we can see how the studentFullName is stored. the Inspect button is disabled. I entered six characters. This is a reference to. The line reading private char[] value shows an arrow. That area actually contains the contents of the String. and then click Inspect. 44 . another area of memory. For the next two illustrations. Now that we are as deep into a String as we can go. showing the characters which make up the student number. I was lazy and repeated the same digit over and over. If you click Inspect in this dialog. Now we are looking under the hood. you will see the image below.

so a scrollbar allows you to see the rest of the information. 45 . Click Close as many times as necessary to close the Object Inspector. there is too much information to show in a window of the default size.In this case.

46 . described in more detail at www. When you change the order by which you sort some data. 20.Unit testing . 5. Ad hoc testing would be very difficult. If zero is correct data. and 20 are correct data. you‘ll probably break code.junit. 10 and 17 are examples of correct data. you‘ll need to know that the getters are correct. I guarantee you will break some other code.‖ The word ―regression‖ refers to the need to redo previously-passed tests and ensure that the code still passes them. while 5. Ideally. Suppose you made a major change and want to make sure that you have not broken any other code. what happens when you provide 100 or -43 as input? o That getters return the correct value. and 6 at the lower end. and 21 at the upper end.org/wiki/Unit_testing) tells us that ―a unit test is a procedure used to validate that a particular module of source code is working properly. Correct data means data which is reasonable to expect. Normally we wish to test all the parts (the units) of the system. BlueJ provides access to a tool named JUnit which facilitates this testing. Wikipedia (http://en. o That toString returns the correct value. When you change a datatype from one type to another. Using the previous example. To test setters. 19. Using the previous example. Breaking code refers to having previously-working code stop working due to some change you have made. o That each method behaves correctly when you provide wildly incorrect data. data that is on the boundary between correct and incorrect data include 4. Note that 4 and 21 are incorrect data. If the method expects integer input with values between 5 and 20. … This type of testing is mostly done by the developers and not by end-users. a better way to test is to do systematic unit testing. After a change. each test case is separate from the others. make sure you test it.org. o That each method behaves properly when you provide input that is on the boundary between correct and incorrect. JUnit is a testing framework. create and save a series of unit tests so that we can use them over and over again as necessary. To do this. o That setters change the correct instance variable to the correct value. it can be quickly identified and fixed. 6. The procedure is to write test cases for all functions and methods so that whenever a change causes a regression. you will perform regression testing. this involves testing components individually.definition The testing we just did to see that the object was created correctly is a form of ad hoc testing. with whatever data came to mind. and 19.wikipedia. What things should you test through unit testing? o That each method behaves properly when you provide ―correct‖ data. and we may need to test some many times.

‖ Then click Ok to dismiss the Preferences dialog and right-click the Student class again.Unit testing with BlueJ Let‘s create a series of unit tests for the class Student. The test class for Student is thus named StudentTest. Right-click Student in the class diagram and choose Create Test Class. 47 . Choose Create Test Class. If ―Create Test Class‖ does not appear. Miscellaneous. Preferences. use the main BlueJ menu and choose Tools. BlueJ names test classes by taking the name of the class being tested and appending the word Test. and click ―Show unit testing tools.

much as English uses the double quotation marks. and s3 if you need several objects! As a general 48 . enter private Student s. when that happens. or we can create then once and then use them in all the tests. adding author and version information. To do the test. s2. enclosed in guillemets. Open StudentTest in the editor. we need some objects. before the default constructor and its comments. And so are s1. In the unit test class. One possibility is to create the objects anew in each test. declare the objects you‘ll be using. My unit test was drawn too close to the top of the window.. My preference is the latter. I know that I previously insisted on meaningful variable names. StudentTest will follow along.This may not look exactly like what you see. These symbols are used in some languages. In this context s is a meaningful variable name. Yes. click on the Student class and drag it down a little. These symbols have been adopted in the UML. You can‘t do the same thing by dragging the test class. These objects will exist during all of the tests. These declarations are of the form private datatype variableName. Note that BlueJ continues its practice of colour-coding parts of the diagram. to mark the beginning and end of speech. Unit tests are green. In our case. including French. Document it properly. A class is clearly shown as a unit test by the words unit test.

o Has a name that consists of the word test followed by the name of the method being tested. Each test is similar. In the tearDown method. In the setUp method. but it doesn‘t have an area of memory associated with it. but you will see that it works. the outcome of one does not affect the outcome of another. Generally. to distinguish between objects. The variable was declared. If I need several tests for the same method. We would not know for sure its state (the values of the instance variables) before a test and so we would not be able to forecast the results of the test beforehand. we could change the state of the object. we describe any processing which must take place after each test. which must take place before each test. we need to write nothing in the constructor. o Returns nothing (or void). when necessary. s. we need to write nothing in tearDown. In this test. the tests are independent of each other. Generally. I capitalize the first letter of the method being tested.rule. s = new Student(″123456789″. and then did the unit tests in varying orders. Every test: o Has public visibility. Then create the tests you wish to perform. ″Richard D. This sounds an unusual way to do things. we are guaranteed to know the state of the object before each test. once for a student with a preferred name and once for a student without a preferred name. ″Dennis″. deciding if it is correct. ″Richard″. o Carries out some processing and produces a result. We will determine what the result of the method should be before testing it. but that is not necessary. Gee″). ″Gee″. Here‘s a sample test for the getStudentNumber method.getStudentNumber()). This unit test class skeleton contains three methods. o Uses an assert statement to check that the result matches the expected result. ″Rick″. By doing the initialization in the setUp method. We will not run a test and then look at the result. in unit tests. so it has no value. Note the use of the word ―beforehand‖ in the middle of the previous paragraph. I place a sequence number at the end of the method name. public void testGetStudentNumber() { assertEquals(″123456789″. 49 . Thus. If we initialized the object when we declared it. generally initialization. That is. and place the result we expect in the test. for example. we describe any processing. By initializing the objects in the setUp method. I will generate variable names by taking the first letter of the class being tested along with. we will need testToString1 and testToString2 since we need to test that method twice. we need to create a Student object. Here we give it a value. a digit.

/** * The test class StudentTest * * @author rick gee * @version 2006 04 20 */ public class StudentTest extends junit. so we need to test the getter first. When there is confusion between the name of an instance variable and a parameter. you may find it fails if you made a typing mistake which nevertheless was correct Java. the parameter and the instance variable have different names. // confirm that the change took place assertEquals(″678678678″. and then the actual value coming second) to check that the student number returned is the expected value.studentNumber = studentNumber. We use the actual name of the object followed by a period and the method we wish to use.framework. public void setStudentNumber(String stuNumber) { this. Since the attributes have private visibility. If there is no confusion. To modify them from outside the object we use a setter. this may be omitted.In this test. } While this test seems overly simple. we use the getStudentNumber method on an object whose student number we know. Once we are sure that the getStudentNumber method is working correctly. public void testSetStudentNumber() { // change the student number s. The test for the setter involves the getter as well. Both this. assertEquals is a method provided as part of JUnit. we can only access them from inside the object.studentNumber and studentNumber refer to the instance variable. /** 50 .setStudentNumber(″678678678″). Here is the complete unit test for the studentNumber getter and setter. s. Then we use the assertEquals method (with the expected value coming first. } This will compile but will not give the correct result since the value of the parameter is never saved. To retrieve them from outside the object we use a getter. In the method shown. Consider the following method. the instance variable must be prefixed with this.getStudentNumber()). we can test that the setStudentNumber method also works correctly. so there is no confusion.TestCase { private Student s.

* Default constructor for test class StudentTest */ public StudentTest() { } /** * Sets up the test fixture. the one we use takes two parameters. the second is a String containing the actual value.setStudentNumber(″678678678″). so we test that the correct value is returned. Technically this is perhaps better 51 . we know the student number we used to create the student. ″Dennis″. s. Of course. and the test will fail. * * Called after every test case method. */ protected void setUp() { s = new Student(″123456789″. ″Richard″. the second is what the program gives us. the first parameter is the answer we expect. JUnit will indicate that very clearly. } /** * Tears down the test fixture.getStudentNumber()). so we test that the value returned by getStudentNumber is the expected value. the assertion will fail. we use the assertEquals method. ″Rick″. */ protected void tearDown() { } public void testGetStudentNumber() { assertEquals(″123456789″. ″Gee″. } public void testSetStudentNumber() { // change the student number s. In testGetStudentNumber. We know what the expected value is. The first is a String containing the expected value. } } As part of each test. they should be the same. In testSetStudentNumber. This method comes in many forms. If they are not the same. we change the student number and then retrieve it. That is.getStudentNumber()). ″Richard D. // confirm that the change took place assertEquals(″678678678″. * * Called before every test case method. Gee″). s. returned from a method.

called an ―integration test‖ since we are combining different methods and seeing that they work together. When we use JUnit in more advanced situations, we‘ll see some other assert methods. These include assertNull, assertNotNull, assertTrue, and assertSame. For details on all the assert methods, look at the documentation at http://www.junit.org and follow the link to javadoc. Notice that when you compile a class, the corresponding unit test class (if it exists) is also compiled. Unit testing – the results
StudentTest is on the class diagram, so we can right-click its symbol. The resulting menu offers

the possibility of running all the tests, or just one. When you choose to run all of the tests (usually a good idea), a window (shown below) appears showing the results of all the tests, one per line. (Of course a scroll bar appears in the upper portion of the window when there are many tests.) A successful test is shown with a green tick beside it. An unsuccessful test, one that failed for some reason, is shown with a black X beside it, if there is an error message available, or a red X is there is no error message available. For a failed test marked with a black X, you may click the message in the upper pane and abbreviations of the expected and actual values are shown in the lower pane. Note that a test may fail because the test was created incorrectly or because the method it is testing is incorrect. For example, in my test for setLastName, I changed the value of the lastName instance variable but retrieved the firstName instance variable in the assertEquals call of my test. I was sloppy when I cut-and-pasted. Of course the assert method failed. You want to see a green line across the middle of the test window; this tells you that all of the tests were successful. When any tests fail, the line is red.

52

Below the line, is the number of tests run, and the number of errors detected or tests that failed. We wish to test each method in the Student class. There are six getters, one for the student number and five for the parts of the name, and six setters. Thus we need to create 12 unit tests and ensure each test works successfully. Cut and paste, and be careful as you make changes! To test the toString method, we need thirteenth and fourteenth tests, one applied to a student with a preferred name, one applied to a student without. As noted above, these could be called testToString1 and testToString2. If you prefer, you could use the names testToStringWithPreferredName and testToStringWithoutPreferredName. Testing toString is a little challenging, since you need to remember all the literals which are added to the instance variables. Thus you need to implement 14 tests to ensure your class behaves correctly in all cases. Make it so.

Smoke testing
These simple unit tests are exhaustive. That is, they test everything an object can do. An alternative type of testing is ―smoke testing‖. A simple definition of smoke testing is ―Smoke testing is non-exhaustive software testing, ascertaining that the most crucial functions of a

53

program work, but not bothering with finer details. The term comes to software testing from a similarly basic type of hardware testing, in which the device passed the test if it didn't catch fire the first time it was turned on. A daily build and smoke test is among industry best practices advocated by the IEEE (Institute of Electrical and Electronics Engineers).‖, provided by http://searchvb.techtarget.com/sDefinition/0,,sid8_gci930076,00.html JUnit allows us to create many tests, and run only selected ones. When we run only a few of the tests, we are doing smoke testing.

The Professor class
In a similar manner, we must create the Professor class and unit tests for all the methods in the Professor class. Make it so.

The College class
In a similar manner, we must create the College class and unit tests for all the methods in the College class. You created the College class earlier. Ensure that all methods are tested and pass the tests.

Summary
That‘s it for your introduction to BlueJ. As I stated earlier, my approach to teaching programming is to model something and then implement the model. BlueJ and unit testing are crucial to building the model. An untested model is a useless model. No architect would build a structure without creating a model first. Of course the model may show flaws. That‘s better than building the structure and then finding its flaws. A Wikipedia article on the Tacoma Narrows Bridge shows what can happen when your model has flaws which you do not catch. http://en.wikipedia.org/wiki/Tacoma_Narrows_Bridge#Film_of_collapse Did you see how strange the output of toString looked when a student did not have a preferred name? We need to fix that. Thus, the next feature we need is some way of taking one of two branches, depending on some condition. This will also allow us to deal with some of the unit tests mentioned, checking if a value satisfies some conditions.

54

Exercises
1. Develop unit tests for all the methods in the Student class. Ensure that your code passes all the tests. My style is to develop the tests for the getters first, since they do not depend on the setters. The values of the instance variables are all set by the constructor. Test the toString method. It also does not require any setters. 2. Develop unit test for all the setters in the Student class. Ensure that your code passes all the tests. Note that the unit tests for the setters will require the getters. Thus you create the getters first, test them, and fix any errors they contain before you begin to write the setters. Create the Professor class. As you do so, develop unit tests for all the methods in the Professor class. Download (from bluej.org) and install BlueJ on your laptop or other home computer. Download (from java.sun.com) and install the Java SE Development Kit. Download (also from java.sun.com) and install the Java class documentation so that you do not need to be connected to the Internet while using BlueJ, unless you want to be, of course. Use Tools, Preferences from the main menu, and then the Miscellaneous tab to tell BlueJ where the documentation is installed locally. Use BlueJ to create a Student object on the workbench. Inspect it and see how the attributes are stored. In particular, what is stored when you provide an empty String for a parameter? When you write a book or make a presentation, you want everything to look as good as it can. One way to do this is to associate a Font object to each piece of text. http://en.wikipedia.org/wiki/Typeface gives an interesting background on type and its terminology. Read it. A Font class will need to provide the typeface, the point size, and an indication of whether the font is to use bold, or italic, or superscript, or subscript. Implement the Font class. To do this properly you may need to use int and boolean datatypes (what are they?) in addition to the String datatype. 7. One of the standard examples of a class is a bank account. Without downloading a BankAccount class from the Internet (yes, there are lots of them there!), design and implement a simplified BankAccount class. A bank account should know about its number, owner, balance, and the service charge per transaction. Test all the methods. The account should contain methods to make a deposit and to make a withdrawal. It is a

3.

4.

5.

6.

55

simplified bank account since it does not yet contain a record of all the transactions, so deposits and withdrawals affect the account balance only. In subsequent chapters, we will implement the record of transactions.

8.

A playing card is another example of a class. Different cultures have different playing cards. One type of card, a card used in the USA or United Kingdom, and countries in the Commonwealth, knows about its suit (hearts, diamonds, spades, and clubs) and its value within the suit. Images for the suits are available in Unicode. A playing card also knows how to draw itself.

Leaving the drawing for much later, create an AngloAmericanPlayingCard class, along with its associated getters and successors. Test all its methods. As an alternative, create a playing card class from your culture. In subsequent chapters, we will use this class to play card games. Where did the four suits arise? A possible answer is available at http://www.straightdope.com/columns/read/276/whats-the-origin-of-the-suit-designationson-playing-cards .

9.

―Die‖ is the singular form of the word ―dice.‖ Dice are used in many games. Model a die. What does a die know? It knows how many faces it has. Don‘t jump to the conclusion that a die always has six faces. There are five convex regular polyhedra (the Platonic solids) which can be use as dice. These regular polyhedra have all their faces identical; that‘s the ―regular‖ part of their name. The tetrahedron has four triangular faces. The cube has six square faces. The octahedron has eight triangular faces. The dodecahedron has 12 pentagonal faces. The icosahedron has 20 triangular faces. A die also knows how to determine the value that appears when it is thrown. To implement that we need to know a little about random numbers, something we will see later. For now, implement a Die class, having only a constructor and a toString method. In subsequent chapters, we will use this class to play a board game.

56

10.

Dominoes have a relationship to dice, as described at http://en.wikipedia.org/wiki/Domino. Design and implement a Domino class. Birders are people who watch birds and record the details of their watching. Every bird species has a common name (American Robin, as an example) and a scientific name (Turdus migratorius, for example). Design and implement a Bird class. Include all appropriate unit tests. We will explore the world of birding in the exercises of subsequent chapters. Consider the websites http://www.natureinstruct.org/dendroica/ and http://birding.bc.ca/ if you are interested in Canadian birds.

11.

57

58

Chapter 3 – Making decisions
Learning objectives
By the end of this chapter, you will be able to:  Describe situations when your program may need to make decisions  Use boolean variables  Write if statements  Use the online Java documentation to find out about classes

The if statement
As we noted at the end of the previous chapter, the output of the toString method may appear rather strange when you output someone without a preferred name, displaying () at the end of the name, instead of (Rick), for example. How do you suppress the printing of the parentheses when there is no preferred name to display? There are several ways to do so, all involving checking conditions. First, let‘s look at what we mean by conditions. Boolean algebra A statement like ―Today is Tuesday.‖ is either true or it is false. A statement like ―It is raining.‖ is either true or it is false. (Yes, there are statements like ―This statement is false.‖ which are neither true nor false. We will not deal with them here.) When we are dealing with conditions, we are dealing with statements or expressions which are either true or false. True and false are called Boolean values. The Java datatype containing Boolean values is, not surprisingly, boolean. ―Boolean‖ is a tribute to George Boole, a British logician (1815-64) whose life and work are described at http://www-history.mcs.st-andrews.ac.uk/Mathematicians/Boole. There is an algebra associated with these Boolean values, describing the rules under which they may be combined. You have seen one algebra already in your mathematics classes in elementary school, when you studied integers and the addition, subtraction, and multiplication operations. If you add two integers, you get an integer. If you subtract two integers, you get an integer. If you multiply two integers, you get an integer.

59

you need two Boolean values when you use the and operation. Not true is false. o A program may need to do different processing when a specified number of pieces of data have been processed. Two false conditions combined using or produce a false. any other combination of two Boolean conditions combined using and produces a false. since there are many cases where you divide one integer by another but the result is not an integer. or. negative. as do a true and a false (in either order) combined with or. and not false is true. Two true conditions combined using or make a true. That is. Boolean algebra is based on three operations (and.Division is a problem. Think of printing text on a page. o A program may need to do different processing if a string is empty or if it contains characters. You may need to place footer on a page once a specific number of lines of data have been displayed. but only one with not. Not True False False True And True False True True False False False False Or True False True True True False True False What relevance does George Boole have to programming? To have computer programs do anything interesting. they need to be able to examine the data they are processing and make decisions about what to do next. two with the or. the third is unary. Two true conditions combined using and make a true. The first two operations are binary. 60 . or zero. These statements are usually summarized in the following tables. Think of a missing preferred name. and not) and the values true and false. o A program may need to do different processing when a number is positive.

The same way that two Boolean values anded together produce a true result only if both are themselves true. Boolean algebra – an example For example. and doing different processing depending on the value of the condition. depending on the result of the conditions being true or false. o A program may need to do some special processing when there is no more data to be processed. This is an attempt to save energy on the assumption that it‘s light outside longer so people don‘t need to turn on their indoor lights. Most programming languages have an if statement which allows for these decisions. 61 . and the time is 0200 or later. you have one or more conditions. whose results are either true or false. for a net increase in energy usage. The result of this combination is either true or false. This example contains four conditions. If it is true. and remember that we have done so. In an if statement. We just switched to Daylight Savings Time. combined using the three Boolean operations. and we have not already switched to Daylight Savings Time They are combined using the and operation. if false. Early indications were that people didn‘t go home but drove around. and this is the first Sunday in April. Most computers did this automatically by the following logic. so that Daylight Savings Time now begins three weeks earlier. a different series will be executed. and the time is 0200 or later. then several Boolean values anded together produce a true result only if all are true. Note that much of North America changed the rules in 2007. and we have not already switched to Daylight Savings Time. and this is the first Sunday in April. All of these situations require evaluating conditions. If today is Sunday. o A program may need to do some special processing when a data file is missing. this paragraph is being written in early-April 2006.     Today is Sunday.o A program may need to do different processing depending on a number being even or odd. do so now by adding an hour to the time. thus saving some electricity but using more gasoline. one series of statements will be executed. An if statement is a programmer‘s way of writing conditions and executing one of two different scenarios.

which we represented as ″″. choose Help from the main menu. (In the main BlueJ window. then Java Class Libraries. the result of the comparison is true and otherwise it is false. Assuming you are using the online version of the Java documentation. and preferred name. Missing data is a problem. or at an edited version of the output of javadoc (when using the dead-tree form of documentation. one which checks the relation between its two operands. When that number is zero. How do we know that such a string is empty? Its length is 0. the number of characters between the quotation marks. you are looking at the output of javadoc (when online). there is no preferred name. The relational operators are what we use to create simple conditions. return the number. Using the Java documentation The Java language is well-documented. You 62 . The pair of adjacent equal signs is shorthand for ―Check the values on each side and see whether or not they are identical. When creating an object in BlueJ. The frame in the top left corner contains a list of all the Java libraries. Otherwise (as described in a clause beginning else). of course. Thus. It involves only one condition. We combine simple conditions with the Boolean operators to produce more complicated conditions. with three frames visible.) I prefer the online version. as it is always up-to-date. else return ″Student number: ″ + studentNumber + ″ Student name: ″ + studentFullName + ″ (″ + studentPreferredName + ″)″ . Should they be identical.‖ The double equal sign is an example of a relational operator. public String toString() { if (studentPreferredName. We determine its length by using a method of the String class.length() == 0) return ″Student number: ″ + studentNumber + ″Student name: ″ + studentFullName. and results in an error message. your browser opens. How did we find that there was such a method? By looking in the Java documentation for the String class. } The logic used in this method is: Check the number of characters in the preferred name.A revised toString method Here is a possible revision to toString. we had to provide a null string. with the latter enclosed in parentheses. you have found that the constructor requires values for all its parameters. in some textbooks and online. so simply return the number and full name.) When you look at details on the String class. full name.

find the length method. by scrolling down the list until you see java. The bottom frame would then show all the topics available from the java. Or you could use the frame in the bottom left corner. To check if the length of a string in Java is zero. If the condition is false (meaning there is a preferred name). The large frame on the right of the screen now displays the javadoc output for the String class. we write if (studentPreferredName. The statement or statements describing the action(s) to take if the result is true begin(s) immediately after we test the condition. In either case. We use this method to determine how many characters are in the string. studentPreferredName. ― ‖ is different from ―‖. When a string contains many characters but only blanks. simply return the value ″Student number: ″ + studentNumber + ″Student name: ″ + studentFullName. Scroll through it to find descriptions of all the methods this class supports. This is the same way we used the name of a variable followed by a period followed by the name of a getter or a setter. or it is not empty and its length is greater than zero). The statement or statements describing the action(s) to take if the result is false begins after the word else. and scroll down until you see String.) A value of 0 tells us we are dealing with an empty string. Thus. we use the name of the variable followed by a period and the name of the method. public String toString() { 63 . The first contains two blanks. In particular. it will have a non-zero length.length() == 0) Recall that the pair of equals signs is shorthand for ―check the values on each side and see if they are identical. return the value ″Student number: ″ + studentNumber + ″ Student name: ″ + studentFullName + ″ (″ + studentPreferredName + ″)″. by looking at the value it returns. the if statement allows us to distinguish between the two cases. once you have found the String class. (Why is that section of the documentation not in alphabetical order? I have no idea. click it.‖ Since there are only two possibilities (the string is empty. Thus.lang library. If the condition is true (meaning there is no preferred name). a value greater than 0 tells us there are characters in the string.could start there (if you know the name of the library which contains your target). Scroll down that list until you find String. To determine the length of a string in Java. an int.lang and then clicking it. Warning: there are many classes listed in this frame. This is probably the best solution until you know which classes are in which libraries. Further details on the method are in the Method Details. and thus its length is zero. Look in the section of the documentation entitled Method Summary. the second contains none.length() is the number of characters in studentPreferredName.

or you may use one if statement within another.length() == 0) return ″Student number: ″ + studentNumber + ″Student name: ″ + studentFullName. it may not produce the correct results. but having them there may save some problems later. In that case. if (studentPreferredName. } return result. result = result + studentFullName } else { result = “Student number: “ + studentNumber. Some authors suggest you should always use braces when working with if statements. Note that not is represented by the exclamation point. even if there is only one statement. else return ″Student number: ″ + studentNumber + ″ Student name: ″ + studentFullName + ″ (″ + studentPreferredName + ″)″ . Programming style – if statements if statements are usually much more complicated than the one we have seen. This alternative toString method illustrates this use of braces. result = result + “Student name: “. result = result + studentPreferredName + ″)″ . result = result + “Student name: “. You may wish to do several things when the condition is true instead of just one. Therefore a common style is to enclose the statement(s) for true and the statements(s) for false in braces. } 64 . If there is only one. enclose the statements in braces. If you add another statement.length() == 0) { result = “Student number: “ + studentNumber. without adding the braces. if it does compile. your program may not compile and. The pipe symbols used to make || are typically on your backslash key. result = result + studentFullName + “(“.if (studentPreferredName. the braces are not required. It may take several statements to describe the action. } If you wish to combine more than one simple condition in a larger condition. public String toString() { String result. and you may use || for or. you may use the symbols && to represent and. We will see these possibilities later on.

Click the latest . The Checkstyle extension will appear on the menu.jar file in an unzipping program. Once it has been downloaded. but nothing if it is false. To create this version. A .doc. You can find a list of the extensions which are currently available at http://www. a zipped collection containing all the files necessary to use a collection of Java classes.java files. Follow the Download link.) and save the file. This program comes with a collection of rules for standards you may accept and it allows you to set your own rules. BlueJ extensions are features which have been added to BlueJ.html. the right pane lists the style violations found in that class.html Simpler tests Sometimes you have processing in which you do nothing if the condition is true but do something if the condition is false. Now is a good time to introduce a BlueJ extension called Checkstyle. if so. move it to the extensions folder within your BlueJ installation. or you do something if the condition is true.jar. Here is another tool which can check if your Java code meets coding standards. and the .jar file (as I review this in May 2010 the link is labelled Checkstyle-extension4. we first notice that some of the processing in the previous version is the same whether there is a preferred name or not. . but not by the BlueJ development team.bluej.net/. You can see this by opening a .html files which document the classes. the text early on the page notes that Checkstyle was not written for BlueJ. On the left is a list of the classes in your project. Visit that site and scroll down until you find Checkstyle. Then open BlueJ and choose Tools. available at http://java. A window appears containing two panes.class files. Consider the following alternative version for toString.Braces are necessary in this method since several statements are processed when a decision is made of which path to follow.org/extensions/extensions. you may wish to explore the Java Coding Standard Checker. but don‘t unzip it. a jar file may contain . For Sun‘s standards.3-0. look at the ―Code Conventions for the Java™ Programming Language‖ document. 65 . but I‘ll leave it to you to explore them. Click it. We do that processing and then we use the relational operator greater than to see if there is a preferred name and. an open-source project described at http://jcsc.com/docs/codeconv/html/CodeConvTOC. There are many different style files available. Thus. As you click each. do a little more processing.sun. but has a wrapper around it that allows it to operate within the BlueJ environment.sourceforge.jar file is a Java archive.

there are other relational operators. isInternational.charAt(0). More complicated tests The chapter began with an example that combined four conditions and mentioned that conditions could be combined with && and ||. < (less than). Anyone can have any number. if (firstDigit == '8') return true. and != (not equal). if (firstDigit == '9') return true.public String toString() { String result.length() > 0) { result = result + “(″. everyone has a number. a single character. result = result + “Student name: ″. result = “Student number: ″ + studentNumber.charAt(0) == '9'. But it hasn‘t shown how. These include >= (greater than or equal). it appears. except that students whose permanent residence is outside Canada are given student numbers which begin with an eight or a nine. 66 . Not surprisingly. whether they are students or professors or any other employee of the college. for testing equality. Pause for a moment to create a method. result = result + studentFullName if (studentPreferredName. Now we have greater than. Does your solution look like this? public boolean isInternational() { char firstDigit = studentNumber. } return result. } Or does it look like this? public boolean isInternational() { return studentNumber. Let‘s remedy that deficiency right now. Use the charAt method in the String class to extract the first digit of the student number as a char. <= (less than or equal). or >. result = result + studentPreferredName + ″)″ .charAt(0) == '8' || studentNumber. which will examine the student number and decide whether the student is an international student. } The first relational operator we saw was ==. At Okanagan College. return false.

} The modulus operator (%) gives the remainder when you divide the first value (in this case n) by the second (in this case two). For the next examples. since the examples have nothing to do with students.} Or does it look like this? public boolean isInternational() { char ch = studentNumber. then right click it and choose the constructor.charAt(0). The second and third solutions use the || operator to test if the first character is an eight or is a nine. Now write an isOdd method. Right-click it there and choose the isEven method. return ch == '8' || ch == '9'. Add the following method to Example. you could compile Example. An integer n is defined to be even when the remainder when you divide it by two is zero. } public void testIsInternational2() { assertTrue(s2. Here are two of my tests. This places an Example object in the object tray. you could create unit tests. public boolean isEven(int n) { return (n % 2) == 0. To test this method. n is even. Which did you choose? 67 . while s2 should be. The method calculates that remainder and compares it to zero.isInternational()). public void testIsInternational1() { assertFalse(s1. Or. one for numbers beginning with an eight.isInternational()). How many unit tests did you need to test this method? You should have used at least three: one for numbers beginning with a nine. and one for numbers beginning with any other digit. Which solution is best? That decision is up to you and your teacher. you should create new project called Testing and a class within it called Example. If the remainder is zero. } You can see that s1 should not be an international student. } All the solutions are correct.

a century but not divisible by // 400 so not a leap year result = false. public boolean isLeapYear(int year) { boolean result. it will only be a leap year if it is also divisible by 400. Create an isLeapYear method and then come back and look at mine. But 2100. and 2300 will not be leap years. and 2004 were all leap years. } else // not divisible by four so not a leap year result = false. That is.public boolean isOdd1(int n) { return (n % 2) == 1. There are a couple of different definitions for ―evenly even. You should be able to write isEvenlyEven quite quickly. 68 . but the third is based on the mathematical idea that an integer is either even or odd. } The first two are modelled on isEven. This example uses the && operation. The simplified rule is that a year is a leap year if it is evenly divisible by four but if it is divisible by 100. if (year % 4 == 0){ // divisible by four so might be a leap year result = true. 2000. Thus 1996. ones which use && and ||. Note that we also use the != relational operator. } public boolean isOdd2(int n) { return (n % 2) != 0. there are no alternatives. Within a single if statement we can write compound conditions.‖ Let‘s use the one that says an integer is ―evenly even‖ if it is evenly divisible by four. 2200. // check the centuries if ((year % 100 == 0) && (year % 400 != 0)) // oops. return result. we evaluate a second condition only if a previous condition is true (in this example). } In this method you see that we can nest one if statement within another. } public boolean isOdd3(int n) { return !isEven(n). Do it! Leap years in the western calendar are an interesting challenge. There is a mathematical concept called ―evenly even‖.

the Boolean operations and.Summary This chapter has introduced one of the fundamental features of programming: using the data you are processing to control the flow through your program. 69 . and not. or. It has also shown you how to use the Java documentation to answer questions about classes which are part of the Java libraries. and various relational operators. It has also introduced Boolean algebra.

which generates a random number which two other methods. That is. Some goods are exempt from taxes. when the customer makes a purchase. New Brunswick. The names of these two methods are based on practice which says that methods which return a boolean value should have names beginning with the word is. otherwise consider it to be tails. Note that you will use Math. Assume that a Coin class implements the idea of heads and tails by using a random number between 0 and 1. Such methods are also considered to be getters. typically called heads and tails. Each customer has a number and a name. Ontario and British Columbia adopted an HST as well.random. 70 . Of course the discount might also be based on being a neighbour or friend of the owner. This is mentioned at http://en. Stores have customers. not an instance method.org/wiki/Coin_flipping. A simple object to model is a coin. followed by a period and a method name. Starting in July 2010. A coin has two sides. followed by the period and the method name.wikipedia.Exercises 1. How would you implement your class to allow for biased coins. being a student. if the number is less than 0. 3. he/she will be granted a discount. This discount may be zero. each province has its own provincial tax rate.5 consider the coin to be heads. Until now we have used the name of an object.Math contains a random method which you could use. but we will ignore that detail for now. and Newfoundland and Labrador. This is because random is a static method. ones which come up with either heads or tails more than expected? Recently I read that when you flip a coin it ends up the same face up as it starts with 51% of the time.) Create a method. which may be zero. Anyone who purchases something may need to pay the provincial sales tax or PST. it is a class method. or it may be a positive percentage (or a positive amount) based on his/her previous purchases. there is the Harmonized Sales Tax. java. purchases there are subject to an HST.lang. (Check the documentation to see how. 2. Prince Edward Island. flip. Instead of separate PST and GST. isHeads and isTails will examine to decide if the coin is heads or tails. or being an employee. In those four provinces. Each customer also has a discount rate. For a fair coin. How would you model such a discount scheme? In Canada. that is. There is also a federal Goods and Services Tax (GST) whose payment is required in all provinces except Nova Scotia. Here we use the name of the class.

We will explore the world of birding in subsequent chapters. you modelled a die. Common systems use four characters (http://elibrary.ca/personal/tools/pg/manual/PGaddress-e. as we did when determining if a student number represents an international student. In many parts of the word. so the setter for the common name will use this separate method to determine the abbreviation. write a method which has parameters amount and postalCode.unm. we mentioned modelling a bank account. and fifth characters (counting from the left) must be letters. In it. but one person will always use the same system.pdf) or six (http://infohost. use the charAt method from the String class and provide the value zero as a parameter. given the common name. and returns the tax (PST plus GST.html). Add the abbreviation as an instance variable of the Bird class. third.nmt. the only parameters will be the common name and the scientific name. To extract the first character from the postal code. and sixth characters (counting from the left) must be digits. Note that http://www. Note that common names change over time. Use a separate method to determine the abbreviation. not public. The second. Different people prefer different abbreviation systems. you may wish to use the startsWith method from the String class.Create a Purchase class. that method will be private. fourth.edu/sora/NABB/v003n01/p0016-p0025. In an exercise in the previous chapter.canadapost. or HST) necessary for a purchase. The first. 71 .lang. In the constructor. birders often use abbreviations for the bird name.edu/~shipman/z/nom/6home. you designed a Bird class. The Canadian postal code is a six-character string. 7. In an exercise in the previous chapter. 4. Alternatively. What modifications would you need to make to your class if the bank changed the rules to allow some number of free transactions before it began to charge for transactions? What modifications would you need to make to your bank account class if the bank changed the rules to allow free transactions as long as your balance stayed above a specified amount? 5.Math to create a roll method. Since the method to determine the abbreviation is called only by methods within the Bird class. See exercise 1 of this chapter for further information on the random method. 6.asp#1380608 contains a map showing all the provinces of Canada plus the first character of the postal code for that province. Create a method to determine the abbreviation. The larger provinces may use several postal codes. In an exercise in the previous chapter. Use the random method in java.

Recall that Java numbers its characters starting at zero while English refers to that character as the first character. The SIN is a nine-digit number but it‘s not just any nine-digit number. Either technique will work. Create a method. The SIN itself is described at http://en. 8.wikipedia. You will need to use the charAt method from the String class.charAt(loc)). To check that the character in position loc of a string ess is a letter. returning the appropriate boolean value. which accepts a String as a parameter and decides if it represents a valid postal code.org/wiki/Social_Insurance_Number.valueOf and then use the modulus and division operators to extract individual digits. you convert the nine-character string into an int using Integer.isDigit methods from the Character class. isValidSIN. In the second approach.Create a method. 72 . Canadians have a national identification number called the Social Insurance Number or SIN. you extract single-character substrings from the SIN using the substring method in the String class. which accepts a String as a parameter and decides if it represents a valid SIN.valueOf method to convert the single-character substring to an int. Not only does the first digit indicate the region of Canada in which the number was issued. described at http://en.isletter(ess.wikipedia. There are two possible approaches to solving this problem.isLetter and Character. returning the appropriate boolean value. Assume that the input contains only digits. but the SIN can be validated through the use of the Luhn Algorithm. In the first.org/wiki/Luhn_algorithm. and the Character. and then use the Integer. use Character. isValidPostalCode.

We noticed that the Professor and Student classes looked very similar. Commonality usually implies that there is a better way to deal with the classes than what you have first decided. we divided the people in the classroom into two groups. for both. entered as Strings. but think a little deeper. (The name of a class is usually a singular noun. you will be able to:  Define abstract class and inheritance  Use abstract classes to implement inheritance Abstract classes Before we go any further with the Student class. What common fields are there? Well.Chapter 4 – Inheritance Learning objectives By the end of this chapter. So how can we use this information? We can create a new class. right now there are none since the attribute names are different. Thus we used Person rather than the initial suggestion of People. Are they really different? No. Professor has a professorNumber. But we are all people! So why not create a People class? That class can contain all the common fields in Professor and Student. 73 . I will use identifier instead. common on the basis of function if not name. we should think back to a comment made earlier. Student has studentFirstName. called Person and derive the Professor and Student classes from it.) This is shown in the following class diagram. After you gain more experience with object-oriented programming (and object-oriented analysis and design. Student has a studentNumber. Since number is not a very descriptive variable name. both are nine-digit numbers. for both. the steps you should do before you start writing code) your ears will perk up at a statement that says ―classes are similar‖ and intuition will kick in whenever you see such commonality. so I will use firstName instead. In this case. the students and the professors. Are they different in structure? Not in this example. Professor and Student have several common fields. Professor has professorFirstName.

Both derived classes have features in common with the base class. We‘ll see this in a few moments. we don‘t wish this. The Person class Create a new project and create within it a Person class. If we try to instantiate an abstract class we will get an error. You can copy the code from your Student or Professor class. Student and Professor are both derived from Person. 74 . remembering to change the variable names. This is a good way to learn the Replace function in BlueJ. But wait a moment! Do we wish to be able to create instances of the Person class which are neither students nor professors? If you respond that ―No. but the derived classes may have features which make them different. there is an arrow from Professor to Person. a word which appears in the class header and signals to Java that we won‘t be instantiating (creating instances of) the class.).‖ Similarly. which I have used here. One diagramming style. we must declare the class as abstract. BlueJ does not do this.Note the arrow from the Student class to the Person class. Person is referred to as a base class for both Student and Professor. is that the two arrows share a common path whenever it is reasonable to do so.‖ (That‘s the way I responded. Enter the appropriate instance variables and constructor. This is read as ―a Student is a Person‖ or ―Student is derived from Person.

So I will declare Person as an abstract class. there are other types of people we wish to model besides students and professors. Its code is below. In this case. (A variable is a piece of memory with which I associate a datatype and name. Examine the two methods you created and you‘ll see that they are almost identical. which I have named result. middle. so you could argue they should remain where they are. I‘ll use the name result. public String toString() { String result = new String(). and save the result. and when I need the contents of that area of memory. The only difference is that one toString method places the word Student at the beginning of its result. But you could also argue that the following solution works as well or better. What about the toString method? Both Student and Professor contain that method.If you respond that ―Yes.) Whether or not there is a preferred name. Thus the methods are not identical. public abstract class Person Notice how the class diagram shows that Person is an abstract class. I can see the arguments behind both answers but. last. So I concatenate them. the area of memory will contain a reference to a String. for the model we are creating (and it‘s my model!). we won‘t have anyone other than a professor or a student. Perhaps there are the administrative deans. result = "number: " + identifier + " First name: " + firstName + " Middle name: " + middleName + " Last name: " + lastName + " Full name: " + fullName. } To calculate and save a string. toString in an abstract class We have placed the common instance variables in the abstract class.‖ then you do not wish to declare Person as an abstract class. The saving is done in the statement beginning result =. and full names. Create a toString method in the Person class. I need a variable of type String. I need to concatenate the identifier and the first. the other places the word Professor. return result. and. Perhaps we wish to model alumni and the recipients of honorary degrees.length() != 0) result = result + " (" + preferredName + ")". if (preferredName. we should place methods as high up the inheritance tree (as close to the base class) as we can. as a general design rule. The way to interpret this statement is to say ―Calculate the value to 75 .

if (preferredName. But the resulting code looks strange to my eyes. Now I need to check whether there is a preferred name. which we will do in a moment. to testing for equality but having an empty section of code. we will include the following methods in the appropriate classes. super. we test for inequality. } The reserved word super refers to the base or parent class. to my eyes. As we have seen earlier the exclamation point is used to indicate not. So we do not test for equality. as appropriate. and then.toString() asks the parent to represent itself as a String. Tests for inequality or greater than are both acceptable and are preferable.length() > 0) result = result + ″ (″ + preferredName + ″)″. if (preferredName. and that could cause some strange code. we prepend a word to that String. Since it is a String. 76 . and != means not equal.‖ This is exactly what we have been doing in our constructors and previous toString methods. Most people would wonder what is missing so we place a comment there to indicate we have not forgotten something. public String toString() { return "Student " + super.toString(). When we create the Student and Professor classes.the right of the equals sign. } public String toString() { return "Professor " + super. When there is no preferred name.toString(). There are no executable statements between the if and the else.length() == 0) // do nothing else result = result + ″ (″ + preferredName + ″)″. use result to remember where the value is stored. there is nothing to be done. Thus == means equals. Note that we are overriding the toString method in the parent class by creating a toString method in the derived class. Note that we could have used the symbol > (or greater than) instead of != since the length cannot be negative.

where s is an instance of Student. That is. } Attempt to compile Student. Do you need to create a getFirstName method in the Student class? No. Create two new classes within this project. That method. continued Compile the Person class and see what happens when you attempt to instantiate it. String middleName. Notice the statement that says public class Student extends Person. As noted above. fullName. middleName. Then double-click the Student class to open it in the code editor. Draw the arrow from Student to Person. super is the word Java uses to refer to the parent class. String fullName. and the other getters and setters should be in the Person class. Right-click the class and choose the constructor from the menu. firstName. Student. the parent class. How do you create a Student object? A Student object needs a simplified constructor. String preferredName) { super(identifier. private instance variables (and methods. They may not be accessed within derived classes. will be compiled first. That is because the class is abstract. Student(String identifier. for that matter) may be accessed directly only within the class in which they are declared. and Professor. You created this statement by drawing the inheritance arrow from Student to Person. It will not compile. But the constructor is not exposed! That is. Without a method after the word super. the effect is that the Student object essentially says ―I don‘t recognize that message. if you have changed both Student and Person. Change the visibility on the instance variables of Person to protected. You can tell which classes need to be compiled since they appear striped in the diagram. Then create toString methods in Person. simply by calling super as the first step in the Student constructor. Student and Professor.‖ 77 .getFirstName(). it can use the constructor of its base class. since the constructor in the derived class is trying to use private instance variables of the base class.The Person class. Thus we cannot create a Person object. indicating inheritance. I‘ll ask my parent to respond to it. String lastName. preferredName). lastName. it does not appear on the menu. Person. Simply click the Compile button beside the class diagram and all will be compiled in the appropriate order. as we showed earlier. protected instance variables (and methods) may be accessed directly within the class in which they are declared as well as in any derived classes. Compile all the classes. look at the class diagram. String firstName. If we use the expression s. you are executing the constructor in the base class. Hint: If you are unsure which classes you have changed and thus should be compiled.

fullName.charAt(0). } } // end class Modify the unit tests for Student to take into account the different instance variable names we are using. String firstName. } /** * @return a Student. 78 . if (firstDigit == '8') return true.Set up your Student unit tests to ensure that they still work. as a String */ public String toString() { return "Student " + super. String fullName. lastName. String preferredName) { super(identifier. String lastName. } /** * An international student is one whose identifier * begins with an eight or a nine * @return true if the student is an * international student */ public boolean isInternational() { char firstDigit = identifier. middleName. The Student class – a derived class My implementation of the Student class is shown below. firstName. if (firstDigit == '9') return true. /** * A Student * * @author rick gee * @version september 2007 */ public class Student extends Person { Student(String identifier. return false. String middleName.toString(). preferredName).

Of course. A model is a representation of something ―real‖. 79 . we can explore them in more detail. This exploration begins in the following chapter. In particular. Note the phrase ―simplified classes‖ in the previous paragraph. our class and its instances do not represent actual. When we speak of abstraction. it is a derived class. Like the Student class. students in this case. The only method we need to test is toString. We know that the getters and setters work. It represents a simplified student. albeit simplified classes. we have seen how to create classes which inherit instance variables and methods from their parents. It is currently similar to the Student class. It is just a model and omits many aspects of real students. identifying missing instance variables and behaviours. Summary In this chapter we have had an introduction to inheritance. students. we are referring to the process of eliminating non-essential aspects of objects which model real things. but does not need the isInternational method. we can create and test the Professor class. This simplification is the essence of abstraction and model making.The Professor class Now that we have the Student class created and tested. But it is just an introduction. an abstraction. We will see inheritance again in later chapters. Now that we have created well-designed Student and Professor classes. living. We have also gained more experience with unit testing. The unit tests here are simple. since we have tested them as part of the Student class.

including Harris‘. Objects of the Administrator class need to know their salary. An interesting collection of bank accounts are described at http://cse. 80 . Objects of the SupportStaff class need to know the local to which they belong. etc. In a previous chapter. the people without whom the institution would not run. Sparrows come in many varieties. Birds and all other living things provide interesting examples of inheritance. I discussed birding. For historical reasons.pdf. and support staff. Note that the biological classification into kingdoms. 2.stanford. is a fertile source of modelling exercises. Sun provides a Java tutorial on its website. Model these in the simplest way possible.sun. including Herring. One of its inheritance examples is the bicycle and the different types of bicycle.com/docs/books/tutorial/java/concepts/inheritance. who provide management and direction. Warblers too come in many varieties. Savings accounts don‘t allow cheques. I discussed the use of a bank account as a common class for modellers. A second section of the page referred to above contains an interesting perspective on the role of Instructors at a teaching institution. Extend your model of the bank account to accommodate some of these variations. Support staff are unionized. orders. 4. including the Blackbrowed and the Black-footed. In a previous chapter. There are also administrators. families. there are three separate locals of the union on campus. 3. but you may be able to understand much of it.Exercises 1. and there are many types of Gulls. and California. and the Gambler. Mew. and Kirtland‘s. and there are many types of albatross. Implement Administrator and SupportStaff classes using inheritance from Person. High interest accounts allow only a few withdrawals in a month. Model the inheritance described.edu/class/cs108/982handouts/14%20Inheritance%20Examples. The programming in this example is in C++ rather than Java. Song. including Yellow.html. Swainson‘s. An albatross is a type of bird. At Okanagan College there are not just students and professors. I don‘t think a real bank would have account types called Nickel ‗n Dime. and House. http://java. Part of its attraction is that there are so many types of bank accounts. A gull is a type of bird.

There are actually several types of rooms. Use inheritance to model these three room types. use inheritance to model these different types of furniture. chairs.How would you change the model to accommodate unicycles? Is a unicycle a bicycle? 5. 6. including lecture rooms and laboratories. I discussed modelling a Room at a college. people who have already completed one degree and are studying for a higher degree. 7. How would you model a graduate student? In a previous chapter. desks. In a previous chapter. 81 . Assuming that the different types of furniture include tables. I discussed modelling Furniture at a college. and filing cabinets. A GraduateStudent is a Student. Okanagan College is a four-year college so has no graduate students.

82 .

It‘s just a String. Professors also need to provide an address and contact information. Introduction A college needs to know the address of students. this time to the Human Resources Office. A phone number is not so interesting. or they may be the same. Email addresses are not so interesting. (A transcript is an official record of the marks a student earns in the courses she takes.) The Library will use that address to send notices of library fines. In addition. We can add an address to the Person class and both Student and Professor will have access to it. Adding an address Let‘s now add an address to the Student and Professor classes. Stop! Do not pass go! What is wrong with the statement? We do not need to add an address to both classes. including transcripts. many institutions also want email and/or cell phone (mobile phone) numbers they can use to contact students in case of emergencies. Given the problems with violence on campuses. It may have a mailing address and a separate street address. So what is an Address class? What makes up its state and its behaviour? 83 . so the Registrar‘s Office can send written communications.Chapter 5 – An Address class Learning objectives By the end of this chapter. An Address class is the focus of this chapter. The interesting discussion is around a person‘s mailing address. Let‘s begin there. you will be able to:  Create more complicated classes  Explain when and why to use cloning  Use the online Java documentation to find out about classes. They too are just Strings. a college also needs to know its own address.

giving addresses like 8743 12 St NE. but don‘t you think it would be better to create an Address class (especially since the college may need this class to hold its address) and then allow the Person class to contain an instance of the Address class? Yes. If you do include the apartment number. are examples. For complete generality.  Type. what happens at a workstation?‖ Isn‘t the English language wonderful?  Direction.ca/tools/pcl/bin/advanced-e. or Crescent. as we have seen earlier when we looked at names. Perhaps you live in a suite in a house and have an A after your address. if you have some spare time. What statements are those? In addition to the ones BlueJ creates for you. it would be a very good idea to create a Name class.  Name. Parkway. one with an apartment number. you could make the same argument about a Name class. you may wish to have two constructors. I would suggest the following fields:  Number. Return to the BlueJ drawing pane and create a new class. Road. Different countries use different formats for their codes.The Address class What fields do we need to form an address? You could use one long String.asp We could add all these fields to the Person class. consider the Canada Post postal code lookup page at http://www. Street. named Address.  Number suffix. and one without. To see where the ideas for these fields arose. and a toString method.mailposte. Double-click Address and enter the Java statements that it requires. it may be more efficient to decompose the address into smaller fields and combine them to form larger combinations as needed.  Postal Code. you also need the comments that are appropriate.  Province (or state) or other subdivision of the country. the details of the constructor. you need private instance variables.  City. This reminds me of the old question ―Why do we drive on a parkway and park on a driveway?‖ or ―If a train stops at a train station. 1703A Yates Street is an example. We will not deal with that here. Some towns are divided into sections.  Country. 84 . In fact. My example will not do so. Of course. but. you should also add an apartment (or unit) number to the address.

String direction. // NW. private String direction. this. this. String postalCode) { this. String province.the number on the street * @param suffix . this. this. or village * @param province .the city.suffix = suffix.name = name. /** * a class to contain a street address. this. * @param number . etc. * @param city .number = number.postalCode = postalCode.a suffix to the number (1702A) * @param name .direction = direction. SE. * excluding internationalised postal code * @author rick * @version 1 – april 2006 */ public class Address { // instance variables private String number. /** * Constructor for objects of class Address. } 85 . private String country. String type.The Address class – the code My code is below.for a city divided into NW. // 1702A. for example private String name. String country. String city.the postal code. private String suffix. * @param direction . */ public Address(String number. town.the name of the street * @param type – road. private String type.two-character abbreviation * @param country – the country * @param postalCode . this. String suffix. this. for example private String city. street. private String province.type = type.province = province.city = city. String name.country = country. crescent. private String postalCode. this.

each person develops a different programming style. * * @return . if (suffix. but there are some interesting things in toString. For example. The Address class – the code – in detail Let‘s look at my code in some detail. First. if (direction. instead of result = result + ″ ″ + name. If you prefer not to use the keyboard to see the documentation. result = number. // end of line 2 result = result + '\n'.length() > 0) result = result + " " + direction. result = result + " " + country.length() > 0) result = result + suffix. 86 . result = result + province. I prefer to write many short statements while concatenating Strings. other than provide a few statements in your code.convert the address into * something suitable for a mailing label. Some people write fewer and longer statements. // end of line 1 result = result + '\n'. Press J again to return to your source code. result = result + city. result = result + " " + postalCode. result = result + " " + name. Isn‘t that a nice piece of documentation that appears? And you didn‘t have to do anything special to have it appear. press -J while viewing the Java code of the Address class./** * toString .a String containing multiple lines */ public String toString() { String result = new String(). result = result + " " + type. // end of line 3 return result. simply use the dropdown box at the top right corner and choose between Source Code and Documentation. The constructor contains nothing new. } } If you think documentation is not worth writing. Despite what you see in some of my examples.

Adopt what you like from my toString method. A line feed moved you down one line. called char. the value of name. you could write result = result + ″ ″ + name + ″ ″ + type. (Yes. Concatenating a char onto a String creates a new String. The effect is the same. http://en. a blank. http://en. In the days of the typewriter. is shorthand for x = x + y. Some people are even more terse. one which. If you want a single character. See the Wikipedia article on ASCII art for some examples. This allowed you to produce some interesting effects. My toString method produces a three-line address that is suitable for printing on a mailing label. Since the carriage return didn‘t move down a line. When you display an address. 87 . Single characters are enclosed in single quotation marks.) So Java contains a character datatype.wikipedia. and a carriage return and linefeed combination is a character. concatenating the current value of result. They will write result += ″ ″ + name + ″ ″ + type.result = result + ″ ″ + type. x += y. a carriage return moved you from the current position on a line to the beginning of the line.org/wiki/ASCII_art You may even wish to see the article on typewriters if you don‘t know about them. but that detail is hidden from us when we are using Java. each digit of a number is a character. A String may contain zero or many characters. BlueJ shows the \n character instead of moving to a new line. and test it. and saving the resulting String in the variable named result. Why the blanks? So the output is ―1702A Fifth Street‖. represented by \n. in this case. A tab is a character. So ‗\n‘ is the representation of the carriage return and linefeed combination. and the value of type. represented by \t.wikipedia. There are other shorthand operations including -=. Each letter of the alphabet is a character. and /=. *=. you could type over what you had typed. each punctuation mark is a character. a blank. compile it.org/wiki/Typewriter Some operating systems treat a carriage return and a linefeed as two separate characters. And what is this ‗\n‘ that appears in two places in toString? A String is delimited by double quotation marks. a String may be overkill. not ―1702AFifthStreet‖. contains the command to display the rest of the String on a new line. I have used a single-character String for the space between fields.

out. The output to the screen is through either the err device or the out device. and run unit tests as you do so. choose Show Code Pad. println is a method which calls the toString method of the object it is given. Recall that using the word protected means that derived classes may access this variable. from the main menu. Compile the class. Now create the unit test for the getter and setter. Then.println(address1). address1. I have to look at the output to decide whether it is correct. A small window appears at the bottom of the BlueJ window. with different parts on different lines in the lower portion of the window. The Address class – getters and setters Add the first of the getters and setters. but appearance may be part of its correctness. protected Address addr. in this case two. showing the output of the println command. and. A Terminal Window opens. and displays its output on the requested device. the output would have appeared in the upper portion of the window. Accept the suggested name of address1. the cursor moves to the following line.To see the output as it is meant to be seen. Person uses Address Now that the tests are complete and all pass muster so we know that Address objects work properly. how do we add an instance of Address to Person? It‘s simple. declare an instance variable.println.err. type System. I will sometimes display the result in the Terminal Window rather than using an assert statement. and press . one pair at a time. I don‘t care which ones they are. Hint: you can have many. Compile the class after you make each pair. When I am testing a method which produces a long String as output. and save the file? 88 . choose View. in this case. out output appears in the top of the Terminal Window. System is a class which allows your program to communicate with the keyboard and the screen. After displaying the output. In that window. ready to display more output. err output appears in the bottom. Ensure you compile and run the tests after you create them Now create the other getters and setters. If we had used System. compile. editor windows open on your screen at once. Use one to create the class and the other to create the unit tests for the class. Add. create an Address object on the workbench. from the dropdown menu. Did you notice how a ―uses‖ arrow appeared on the class diagram when you insert that statement.

We are not saying that an Address is a Person. @param addr the address Then we save the value provided to the instance variable. one of whom later moves. Making copies (cloning) Note: This section (and others later) deals with an advanced topic. called immutable. We are saying that a Person object contains one or more Address objects. it receives a reference to the Object (essentially an address in memory). when two Student objects refer to the same Address object. Exercise 1 provides directions to see how this can happen. When you have a reference to an Object. It is a special kind of Object since most can be changed. this. do it now. rather than waiting until you have fixed the problem.) This is quite different from the ―extends‖ arrow.A ―uses‖ arrow is an indication that objects of one class (the one at the blunt end of the arrow) contain objects of another class (the one at the sharp end of the arrow. so we add the address as a parameter to the Student and Person constructors. At the moment. Consider roommates. perhaps when you are more comfortable with Java. so may need another address. At least that is what you may have guessed from everything we have seen so far. When an Object (and every parameter we have seen so far is an Object or is derived from an Object. a home address. including documentation. It is included here because this is the correct place to talk about it. Does everyone have an address? They should have an address. But there is a subtle problem here.addr = addr. any change to the Address object will affect both Student objects. But you may skip it should you wish. but we do need to clone an address. 89 . it is possible to use methods of the Object to change its contents. That means it cannot be changed without totally rewriting it. The implication of this is that we do not need to clone the parts of a name. Be aware that your program will contain an error which should be fixed.) is passed to a method. But students often do not live at home. The parts of a person‘s name are Strings. it cannot be changed by adding or deleting a single character. If you are going to do that exercise. a Person will contain only one Address object. In particular. since they both contain references to the same Address object. the method does not receive a copy of the Object. and a String is a special type of Object.

often implemented as addresses of memory) since their contents are in different areas of memory. Thus. even though they have not moved! 90 .equals(s2)). Take the value of the Object and mix it up some way. it can be changed quite simply. Exercise 1 in this chapter asks you to explore the following scenario.err. we do not change the contents of the area of memory associated with it. Now consider the statement String s3 = s1. s1 and s3 will compare as not equal when using the equals methods (since their contents are different) and when using the logical operator ==. Suppose a group of students share an apartment. Thus s1 and s3 refer to different areas of memory. containing the different contents. You can enter them. that address change will be reflected for all the other roommates as well. You can see this by using System. String s1 = “here is a string”. The food called hash is a mix of a variety of different ingredients. When we change its contents. we should make a copy of it when we store it as part of a Person. in the CodePad window.Consider the following statements.println(s1. we allocate another area of memory.) Now consider the statement s1 = “this is a different string”. Two Objects with identical values should give the same hash code. nor are they equal when you use the logical operator == (which compares hashcodes. String s2 = “and here is another string”. The two Strings are not equal when you compare them using the equals method (which compares contents of strings) since their contents are different. Making a copy of an Object is called cloning the object. After this statement. producing a single number. Before executing this statement. Several Person objects now have a reference to the same Address object. Some people say it looks like pet food. s1 refers to an area of memory which contains ―here is a string‖. and the same Address object is used to represent that address for each of the roommates. An Address is not an immutable Object. and System.println(s1 == s2). and the tests I describe. But s1 is immutable. The idea behind the computer technique called hashing is similar. s1 and s3 will compare as equal using the equals method (since their contents are identical) and when using the logical operator == (since they both refer to the same area in memory.err. If one of the roommates moves away. changing his/her address. That number is an indication of the contents of the Object.

Now that we have the code to clone an Address. Open the Address class in the editor and modify the class declaration to read public class Address implements Cloneable Then create a new method in the class. the method would not work. direction. it cannot create a clone method. The word final in the method definition simply says that should any class use Address as a base class. } catch (CloneNotSupportedException e) { return null.com/javapro/2004_04/online/rule5_04_07_04/ If you are uncomfortable about using code which you do not understand. // can not happen } } This method works since all the instance variables are Strings and know how to clone themselves. we must resort to a little deception. country. city. Create the unit test for the Address instance variable in the Student and Professor classes. at least not for a while. } // end clone() The Address class – unit testing Create the getter and setter methods for Address. type. If any instance variable did not know how to clone itself. 91 . /** * @return a copy of the Address */ public final Object clone() { try { return super. this. In that case. postalCode).addr = (Address) addr. Assume the getAddress method returns an Address.To clone an Address object. we can use the correct statement in the Person constructor. name. we would implement a clone method for the class to which those instance variables belong. This is a security issue. of course. province. the following method also clones an Address object. but you must promise not to ask how it works. public final Object clone() { return new Address(number.clone().ftponline. I‘ll show you the code you need.clone(). See more details at http://www. suffix.

what happens when there is no address available? The reserved word null We have assumed that everyone has an address which they are willing to provide. A second way is to modify the unit test for the toString method in Person. o Create an Address object by right-clicking the Address class and choosing the constructor. The test passes if all pass. The simplest way to do this is to use the toString method in the Address class.I had some difficulty with assertEquals when checking the equality of objects. One solution. but the last is the name of the Address object you created earlier. we should modify the toString method of the Person class to display the address. Once the Student objects have been created. and provide values of its instance variables. check their addresses. thus creating a complicated test. You have to check that the corresponding parts are equal. Thus the solution is to use assertTrue(a. When we allow null addresses.toString().). where a is the variable containing the expected value and b is the variable containing the actual value. o Note the name of the object which is being created (probably the name is address1. Strings need to be surrounded in quotation marks but the address. the name of a variable. Recompile everything. which I do not like. o Create a Person object by right-clicking the Person class and choosing the constructor. Before the last line in Person‘s toString.equals(b.toString())).toString(). 92 . How do we create an Address object to pass into the Person constructor? One way is to use the Object Workbench. Most of the values you provide are Strings. Testing Address cloning Before we create the Address and Student objects. but you can change the name if should you wish. In particular. What happens when someone does not have an address or does not wish to provide it? What do we provide to the constructor in that case? Java contains a reserved word. place the line result = result + “ Address: “ + addr. is to place many assert statements in one test. null. to use in this case. But I prefer to have one assert statement per test. like the address. does not. we need to be sure that we neither clone a null object nor should we attempt to convert a null object to a String.

and one with a null address. You‘ll need separate tests for addresses which are missing and for addresses which are provided. Yes. You need to decide which is the most likely to be provided. a college may have two addresses.addr = (Address) addr. We will not add parameters to the constructor. providing the actual location of the college. else this. This applies in both the constructor and the setAddress method. recompile your classes and test your work by creating two Student objects. if (addr != null) this. The College class and addresses As noted earlier.clone(). Modify the College class so that it has instance variables for both the street address and the mailing address. After making the changes to allow for null address. We will use the setStreetAdress and setMailingAddress methods to set the appropriate values.addr = null. if (addr != null) result = result + '\n' + addr. Before cloning the address. 93 . fix it. Instead of simply calling the toString method of the instance variable addr. The constructor will simply set both addresses to null. A third constructor is one which provides only one address. We will see this later when we explore ways to save the contents of objects. we must check it is not null. (Just provide the word null instead of name of the Address object. Create unit tests for both addresses. we need to check whether addr is null. four unit tests in all. A second constructor is one which provides both addresses.Thus we must make two changes to our code.) Does your toString method work properly? If not. which may or may not be the same as its street address.toString(). I would suggest that the street address may be the one you wish to use. The other is its mailing address. one with an address. One is its street address. a class may have several (more than one) constructors.

There is no difference in the structure of the two types of object. Let‘s look at one more structure they have in common.Summary While an address appeared simple. and then we‘ll start to look at their differences. And there are complexities we have omitted! Note that everything we have said about a Student object so far applies to a Professor object. it turned out to be quite complex. 94 . There certainly is a difference in the roles they play at the College.

Design and implement such a class. Use the setNumber method of the Address object to change its number. Create two Student objects on the Object Bench. What happens when you do the tests? Then do another test. and Professor classes we have developed all use instance variables to represent the different parts of a name. Create an Address object on the Object Bench. 5. perhaps we should do the same for Name. It may just have a name. both of which contain references to the same Address object. Use the CodePad window to verify that Strings do not need cloning by repeating the tests described in this chapter. 6. Student. Use the getAddress methods in each Student object to see that the addresses are both the same.Exercises 1. or a description. Is s1 equal to s3 or not? 3. 95 . s1 = “here is a string”. Since we created a class for Address. The Person. Create a unit test that verifies that Strings do not need cloning. 2. That is. Confirm the need for cloning by the following procedure. First. Identify some of the different ways in which postal codes differ from country to country and write code to verify that the code entered matches the country. the other student will appear to have moved as well. Add another statement. Internationalization is becoming more and more important. of course. Then use the getAddress methods for both Student objects to see that both now contain the new number. 4. The effect is that whenever one student moves and updates the address. How would you modify the Address class to support this? Make it so. you‘ll need to add a country instance variable to the Address class. Suppose you are dealing with a culture in which not every home has an address. Internationalization is becoming more and more important. a program is not necessarily used in the country it is written.

96 . United Kingdom. or some other countries which are different from your own.Then. USA. explore the postal codes for Canada.

perhaps. All of these involve the use of dates and. At Okanagan College. It would be better to store the birthday and calculate the age whenever it is required. This chapter will explore dates. a professor is required to retire on the June 30 following his/her 65th birthday. To do that you need to be able to store a date. you need information about the age of a person. How old is a person? In many cases. But you don‘t want to store the age. you will be able to:  Create more complicated classes  Work with dates  Use the online Java documentation to find out about classes. it has been abolished. You will explore that idea in the exercises at the end of the chapter. Sections of a course have specific times for meeting. Perhaps professors who have been there the longest have first choice on middle-of-the-day teaching times. What facilities does Java offer to deal with dates? 97 . Mandatory retirement was in place when this chapter was first written. But the example is a good one. Thus professors need to know the date on which they were hired. Perhaps students who applied first will be allowed to register for classes first. In some other situation. so I‘ll continue to use it. because it changes every day. an employee may not be required to pay a certain type of tax or make contributions towards a pension if he/she is too young or too old. times.Chapter 6 – Dates Learning objectives By the end of this chapter. Perhaps students who have been registered the longest are allowed to register first for a new semester. We will explore this in a later chapter. Since that time. Introduction Many things at a college are based on seniority. for example.

The conventions in GregorianCalendar regarding values used for instance variables are as follows  A year y is represented by the integer y . is hour 12. day) are deprecated. in the package named java. future releases of Java may not include deprecated classes or methods. in the package java. That means that they have been superseded by better methods in other classes. There is a hierarchical structure to these packages. Thus the Date class is within the sql package.m. thus 11 is December. used to derive other classes. 0 is January.sql.1900.Date appears to be used with databases. and so forth. guidance is given on what to use in its place.util.) Many of this Date‘s methods (including the constructor which accepts year. Rather than doing that derivation ourselves. The documentation describing GregorianCalendar provides an interesting. Would one of these be what we need. although most of its methods (again including the constructor with year.  An hour is represented by an integer from 0 to 23. (Package is a Java term referring to a collection of classes. month. There are suggestions to use the Calendar or GregorianCalendar classes.  A month is represented by an integer from 0 to 11. and the hour from noon to 1 p. In this case. Thus.Date. The other Date class.m. and day arguments) have been deprecated. Have you noticed that BlueJ displays the hint ―Compile all uncompiled classes in this package‖ when you hover your mouse over the Compile button beside the class diagram? In this case. Reading the documentation closely. the hour from midnight to 1 a.Dates When you look in the Java documentation. we find that this Date class is derived from the other Date class. or are they more complicated than we need? Details about calendars Calendar is an abstract class (in the same way we have developed Person as an abstract class).  A date (day of month) is represented by an integer from 1 to 31 in the usual manner. we should explore GregorianCalendar. though. 98 . is hour 0. One. month. so it is best not to use them. Did you ever wonder why some countries and religions celebrate Christmas on December 25 and others celebrate it on January 6? It‘s a result of the change to the calendars and the reluctance of some people to switch. the term package is all files in your folder. 1 is February. but brief. review of the way dates have been changed in the past. appears much more useful to us. moving from a Julian calendar to a Gregorian one (for some countries) in 1582 or some other year. you will find two Date classes.

  A minute is represented by an integer from 0 to 59 in the usual manner. month. we may be able to use other types of dates. it is extremely unlikely that two leap seconds will occur in the same minute. and twelfth months of the current calendar. 99 . Because of the manner in which leap seconds are currently introduced. November. Why not just create a BirthDate class. including the date a student graduated. and the date an employee was promoted. What data type should we use for the year. We can always create a birthDate instance variable of type MyDate but it would not be sensible to create a graduationDate instance variable of type BirthDate. A second is represented by an integer from 0 to 61. Instead. arguments given to methods for these purposes need not fall within the indicated ranges. and these values are small integers. since that is what introduced this section? Thinking ahead. September. October. tenth. if you cross from one month to another. I know January is the first month. and needs a constructor and a toString method. for example. and ten. the date an employee was hired. a date may be specified as January 32 and is interpreted as meaning February 1. they are more powerful than we need and introduce complexity we do not need. ―In all cases. we will use none of the provided classes. but this specification follows the date and time conventions for ISO (International Standards Organization) C. month. we‘ll create our own class. eight. eleventh. Having a more generic type of date appears to offer more opportunities for reuse. The MyDate class needs instance variables for year. and December begin with the Latin words for seven. Why might this be? Who had a year that was 10 months long? The documentation on the first Date class also includes an interesting note. MyDate. How do we use all this information on dates and calendars? Can we use this information? The MyDate class – a simplification For now. In English. Yes.‖ That makes it easier to decide when 10 days in the future is. the values 60 and 61 occur only for leap seconds and even then only in Java implementations that actually track leap seconds correctly. despite being the ninth. the names of some of the months represent older calendars. but it is an interesting inconsistency that the month variable starts at 1 while everything else starts at 0. I (and others) have to wonder why the day of the month starts at 1 but all other fields (including month) start at 0. nine. and day. and day instance variables? The documentation quoted above gives limits on the values.

int.  There is a toString method. Due to possible confusion between 1 (one) and l (ell). punctuation marks. short. a short contains 16 bits (representing integers from -32768 to 32767).)  There is a getter for each instance variable.  There is a constructor (and maybe more than one constructor. the longest of the four. as long as your number is no larger than 263-1 and no smaller than -263. and 11. it can represent four values.Programming style – a skeleton for a class The MyDate class is like all other classes we have seen and like the vast majority of classes we will see. When the collection contains two bits. 10. In a computer. It wastes a little memory but you won‘t lose any digits. also known as a byte. Instead of storing the month as a number between 0 and 11. one or zero. 100 . 01.  There is a setter for each instance variable which it makes sense to be able to change. In many languages. a bit is the smallest unit of memory. We‘ll store the day of the month as a number between 1 and the maximum number of days in the month. an int contains 32 bits (representing integers from -2147483648 to 2147483647). or on and off.byte. Everything is stored as a collection of bits. depending on how you look at it. we‘ll store the actual year. But why do the names of these integer types not begin with a capital letter? The names of all the other classes we have seen have begun with a capital letter.  There are unit tests. 00. Thus you might see a statement like this. a byte contains 8 bits (representing integers from -128 to 127). Java stores its characters using the Unicode standard of 16 bits (allowing for 65536 values). long numberOfDays = 1000L. we‘ll use a number between 1 and 12. you should use an uppercase L instead of a lowercase l. and numbers not used in calculations) are stored as eight bits (allowing 256 values). you must follow it with the letter l. characters (letters. and long. Recall that we talked about bits earlier. A bit has only two values. and a long contains 64 bits (representing integers from -263 to 263 – 1). Primitive types Java supports many types of integers . If you wish to provide a long value as a literal or constant. They differ in the number of digits they can hold but programmers often choose long. Instead of storing the year as the actual year – 1900. Representing numbers.  There are several instance variables.

this means we have a class encapsulating some value. you find the address of another location in memory. You will sometimes run across the word ―wrapper‖ describing a class.april 2006 */ public class MyDate { // instance variables private long year. including the toString method. like toString. and String objects. though. But when you create an object and inspect the associated memory location. but not in such detail. in a previous section in connection with cloning Address. There are some primitive types in Java which are not objects. /** * Constructor for objects of class MyDate * @param year 101 . a long. Right-click an object and you will see a list of all the instance variables. * * @author rick gee * @version 1 . you will find the object. For primitive instance variables. Digression When you create a variable of a primitive type. When you inspect that location in memory. you associate a location in memory with the name of the variable. this second Inspect button is disabled. there is also a wrapper class called Long which encapsulates a long. Create your unit tests as well. /** * A date on the Gregorian calendar.The answer is simple. there is another Inspect button which is enabled. private long month. including its instance variables. and we have just found the names of four more of them. you will find the value of the variable. As a class. and gives it some of the methods of other classes. For those which are objects. private long day. The MyDate class – the code Take a shot at creating your own MyDate class before looking at mine. Long supports additional useful methods. BlueJ shows this when you inspect an object. as its instance variable. If you go to that address. Name. The phrase ―encapsulates a long‖ means that a Long contains. Of course. below. We discussed some of this.

Try it. this. The bit pattern for a slash is 0000000000101111. When interpreted as a character it is a slash. and so are numbers.unicode. a lowercase a is 0061. (An uppercase A is 0041. long month. and translate each group of four into one of the hexadecimal digits from 0 (0000) to 9 (1001) and A (1010) to F (1111). giving 0000 0000 0010 1111.* @param month * @param day */ public MyDate(long year.toString() + '/'+ (new Long(day)). Thus. What would happen if I used return year + „/‟ + month + „/‟ + day. That is. When interpreted as a number. In an expression which involves a character being added to a number. To interpret the table. group the bits into groups of four (starting from the right). I have used the constructor of the Long class to convert a primitive type to an object.toString().day = day. 002F. the pattern 0000000000101111 is 47.pdf.org/charts/PDF/U0000. thus allowing me to use the toString method to display it. this. you can only send such a message to an Object. Thus when you add a slash to a year you get (It is 2010 as I write this) 2010 + ‗/‘ is 2057. in hexadecimal (or base 16). and explain what happens.year = year.month = month. } /** * convert a MyDate to a String * * @return the date as a String */ public String toString() { return (new Long(year)). Hint: Characters are stored as bits.) To convert from binary to hexadecimal. long day) { // initialise instance variables this. How you interpret those bits depends on the datatype you have specified. 102 . You can see this at http://www. Java interprets the character as a number.toString() + '/' + (new Long(month)).. } } You can‘t send a toString message to an instance of a primitive type. find the symbol you wish and create its hexadecimal value by using the three-digit column heading followed by the digit at the left.

month. 3. hexadecimal. 7. 3. What happens when you specify August as month 08 instead of just 8 (or September as 09). 10.) They begin 0. 5. Thus the octal number 10. But octal numbers go 0. and day if you wish. These two methods cannot be named toString since there would be no way to distinguish between the three methods. 2. 1. so you do not need to enclose them in quotation marks as you did for Strings. and day) in this method. 0123 is acceptable as an octal number. their signatures (the name and the type and number of parameters) would be identical. The MyDate class – unit tests Use your unit tests to see that MyDate creates and displays dates correctly. 5. 1. we find it is equal to 1 * 162 + 2 * 161 + 3 * 160 or 256 + 32 + 3 or 291. Larger octal numbers are preceded by 0. Note that I have used the international ordering (year. If 123 is a hexadecimal value. 2. month. I chose to use a slash (/) but you may prefer to use a hyphen (-). in the constructor? Java allows you to specify integers as decimal numbers (base 10. 6. You may wish to create two extra methods. F. Larger hexadecimal numbers are preceded by 0X. 6. 4. So 08 is not an octal number and you receive an error when you attempt to use it. number in decimal and hexadecimal. The decimal. 6. 8. etc. one to return the date in the American format (month. but different. 10. day. 9. you will use Integer in place of Long in toString. and octal numbers 0 through 7 are identical. 4. 7. 1. 7. 5. 3. D. year) and one to return the date in the British format (day. E. representing the decimal value 8. etc. 10. too. Hexadecimal numbers begin 0. 103 . 4. Java also allows you to specify integers as hexadecimal numbers (base 16) of which we just saw a few. They would all have the same name and the same parameters. 9. In that case. Its value is different from the decimal number 123 and the hexadecimal number 0X123. month. When you use its constructor. 1. Thus the hexadecimal number A. is written as 0XA. we find it is equal to 1 * 82 + 2 * 81 + 3 * 80 or 64 + 16 + 3 or 83. 4. When we translate 0123 as an octal number to a decimal number. 2.. enter it as 0X123. When we translate 0X123 to a decimal number. 7. 8. 10. representing the decimal value 10. 11. Java also allows you to specify integers as octal numbers (base 8. 6.You may wish to modify the separator. etc. year).) Such numbers are the one you use all the time – 0. A. Similarly you get an error if you enter September as 09. 3. you are specifying integers. a bad thing which would prevent your program from compiling. 123 is a valid. Note that you could use the int datatype for year. But what about 08? It begins with 0 but not 0X so it must be an octal number. is written as 010. The numbers 0 through 9 are the same in the decimal system and in the hexadecimal system. 2. 5. C. B.

In a different application. checking that they process birthdates properly. you can‘t create a Person object and then test its methods. How? Since the Person class is abstract. result = (new Long(year)). else result = result + ″/″. Using MyDate objects Create a birthDate instance variable in the Person class. as we did for the Address class.Since the Person class is abstract. Can you imagine an example where such changes would be very bad? Seniority matters. so changing dates there could be a problem.toString(). result = result + (new Long(month)). return result.toString(). Student.toString(). and Professor. you create a Person object. result = result + (new Long(day)). if (month < 10) result = result + ″/0″. 104 . and test it. What the reminder meant to say is that you cannot directly call the constructor of the Person class. But you can create unit tests for Professor and Student. if (day < 10) result = result + ″/0″. public String toString() { String result. else result = result + ″/″. While you should understand that statement. you can‘t create a unit test for it. } Make the MyDate class cloneable. it is wrong. This is because we need to keep dates with no possibility of changing them accidentally. do you want the first nine months of the year to appear as single digits (as happens with the code above) or as two digits? Do you want the first nine days of the month to appear as single digits or as two digits? If the answer is ―two digits‖. and add it to the constructors for Person. modify toString as shown below.In the toString method. A reminder . Create a getBirthDate method in the Person class. keeping track of when parcels arrived could be important. whenever you create a Student object. Because a Student object is Person object as well.

you can create an Address object and then a Student object. and thus it must be an instance variable in the Professor class. While the constructor will accept a null date. Create a Student object. but different behaviours. and then choose getBirthDate. so I deleted those ―uses‖ arrows as well. Then right-click the Student object. specifying null for the birth date. /** @return birthDate as a MyDate */ public MyDate getBirthDate() { return birthDate. using the birth date object you just created. BlueJ may be creating a very complicated class diagram. Simplifying the class diagram By the way. Both these classes are derived from Person. it makes no sense to have a null date here. perhaps with the same names in the different classes. rather than these ad hoc tests. Does toString display the birthdates properly? Remember that it‘s better to have unit tests. getPhoneNumber may return the home number for a student but an office number for a professor. My diagram now has ―uses‖ arrows from the Person. Execute its toString method or its unit tests. It is creating superfluous ―uses‖ arrows whenever one class includes instance variables of another class. Create a second Student object. This is the first time we have had different instance variables in Student and Professor. but now we see that derived classes may also have their own instance variables. Student. Create a Professor object. Unit testing is easier. and thus contain all the Person instance variables. and Professor classes to the Address class. so I deleted that ―uses‖ arrow. Student. and Professor classes to MyDate. 105 . create two MyDate objects. My diagram has ―uses‖ arrows from the Person. We will also see that derived classes may also have their own methods. As an example. choose Inherited from Person. } Now modify Professor to contain a dateHired. How do you test that birth dates and hired date are handled correctly? On the Object Workbench. We will need to insert additional code at a later time to prevent this from happening. The Student class does not directly use the MyDate class. This is an instance variable which Student does not have. But Student and Professor do not directly use the Address class. one for birth date and one for date hired.In BlueJ. My getBirthDate method is shown below.

When the month of birth is June or earlier. Retirement of a professor Recall that I mentioned earlier that a professor at Okanagan College is expected to retire on the June 30 following his/her 65th birthday. since we can calculate the retirement date once we are given the birth date. 106 . We don‘t have a setter method. private void setRetirementDate(MyDate birthDate) { long retirementMonth = 6. Whenever we set the birth date. we calculate the retirement date. haven‘t you? The diagonal shading indicates that I need to compile all my classes. the professor retires on June 30 of the following year. the professor retires on June 30 of the year in which he/she turns 65. You have created all your unit tests. Here is my current diagram (omitting the unit tests for simplicity). Thus.You may find that you can make the class diagram more readable by moving the classes around with your mouse. I‘ve made some changes to them. we can create the following private method. so I can‘t run them until I recompile them. When the month of birth is July through December. and a getter method. Let‘s create an instance variable for the retirement date. that is the only way the retirement date is calculated – it cannot be set through a public setter.

But which method calls this one? The constructor for Professor will certainly need to call it. } Notice some things about this method:  It is private so that only another method within the Professor class may call it. the setBirthDate method in Professor overrides the setBirthDate method in Person.  We use the getters from the MyDate class to extract the year and month of the employee‘s birthdate.setBirthDate(birthDate). public void setBirthDate(MyDate birthDate) { super. whenever we changed the Person setBirthDate we would need to remember to do the same for the Professor setBirthDate. } The call to super. The first is for a person whose birthday is in the first half of the year and the second is for a person with a birthday in the second half of the year. dateRetirement = new MyDate (retirementYear. retirementDay). Retirement of a professor . We do not want to cut and paste statements from that method into this one.getYear() + 65. So too will the setBirthDate method.‖  We use the constructor for MyDate to create the retirement date. The best way to handle this quandary is to create another setBirthDate method in the Professor class.unit tests Create two unit tests for getRetirementDate.setBirthDate (the setBirthDate method in the parent class) ensures we do everything the Person setBirthDate method does. Technically. Professor objects do. Once the processing in the setBirthDate method in the parent class is completed.long retirementDay = 30.getMonth() >= 7) retirementYear++. we do the additional processing which the setBirthDate method in the derived class specifies. long retirementYear = birthDate.  We use the ++ operation to increase the year when the birthday is in the second half of the year. and will also calculate the retirement date. 107 . My tests are below. if we did that. retirementMonth. It will do everything the Person setBirthDate method does. if (birthDate. Student objects don‘t have a retirement date. ++ is shorthand for ―increase by 1. setRetirementDate(birthDate). But setBirthDate is inherited from the Person class.

the answer appears to be. What is the retirement date for a person whose birthday is exactly June 30? From carefully reading the contract. 05. We finish by using the || operator to decide if either of the two conditions. if ((birthDate. long retirementYear = birthDate. long retirementDay = 30. The details of the retirement date are in a contract between faculty members and the college. retirementMonth. 10)). } Note the parentheses. } public void testGetRetirementDate2() { p. Here is my setRetirementDate method. we need to test if the month is June (a condition enclosed in parentheses) and if the day is 30 (also enclosed in parentheses. 11. 108 . but there is a subtle error here. Modify setRetirementDate and create a third unit tests to ensure this occurs correctly.getRetirementDate(). is true. we need to be able to confirm that the calculations are being done correctly.getMonth() >= 7) || ((birthDate. } Many people will argue that unit tests for single-line setters and getters are a waste of time.getDay() == 30))) retirementYear ++. Every if statement begins with if (some condition). But this test is definitely not a waste of time since we need to be 100% sure that the retirement date is correctly calculated. the condition consists of two parts (joined by the symbol for or.getRetirementDate().toString())).toString())). equals(p.setBirthDate(new MyDate(1949. June 30 of the following year. the month is greater than or equal to seven or the birthday is June 30. public void setRetirementDate(MyDate birthDate) { long retirementMonth = 6.getMonth() == 6) && (birthDate.) Either the month is greater than or equal to seven (a condition enclosed in parentheses) or the birthday is June 30. &&.getYear() + 65. assertTrue(″2014/06/30″.) To ensure there is no ambiguity. Here. 10)). To test if the birthday is June 30. assertTrue(″2016/06/30″. Oh. ||).setBirthDate(new MyDate(1950. public void testGetRetirementDate1() { p. the tests succeed. equals(p.Note that unit tests are very important here. these last two conditions are combined using the && operator and then the result is enclosed in parentheses. retirementDay). retirementDate = new MyDate(retirementYear. and one of the parts consists of two parts (joined by the symbol for and.

It is good to admit them. It‘s on the Tools menu. The double equals is also used when you are checking whether two objects both refer to the same area of memory. Spelling mistakes in variable names may cause your program not to compile. It is best to learn from them. so don‘t forget it. Every word in a class name is capitalised. For every opening parenthesis there must be a corresponding closing parenthesis BlueJ helps by indicating the matching opening parenthesis when you type the closing parenthesis. A double equals sign is used when you are checking that two variables (usually primitive data types) have the same value. Thus many of the parentheses in the method above are superfluous. The first word in an object name begins with a lowercase letter but other words (if any) are capitalised. the mistakes may cause it not to work.) == or =.Logical operators have a priority. they just mark you as inexperienced or careless.‖ This is by L. Mismatched parentheses. Bernstein from Software Engineering Notes. Missing braces is a more common problem than missing parentheses. and then go back and fill in what should be between the parentheses. and don‘t add unnecessary semi-colons. Commas are only used to separate items in a list. Class names are capitalised. then the closing parenthesis. July 1993. What are some of the common errors you have made? What are some of the common error message you have seen and what causes them to appear?    Spelling misteaks. && is done before ||. due to confusion between variable names. The default style. They don‘t hurt. Common problems it finds are missing javadoc statements. sometimes seems picky. and then go back and fill in what should be between the braces. Missing or superfluous commas. but everything it flags detract from the readability of your code. If the program compiles. Missing or superfluous semi-colons. now might be a good time to use it and check the code you have generated so far. problems with indentation. A semi-colon marks the end of a statement. Programming style – common errors A quotation which I believe is ―It is okay to make mistakes. Mismatched braces. Spelling mistakes in comments are annoying. In my programming style commas appear only when you are defining or using a method (or when you want them to appear in the output of a toString method. A single equals sign is used when you are assigning a value to a variable. and is still true today. I find it helps to type the opening parenthesis. I find it helps to type the opening brace. But I have put them there to clarify how the tests are being done. 109 . problems with parentheses and braces. then the closing brace. For every opening brace there must be a corresponding closing brace.     If you have installed the Checkstyle extension which I mentioned in an earlier chapter. In particular. It is bad to repeat them. Capitalisation mistakes. BlueJ helps by indicating the matching opening brace when you type the closing brace. one with which I agree.

But we have reached a plateau in what we can do with single-valued variables. the topic of the next chapters. overriding methods as required. 110 . We need to consider collections. Doing this well will be crucial to your success as a programmer.Summary In this chapter we have created two more classes. and explored how we derive classes from a base class. accessing variables and methods in the parent class. and adding variables and methods to the derived class.

you will need to add the time of day to the class. Modify the MyDate class to display the name of the day of the week. The Java libraries contain the GregorianCalendar class which we briefly considered. and the number of young. 4. bird behaviour. or you will need to derive a MyDateAndTime class from MyDate.Exercises 1. 5. The Java libraries contain a DateFormat class. In a previous chapter. create a Sighting class which contains the species of bird. Are you thinking that the note would best be represented by several separate instance variables? Good. You could even create a MyTime class. This note may include location. That is. use it to eliminate the comparisons in the toString method of MyDate. 3. If you use MyDate. simply use the English-language names of the days of the week. the date and time of the sighting. Using either MyDate or GregorianCalendar. but do not eliminate the clarity. Rewrite the setRetirementDate method to eliminate some of the parentheses. Use it to display a date with two-digit months and days. For now. we talked about birders and the sightings they make. Explore that class more fully and use GregorianCalendar objects to replace MyDate objects. number of males and females. 2. and a note about the sighting. weather. Part of a sighting is the date on which it occurred. 111 .

112 .

a collection of vacation destinations. commonly called collections. We need to look at data structures. by giving each Professor object a separate name. You may have noticed that a department at your college or university consists of many professors. A collection of X is an object. You may have noticed that some of your courses have one section but others have multiple sections. list. You may have noticed that a department at your college or university offers many courses. Thus you can talk (in other examples) about a collection of automobiles.Chapter 7 – Collections. part 1 Learning objectives By the end of this chapter you will be able to:        Define collection. and map Compare and contrast the capabilities of set. and a collection of occupations. different departments have different numbers of professors. and new professors are hired. Others may take four. how do we accommodate students taking varying numbers of courses? Some students may choose to take only three courses at one time. list. set. we have two situations. not as singles. list. and map Describe implementations of set. lists. First. We can even have a 113 . Similarly. a collection of houses. You may have noticed that your studies extend over more than one semester. containing within itself a number of different objects of type X. You may have noticed that a professor generally teaches more than one course. we have been able to create two professors. All of these remind us that the world contains objects in multiples. five. the same department may have a different number of professors at different times as professors retire or resign. and maps to represent complicated data Define iterator Use an iterator and a for-each loop to process elements in a collection Use a while statement Life is complicated You may have noticed that you are taking a number of courses. How do we accommodate varying numbers of professors in a department? That is. and map Use sets. or more. Up to now. Second.

a different collection for each type of employee. A college contains a collection of departments. from the college‘s collection of employees.collection of collections. The only employees we have implemented so far are professors. rather than as a collection of Employee (or Person) objects. you will have a getter which accepts an identifier and returns the object which has that identifier. there are at least four kinds of employees. 114 . a different type of organization. they form a collection. provided you have the appropriate getter method for the collection. we‘ll see that it is actually a collection of Department objects. If you have an identifier. I have done analysis (to understand the problem) and design (to find a good solution) in order to decide what I am asking you to implement. When we implement this collection in an exercise. many of which will be in the College class. Each department contains a collection of employees. Thinking like this comes from courses in systems analysis and design. A college contains a collection of students. All other collections ―of departments‖ will contain only department identifiers. All other collections ―of professors‖ will contain only employee identifiers. When we need Employee (or Person) objects. For each collection. you can always find the object associated with that identifier. All other collections ―of students‖ will contain only student identifiers. When we implement this collection in an exercise. That is. I‘ve included a brief discussion of why I believe that collection is appropriate. you register as a student of the college. A note regarding the decision to have many collections of employees: At my college. Collections the college model contains There are many possible ways to model the collections this college contains. you do not register as a student in a department or as a student in a course. When you register as a student. as long as we know the employee identifier. This collection of professors (in the College class) will be the only collection containing Professor objects. This collection of departments (in the College class) will be the only collection containing Department objects. The fourth kind is the administrators who are not in a union but are in an association. The college model we are examining contains many collections. This collection of students (in the College class) will be the only collection containing Student objects. three of which are based on the unions and the locals of the unions to which they belong. we‘ll be able to retrieve them. These courses teach you the questions you should ask before you start to code. we‘ll see that it is best to implement a department as a collection of employee numbers. A college contains collections of employees. What follows is my opinion. Each kind of employee corresponds to a different collection.

There are several such associations. it will need the student identifier and can use that identifier to ask (by calling a method) the College class to search its collections and return the appropriate data. we‘ll see that it is best to implement a collection of student identifiers. By having only one object corresponding to each item in the real world. the collection of sections. While that may be reasonable. This collection of sections (in the College class) will be the only collection containing Section objects. Why will some collections contain objects and some the identifiers of objects? The prime reason is that we wish to have only one copy of an object. we‘ll see that it is best to implement a collection of section identifiers. and one which represents the sections in which a student was enrolled in the past. That is. Each section contains a collection of its meeting times. one which represents the students in a section. Next we have an interesting collection. Whenever any method needs information about a student. While a course may appear to be offered by a department. For past sections. When we implement these collections. Each section contains a collection of students. Each student contains two collections of sections. one which represents the sections in which a student is currently enrolled. we‘ll see that it is actually a collection of Meeting objects. one consisting of sections in which the student is currently enrolled. rather than a collection of Student objects. we remember the marks the student earned at that time. it will lead to problems later when we attempt to model the associations between students and sections. All other collections ―of sections‖ will contain only section identifiers. When we implement this collection. This collection of courses (in the College class) will be the only collection containing Course objects.A college contains a collection of courses. There will be only one Student object representing each student at the college. we will eliminate duplication of data. When we implement this collection. it is actually offered by the department on behalf of the college. When we implement this collection. All other collections ―of meetings‖ will contain only meeting identifiers. 115 . we‘ll see that it is actually a collection of Course objects. All other collections ―of courses‖ will contain only course identifiers. One possibility is that a course contains a collection of sections. This collection of meetings (in the Section class) will be the only collection containing Meeting objects. We will also ensure that when an object is updated. a better possibility is to have the college contain a collection of sections. there will be only one Professor object representing each professor at the college. Rather than have the course contain a collection of sections. When we implement this collection. we‘ll see that it is actually a collection of Section objects. rather than a collection of Section objects. and one consisting of sections in which the student was enrolled in the past. for example. the update needs to happen in only one place.

By asking questions such as these. Many words have multiple definitions. Sets and lists are collections of single values or of objects. consisting of a key and a value? If you are creating a list of the words used in a document. (Another difference is that a set is unordered. These would be represented by sets. since students are unique within a section and sections within a course are unique. or the list of items you need to pick up on the way home. how many other items do we need to check? Is the collection designed to allow speedy searching? This matters when we are searching through large collections.‖ Any course in database management will explain this in more detail. Think again of the list mentioned above. But when you are creating a dictionary. One such word. we can determine the type of collection we should use in a particular circumstance. To check that an item is in the collection. the collection need only contain the words. so each item of the collection may itself contain a collection. Think of a table with two columns and many rows. The first column represents the key. or may it vary? The number of months in the Gregorian year is fixed at 12.) Consider the students in a section of a course or the sections of a course a professor teaches. A map uses a key/value metaphor to store information.      Is the size of the collection fixed. but a list does. For example. Are the items in the collection sorted in some order. and from semester to semester. Consider the coins in your pocket. the second column represents the value associated with the key. The difference between them is that a set does not allow duplicates. the collection needs to contain both the word and a definition. the key might be a student identifier and the value might be a Student object. while a list has an order. chosen for no particular reason.These ideas are behind the practice of ―database normalization. We‘ll explore this in more detail later. can they be placed in a different order? Does an item in the collection consist of a single value or is the item a pair. The uniqueness is enforced by having unique identifiers. the things you must pick up on the 116 . is elegant. These are lists as you may have two coins of the same denomination or two loaves of bread on your shopping list. Does the collection allow duplicate values or does it not? A rack of Scrabble® tiles can contain duplicate tiles but a hand of playing cards drawn from a 52-card deck cannot. but the number of courses a student takes may vary from student to student. Now that we have an idea of what collections our model needs. There are very few words in the index that appear on only one page. The Java Collections Framework Collections may be categorised in many ways. let‘s see what Java provides to implement the collections. or are they unsorted? If they are in one order. Think also of the index of this book.

Implementations of this interface include HashSet and TreeSet. is Set. Implementations of this interface include ArrayList and Vector. These interfaces describe the characteristics of the collection without providing knowledge of the implementation details. there are other collections available. since a word (the key) may have many meanings (the values). We will look at some of the aspects of collections in this and the following chapters. Rather than reinventing these collections. The Java Collections Framework provides collections via interfaces. 2. This last statement shows that choosing the type of collection is not simple. A multimap is a map in which the values are themselves collections. 4.com/p/guava-libraries/. A set In mathematical terms. 5. 2}.com/docs/books/tutorial/collections/index. A multimap is also called a dictionary. 117 . 1. One collection type. a set is an unordered collection of items. HashSet is designed to allow speedy retrieval and insertion. {1. 2.google. Another collection type (and interface) is List. 6. with no duplicates. the key might be a course identifier and the value might be the professors teaching the course. at http://java.way home.com/p/google-collections/ if not from the previous URL. including the Collections library. We‘ll use some other Google libraries in a later chapter. We will begin our discussion of collections by considering the simplest collection. For example.sun. a collection of data items with no duplicates and usually no order. 3} is a set. A third collection type (and interface) is Map. the same set as {3.google. The Java Collections Framework also provides classes which implement the interfaces in varying ways. One interesting collection (of collections!) of them is available at http://code. containing many of the core libraries used by Google projects. which may be available at http://code. The key may be ―loaf of bread‖ and the value may be two. we will use the Java Collections Framework in this textbook. This is a project that Google has developed. An implementation of this interface is HashMap. More details on the Java Collections Framework are available in the Java tutorial. 4} is not a set because of the duplication of the number 4. a set. But both allow an element to occur only once in the collection. {1. Guava contains many libraries. TreeSet provides a sorting mechanism. and hence interface. However.

and one seminar section of the same course in a semester. A collection of professors Let‘s consider how to implement a collection of professors. Given these possibilities.Set. we will impose an order. After all. This is very common and our model supports it since each section will have its own identifier. we need to import a Java library into the College class. there are many possible orderings of professors. This is because every professor has a unique employee number or identifier. a person will not be registered twice in the same section of a course. the order doesn‘t matter. When it does. What matters is that there are no duplicates in the collection. That ensures there are no duplicates. a student is not registered twice in the same section. we will sort the data structure before processing it. we can use sets in our model of the college. but none stands out as the predominant one. The collection of professors will be represented as a set since there are no duplicate professors. 118 . Use this import statement import java. They might be ordered by name. At my college a student may be registered in two lecture sections of the same course at the same time only when the course is a Special Topics course and the two sections focus on different topics. Recall that this collection will be an instance variable of the College class.util. but remains unordered. nor will a professor teach the same section twice. We will assume no ordering on the elements. Then. To implement this collection. should it be necessary. They might be ordered by name within department. all of whom are employees of the college. Does the order in which we store the courses in which a student is registered matter? Does the order in which we store the professors in a department matter? In general. The Google project mentioned above does contain a multiset.There is a collection called a multiset (or a bag) which allows multiple occurrences of an item. we will not impose an order until the time we need to process the collection. They might be ordered by employee number. As noted above. Professors might be ordered by hiring date. There is no Java class for a multiset available as part of the Java Collections Framework. More correctly. At my college a student may be registered in one lecture section. Even in this special case. one lab section.

Two Objects with identical values should give the same hashcode. import java. An interface describes the capabilities of a data structure. there are other meanings for the word ―hash. you must import the portion of it which you need. we need to know how to import it into our project.util. but it does not describe how these capabilities are implemented. That is. that operation too is very quick.HashSet package. the hashcode. what methods it supports.util. Of the several choices presented. so we need to import that package as well. That number is an indication of the contents of the Object. The word ―hash‖ refers to how the set keeps track of its members. BlueJ will use javadoc to create the documentation for a class.HashSet.util. These are the classes which implement the capabilities of the Set interface. import java. The idea behind the computer technique called hashing is similar.‖ Java is actually a very simple language.Place this statement at line 1 of the class.about. any import statements must appear at the beginning of the file describing the class.htm. producing a single number. and how to use those methods. When you wish to use a class from one of the libraries (or packages).util. that retrieval is very quick. HashSet A HashSet is a very efficient way of implementing a set. we‘ll choose the HashSet.Set. we just need to know how to use it. Now College contains two import statements. Take the value of the Object and mix it up some way. Some hash recipes are available at http://homecooking. you‘ll find. All of this is described in the online documentation. Most of its complexity and power comes from its many libraries. that it is an interface rather than a class. That is. The Java documentation tells us that HashSet is in the java. Thus.Set. At least. Why we choose HashSet is discussed below. If you look at the documentation describing java. often chopped up. but one of javadoc‘s restrictions is that the comments describing the class must appear immediately before the class header. you must import that library or package. When we need to place an element in the set. but one of the beauties of object-oriented programming is that we don‘t need to know the details of how a HashSet works.com/library/archive/blhash. as expected. The documentation lists All Known Implementing Classes. when we need to retrieve an element from the set. 119 . BlueJ politely leaves a blank line at the beginning of the file when it creates the skeleton of a class for us. Yes. The food called hash is a mix of a variety of different ingredients. Some people say it looks like pet food.

The compiler will display an error message when we attempt to compile a program including statements to add an object of an incorrect type. 120 . We are also asking the Java compiler and interpreter to let us know should we ever attempt to place some other type of object in the collection. and checked ―Show compiler warnings when unsafe collections are used. By writing HashSet<Professor> when we declare a variable we are saying we will be using a HashSet all of whose items are Professor objects. That is. It is much better to identify the type of element in the collection as precisely as we can when we first declare the collection. and thus place any type of object in it. Preferences.‖ Note that this will also cause the compiler to tell us whenever we declare a variable as just a HashSet without specifying the type of its elements. While we could create a collection of Object. Miscellaneous. At least it will as long as we have gone through the BlueJ menu choices Tools.Generic collections Java collections are generic. and its capabilities. is independent of the type of data it contains. that is not a good idea since we might have to check the type of each object as we retrieved it. the collection.

By declaring theProfessors as a Set. changing the first letter to lowercase and adding an ―s‖ to the end of the class. theProfessors = new HashSet<Professor>(). theStudents.We need to name the collection of professors at the college.theProfessors as there is no confusion possible between an instance variable and a parameter. we are describing its general structure and capabilities. Its declaration is private Set<Professor> theProfessors. Let‘s use theProfessors. Note that the order of elements using the hashcode may have no connection to the order you might expect. I would name a collection of Course objects as courses. But there is nothing wrong with using it. A different naming convention. When we add elements to the collection. To see this. and equals is used to detect collisions. This creates a collection which is initially empty. How do you name a collection? Sometimes I will often name a collection after the class of object it contains. I would name a collection of Meeting objects as meetings. hashCode is used to determine the location in the set which the Object will occupy. Programming style When declaring variables which are collections. We have not yet indicated the specific implementation of Set we would like to use. HashSet<Professor> Note the details in the documentation that says that any Object placed in a HashSet must implement the equals and hashCode methods. declare the type as an interface. all of whose elements must be instances of the Professor class. four. We do that in the constructor. I have said that a set is unordered. and 121 . suppose the hashcode is the number formed from digits two. but the HashSet implementation needs to determine where in the set to place a particular object. prefixes the name of the class with the word ―the‖ and adds an ―s‖ to the end of the class name. It uses the hashcode of the object to do so. when two Objects have the same hashcode. That is correct. and then use a specific implementation when the variable is instantiated. the one I‘m using here. Thus I would name a collection of Student objects as students. and theMeetings. This leads to variables called theProfessors. We do not need to use the name this.

/* * test for Person object equality using names. others say it is limited to members named John Smith. 122 . Of course.equals(p. one provided via the reserved word this (in the example above that object will be p1) and the other provided as a parameter (in the example above that will be p2). so 777234567 comes first. an American pioneer. 487654271. one which examines the identifier. The equals method The equals method provides a way to signal when two objects have identical content. we can place the equals method in Person and it will be available to professors. perhaps we should use an alternative form of equals. result = this. In the case of people. if (o instanceof Person) { Person p = (Person) o. but some part of the names are different. 862. and any other type of person we create.otherName.givenName. to check them for equality we use the expression p1. They will be placed in the set in the order of the hashcodes. In that case. In the latter case. this definition wouldn‘t work in the John Smith Society. } return result. We have seen a similar use of the equals method while comparing Strings in the unit tests. their hashcodes are 947. students. Some stories say this society is limited to descendants of John Smith.equals(p. This method examines two Objects. exactly the reverse of the order you might have expected. we could define equality to mean that the names are identical. Since a professor is a person. } If we assume we have two Person objects (p1 and p2).getFirstName()) && this.getLastName()) && this.getMiddleName()). This method returns a boolean whose value is true when the objects are both Person objects with the same name and false when either the objects are not both Person objects or they are both Person objects.familyName. A different way to calculate the hashcode would result in a different order. and 725.equals(p2). We show this possibility later in this chapter. and 777234567.equals(p.seven of the professor identifier. the definition of equality using names we have proposed won‘t be appropriate because it would say everyone is identical. If you have professors whose identifiers are 193456789. * @param o The Object to be compared against the current Object * @return true if both objects are Person objects * and the names are the same */ public boolean equals(Object o) { boolean result = false. and 193456789 comes last.

equals(p. If not. we could check that the identifiers are equal. 123 . What happens when a professor takes some courses. Collisions are dealt with by the collection in one of several possible ways.) when adding the Objects to a HashSet or a HashMap. } return result. This method manipulates the contents of the Object to determine an integer which characterises the Object. } Recall our discussion of George Boole earlier. The hashCode method Recall the details in the documentation that mention every object added to a HashSet must have a hashCode method. other names. if (o instanceof Person) { Person p = (Person) o. but this is an advanced topic which we will not pursue here. then the objects are equal when the given names. the comparison fails. there is no problem since the identifiers are the same structure. boolean variables have the value true or false. Several recent graduates from a degree program were working at the college while completing the degree. It is possible that two Objects may hash to the same number. But we could. and family names are identical. as we saw earlier. Their classification at the college was support staff. a type of person we are not modelling here. Thus a better equals method is: /* * test for Person equality * @return true if both objects are Person objects * and the identifiers are the same */ public boolean equals(Object o) { boolean result = false.We cannot compare apples and oranges. as noted above. we will have a collision (That‘s the technical term. and the method returns the value false. Since the identifier is an Object. Every Object has a hashcode.getIdentifier()).identifier. Alternatively. result = this. both students and professors. In that case. so the method first checks that the Object (p2) provided for comparison is a Person object. we will simply use its hashcode as the hashcode representing the Person object rather than inventing our own hashing algorithm. If it is a Person object. This is probably safer since schools have unique identifiers for Persons. thus becoming a student? At my college.

Create a test for this collection now. at the moment there are none.) We may find it useful to know how many objects are in the set at any time. /** * How many professor are there? * @return the number of Professor objects teaching * at the college */ public int getProfessorCount() { return theProfessors. But first./* * @return hash code for the Person object */ public int hashCode() { return this. Yes.identifier. } What are the elements in the set? I realise that we don‘t have any way of adding professors yet. We can include this in a getter method with no corresponding setter. even though the collection contains no professors. we need a way to visit all the elements in a collection. 0). public void testGetProfessorCountZero() { assertEquals(c.size().hashCode(). even when the collection is empty. but I find it a good practice. Thus we look in the Set documentation (rather than the HashSet documentation) and find a size method which will give us that information. or style. to be able to display a collection. How many elements are in the collection is independent of the way the collection is implemented. } We saw a getter with no corresponding setter earlier when we discussed a professor‘s retirement date. } How many items are in a set? Now we have a collection in which we can place Professor objects (but we don‘t know how to place them there yet.getProfessorCount(). since the value we are getting is calculated for us automatically. 124 . We need no setter.

for (Professor p : theProfessors) { result = result + „\n‟ + p. this statement means visit all the elements of the collection in some order. For a Set. the for-each loop. like this for-each loop. If you omit them. As you visit an object. Note the opening and closing braces. that collections support an add method which will. } Since the collection we are listing is an instance variable of the College class. we have no control over the order in which these visits take place. p. add an object to the collection. public String professorList() { String result = "Professors :". we can list the elements in the collection. obviously. one per line. this addition will take place only when the element is not already present. Then do something with p. but you can display it or count it or examine its contents. * @param the Professor object to be added */ public void addProfessor(Professor p) { theProfessors. since sets do not allow duplicates. The name p is just an abbreviation of Professor. professorList is a method in the College class. } return result.Traversing a collection with a for loop Recent versions of Java provide a very convenient way to do this.add(p). /** * Add a Professor as a new employee. this code will not compile even when there is only one statement which you execute for each element of the collection. 125 . I use single. Adding a professor Java libraries have generally been well-designed (but see the earlier discussion about dates. Now that we can visit the elements in the collection. by looking further at the online documentation. copy it into a temporary variable whose name is the one we have provided. Here is a method to create a String which contains all the professors in the collection. for (Professor p : theProfessors) { // do something with the contents of each p } In English. Note that you cannot update or delete p this way.) We will find.or double-letter names to represent temporary variables which are used only within a small piece of code.toString().

Within that package is an object named out. the definition of a set says there will only be one occurrence of each value in the set. In what order are the professors listed? Run the test again.professorList(). the order in which elements of a set are listed does not matter so it may change from test to test. A window appears in which you will be able to see the output of the test. 126 . where c is a variable of type College. is assertTrue(c. To clarify a statement I made earlier.out. click the name of the test and see its more-detailed explanation. the hashcode is used to help determine the order in the set. but the professor is not added. It is always imported. the addition is silently rejected. Before testing professorList. admittedly clunky solution. false). After all. One is to replace the call to assertTrue with System. which it always does in this case. when we want the professors listed in alphabetical order. This object exists to display messages on the standard output device. As we have seen in many places so far. System is a package which the Java libraries provide us. But there are other solutions. That is. Then test professorList.} Create a unit test which uses this method to add some professors to the collection and then use professorList to display the list of professors.‖ Compile CollegeTest.professorList()). choose View. a matter of personal preference. The name println is an abbreviation for ―print line‖ which itself is an abbreviation for ―print some text and then move down a line. Show Terminal from BlueJ‘s main menu. The order may change as you run and rerun the unit test. One. of course. When JUnit tells us the test has failed. there is often more than one way to produce a result. the screen or monitor you are using. Which is better (or best) is sometimes a judgement call. The order does matter. The explanation is the list of professors working at the college. This is a form of the assert statement we haven‘t seen before. You may do this within your unit tests in several ways. In it we provide a message (the first parameter) which will appear should the assertion (the second parameter) fail. The out object supports a method called println which displays the value we pass to it. you do not receive an error message.println(c. When you attempt to add the same professor a second time. by placing an X beside the name of the test (and displaying the dreaded red line). Is this a problem with our program? No. it does not determine the order. in this case the representation of a professor.

Actually. Let‘s remedy that right now. Now clone the Professor object when you add it to the collection. Some of these instance variables may be primitive datatypes. } When should you add a Professor object to the collection? I would argue that it should be done when the object is created. as the last statement in your constructor for Professor. fullName. you will see the add method returns true when the addition is successful. we will need to modify the clone method to ensure all the instance variables are cloned. We cloned addresses. some may be collections. dateHired). Do your unit tests still work? If not. The addProfessor method we have created discards the value returned. * @return a copy of the Professor */ public Professor clone() { return new Professor(identifier. and addProfessor should become. lastName. } // end clone() Note that as we create more instance variables in the Professor class. Cloning a professor Note that we have not cloned the Professor object when we added it to the collection. but it seems to be acceptable in this situation. addr. Modify the unit test as well. Hence you can say it silently rejects duplicates. when you check the documentation closely. fix the problem. preferredName. birthDate. but we don‘t yet have a clone method. 127 . Why should we not clone professors? Actually. /** * clone. middleName. then addProfessor should return a boolean. It is usually not a good idea to ignore values returned by a method.add(p). firstName. we should clone it. Modify the constructor to make it so. public boolean addProfessor(Professor p) { return theProfessors. If you wish to pay attention to the value returned. It returns false when the addition is not successful.

she could have resigned and gone elsewhere. an Iterator is a class that implements the iterator concept. We have already created a HashSet instance variable theProfessors. Every Iterator object has two methods. and then we remove it. But we wish to delete an element from the collection and the for-each statement does not allow that. As we visit the objects we may change them (including delete them) should we wish. we do not know the object. we would probably not actually remove the professor. to remove a professor. Traversing a collection with an iterator and a while loop An iterator is an object which allows us to visit all of the objects in a collection. removeProfessor would not actually remove the professor. There are at least two types of inactive.util.Iterator.Removing a professor By looking at the online documentation we see that many collections support a remove method to remove an object from the collection. see the Java documentation on Iterator. Before using the next method. o next returns the next unvisited item in the collection. the one with the identifier we are seeking. An iterator is a concept. you should check the result of the hasNext method to be sure there is an unvisited item. an iterator may be implemented in many different ways. Depending on how the collection is implemented. and then use the hasNext and next methods. To allow us to create its iterator. we need to look through all the elements in the collection until we find the correct one. We would probably mark her as inactive. It would set a flag (an instance variable with a limited set of special values) to show that the professor is inactive. But. However. For more details than we have seen here.util. The for-each statement is very handy when we wish to just display the elements in a collection. should there be one. associate it with a collection. o hasNext returns the value true when there are more unvisited items in the collection and returns the value false once you have visited all the items. Thus. or she could have retired. we place another import statement in the College class import java.Iterator. 128 . since we cloned the object. We need an iterator. If we were developing a more sophisticated model. This method assumes that we know (have a reference to) the object we wish to remove. But we won‘t worry about its details! It is sufficient to know that we import the Iterator class from java. we do know its identifier. If we wish to do this.

toString(). Iterator<Professor> it. we have processed. A while statement (or while loop) uses a condition to determine whether a statement (or a block of statements. Otherwise you have created what is called an infinite loop.iterator(). California. We know no way to get out of an infinite loop yet. o Step 1 – check whether there are more elements in the HashSet. When it returns true there are more elements in the HashSet beyond those. the loop continues processing data. The hasNext method returns a boolean value. public String professorList() { Iterator<Professor> it. it = theProfessors. This means that something inside the loop must change the value of the condition. When you are using an iterator. Apple Computer has its headquarters located at 1 Infinite Loop. you often need a while loop as well. } Recall our discussions of George Boole earlier. enclosed in braces) should be executed and then whether the statement (or statements) should be repeated.In any method in Professor which requires an iterator. to make sure it iterates over all members of the HashSet<Professor>. Here is a version of professorList which uses an iterator and a while loop. process the element which is available. } return result. while (it. the loop is completed. it = theProfessors. boolean variables have the value true or false.next(). String result = "Professors".hasNext()) { result = result + '\n' + it. place a statement to create but not instantiate an instance variable which is an iterator over Professor objects. and repeat Step 1. ignoring any previous setting it may have had. While the condition remains true. o Step 3 – If there are no more elements. so resume execution of the method with the statement following the closing brace at the end of the while.iterator(). By the way. 129 . if any. Instantiate the iterator (attach it to the correct collection and ensure it is initialised) when we need it. In English. there are no more elements to process. o Step 2 – If so. Cupertino. If it is false. this while loop does the following.

we use the collection‘s remove method to remove the object. we need look no further. while (it.hasNext(). } } } The iterator provides the elements in the collection one element at a time.iterator(). boolean notFinished = it. if (target.equals(p. } else notFinished = it.remove(p). Since there is only one professor with the specified identifier. it is a collection of professor identifiers. Is this a better way? public void removeProfessor(String target) { Iterator<Professor> it = theProfessors. notFinished = false.remove(p).next(). * @param the identifier of the Professor object to * be removed from the collection */ public void removeProfessor(String target) { it = theProfessors.hasNext(). and then we use a break statement to terminate the loop immediately. When we implement a department. while (notFinished) { Professor p = it. Once we have found the appropriate Professor object.hasNext()) { Professor p = it. break.getIdentifier())){ theProfessors.equals(p. We compare the identifier (the employee number) of the element to the target. rather than a collection of Professor objects.In a similar manner we use an iterator and a while loop to create a removeProfessor method.getIdentifier())){ theProfessors. The break statement is equivalent to ―terminate the loop immediately!‖ Some would say that a break statement is a harsh way to terminate a loop. } } Does this method work when you attempt to remove a Professor object which does not exist? Another collection of professors – the department A college contains a collection of departments.next(). if (target.iterator(). /** * remove a Professor from the collection. Each department contains a collection of professors. 130 . the identifier of the object we wish to delete.

while (it.hasNext()) { String s = it. public Department(String departmentName.chairPerson = chairPerson.departmentName = departmentName.HashSet. } } } } Listing all the professors Now let‘s consider the problem of listing all the members in the department.util. private String chairPerson. } public String toString() { String result = "Name: " + departmentName + " " + "Chair: " + chairPerson.remove(s). import java. break. } public void removeMember(String identifier) { Iterator<String> it = theMembers.iterator(). return result. It is easy to list just the employee numbers. import java.Iterator. } public void addMember(String identifier) { theMembers.next(). import java. theMembers = new HashSet<String>(). public String departmentList() { String result = "Department:" + departmentName. this. for (String id : theMembers) { 131 .Set. private Set<String> theMembers.equals(s)) { theMembers.Here is a portion of the code to implement a department.util.util. String chairPerson) { this. if (identifier.add(identifier). public class Department { // instance variables private String departmentName.

the method should create it and then return it. this. It is null as it is not associated with any data yet.getInstance().mailingAddress = null. private College() { this. so you will need to use the setters to specify its name. phone number.homePage = null.name = null. public static College getInstance() { if (theCollege == null) theCollege = new College(). First. create a getInstance method which returns theCollege. Thus it may be possible to determine the College object which we are using by simply asking the College class itself. Consider these modifications to the College class. which we will create in a moment. It is private so that it is accessible only through a method. Whenever your program needs information about the college. } But how do we list the names of the employees? The only objects which know the names of the employees are the elements of the theProfessors collection within the College class. Second.streetAddress = null.result = result + '\n' + id. It is static so that there is only one such object. this. create a College object. this.phoneNumber = null. If that variable does not yet exist. it uses College. It will have no parameters. but the best is to recognize that we will probably be modelling only one college at a time. return theCollege. private static College theCollege = null. } This method is the access point for theCollege. How do we access that collection? The Singleton pattern There are several solutions. etc. } return result. theProfessors = new HashSet<Professor>(). Your program will contain many statements that say 132 . this. // any other collections } Did you import all the correct classes? Third. make the constructor private.

equals(p. } When we find the professor with the correct employee number we return the name. for (String id : theMembers) { result = result + '\n' + c. showing the names of all the members. This technique is one which has been used in many circumstances.getInstance(). will do it.getInstance(). and then listing the members of the department. given the employee‘s identifier. break. } } return result. } return result. MyDate date2 = new MyDate(2004. This particular pattern is called Singleton. public void testDepartmentList() { // sample dates MyDate date1 = new MyDate(1999. String result = "Department:" + departmentName. This method. 10. 8). That is the one place which contains a collection of the objects in the model. 12. 12). placed in the College class. The word pattern is used to describe such generally-useful techniques.getProfessorName(id). creating a department. we can use it to determine the name of an employee. Now we have all the pieces to produce a list of the members of a department.getFullName(). Patterns will be covered in more detail in a later chapter.College c = College. 133 . public String departmentList() { College c = College. continued Now that we have access to the College object. placing some professors in the department. creating some professors who work at the college. for(Professor p : theProfessors) { if (identifier. public String getProfessorName(String identifier) { String result = "". Listing all the professors. If we do not find the professor. but in every case the object c will refer to the same College object.getIdentifier())) { result = p. so we can be sure that any updates happen in only one place. we return an empty String. } The unit test involves creating a college.

Use these // statements only if your constructor does // not add the professors to the collection c. "L1". "M2".out. how would you modify the Department class? Collection of departments Now that we have a functioning Department class. // professors are in the department d1. d1. and departmentList methods. "F2 M2 L2". System. date2). Professor p3 = new Professor("333". "F1". "p2". // the department Department d1 = new Department(“Gaelic Studies”.departmentList()). date1. date2). and the addDepartment. removeDepartment. null. date1. "L3". "F1 M1 L1". By the way. "F2". "F3 M3 L3".println(d1.println instead of assert.addMember("333"). "L2". Professor p2 = new Professor("222".addProfessor(p1). "p1". Ask your professor to see if this is the situation at your college or university. Is there a clone method for departments? There should be one. "M3". We will leave it as an exercise for you to implement the collection of departments. If it is not. we can modify College to contain a collection of Department objects. p2. null. c. } The department list appears in the Terminal window since this test uses System. // professors work at the college. "M1".out. date1. date2).addMember("111").addProfessor(p3).addProfessor(p2). "p3".getFullName()). "F3". You will need the statement theDepartments = new HashSet<Department>(). this unit test appears to show that the department chair is not a member of the department.// sample professors Professor p1 = new Professor("111". 134 . null. c.

removeStudent. Everything we have said about the collection of professors. and the addStudent. and much of what we have said about departments. a college contains a collection of students too. 135 . which we will see in subsequent chapters. they come in collections. Is there a clone method for students? There should be one. also applies to the collection of students. and studentList methods. Summary Things in the world do not come in singles. including lists and maps. We have seen one type of collection. We will leave it as an exercise for you to implement the collection of students. You will need the statement theStudents = new HashSet<Student>(). the set. We noted that there are other kinds of collection.Collection of students As mentioned earlier. and how to use it.

or should there be a Bank class which contains the collection of Transaction objects? Why? 5. Should you use a Set or a List? Why? Should the BankAccount class contain the collection of Transaction objects. 3. or seen in the movies. we discussed modelling a bank account. which faced out the window. The most-unusual was the birder who kept a list of all species seen reflected in the monitor of his computer. 4. the College class will contain a collection of Department objects. In a previous chapter we discussed modelling playing cards. Only active professors should appear in the output of professorList.Exercises 1. but lives in a flat (or an apartment). If you imagine the birder does not live in a house. In a previous chapter. To do this. the College class will contain a collection of Student objects. or seen on the trip to and from work. I imagine that list doesn‘t get much use now. Then modify your BankAccount class to contain a collection of Transaction objects. Model a Transaction class. Create a YardList class which contains a collection of all the sightings a birder has made in his/her yard. preauthorized deductions. Having a PlayingCard class allows you to model any number of card games. You should be able to produce a list of all the students registered at the college. That is. and retired. You should be able to produce a list of all the departments at the college. Choose a card 136 . etc. Possible values are active. interest payments. In a previous chapter we discussed modelling the sightings a birder makes. Implement the collection of departments referred to in this chapter. That is. Implement the collection of students referred to in this chapter. 2. With LCD monitors. Bank accounts have transactions associated with them. deposits. The transactions come in many forms – withdrawals. I have heard of birders who maintain lists of the birds seen from work. Modify the college model so that a professor is not actually removed from theProfessors. 6. create a class which contains a collection of all sightings made at some specific location. resigned. create an instance variable which contains the professor‘s status.

In a previous chapter we discussed modelling a die.org/wiki/Dice_game. which contains a collection of dice. In bridge. the skeleton for a game. Create a class. In Go Fish. How would you model a game which uses several 52-card decks at once? 7. In poker you may be holding five. consult http://en. 8. you may be holding many.wikipedia. 137 . Many games use several dice. you may be holding 13 cards. Implement a Multiset class. Examine the Google MultiSet class and see how your code differs. In this chapter we referred to a multiset. For some possible games.game with which you are familiar and create a class which contains a collection representing the cards you may hold at any time.

138 .

a course description (String).‖ 139 . a Course object needs a subject abbreviation (String) and a course number (int). whose title is ―Computer Programming I‖. part 2 Learning objectives By the end of this chapter you will be able to:      Describe the use of a comparator Implement a comparator and use it with ordered collections Use a TreeSet Format numbers Produce reports from collections Introduction In this chapter. It also needs a course title (String). with the emphasis on the development of working problems. The course title is a short phrase. this textbook was written to be used in COSC (the subject abbreviation) 111 (the course number). and whose description is ―This course is an introduction to the design. algorithm design. it also contains a collection of courses. including formatting numbers. and then focus on tools and techniques we need to be able to process collections. we will examine more of the collections a college contains.Chapter 8 – Collections. What is a course? What data do we need to remember about courses? The Course class At my college. laboratory (double). and the number of hours each section of the class meets (lecture (double). A collection of courses Not only does a college contain a collection of students. and a collection of departments. the course description is a longer statement about the course. implementation. the number of credits a student earns by passing the course (int). For example. a collection of employees. and understanding of computer programs. and seminar (double)). Topics include problem solving. and abstraction. This includes the production of complicated reports.

Larger hours will occur for courses which are taught in an intensive manner (all day for a week.0.0) is totally incorrect. you look in the Java documentation. For this course. 0). The double datatype allows numbers much larger than these. In this example. 0. 2. with 3.  A course worth three credits. We will adopt that practice. You can see this by visiting http://www. seminars. 0. Everything looks fine until you notice that the triplet containing the lecture hours. the values will be no more than 50. four lab hours. 0). This is ―an abstract base class for formatting locale-sensitive information such as dates.‖ That sounds like what we want to do. 2.0. 2. 2. Thus (3. but we will use double rather than the smaller float datatype. at least according to the standards at my college. and no seminar hours. The outputs should be (3.5. and numbers.5 lab hours. 1. labs. messages. most programmers waste a few bits and use double instead of float. Sample courses could include:  A course worth one credit. didn‘t it? Different colleges display their hours differently. Course – unit tests Create the Course class. with three lecture hours.okanagan. usually the lecture hours will be no more than five. My college standard is that numbers with a zero after the decimal point should be displayed as integers. In our model. and seminar hours is slightly incorrect.The hours will appear in the calendar as a triplet.5 lecture hours. the lab hours will be no more than five.0f is a float and 1. and one seminar hour. for example) before a semester begins or after it has ended.5.  A course worth two credits. the seminar hours will be no more than two. Your toString method did display the hours. the credit hours will be no more than four. and find the Format class. Using the idea of ―formatting‖ numbers.0) is two-thirds correct and (3. Create unit tests to ensure a few courses are created correctly. We need a way to format the numbers as they are converted to Strings. 2.html. As memory is cheap. the triplet is (4.5.ca/calendar/coursedescriptions/university_studies/computer_science. in the order lectures. lab hours. but we can‘t instantiate objects of an abstract class. 0) and (3. 140 .bc. That is. including the constructor and the toString method. with zero lecture hours. What happens when you run the unit tests? Are they successful? Formatting the output Examine the output. if only so that we do not need to put the letter f after numbers. two lab hours. and no seminar hours.5.0 is a double. A double is a primitive datatype (hence begins with a lowercase letter) which stores numbers with a decimal point. 2.

Comments have been omitted in the interest of saving trees.In the ―see also:‖ section of the documentation. http://java.  Second.format(hours).' + myFormatter. return result.#″). } 141 . and that formatting consists of two steps.format(laboratoryHours) + '.util. public String toString() { DecimalFormat myFormatter = new DecimalFormat(″#. entitled Formatting. totalHours = lectureHours + laboratoryHours + seminarHours. which returns it.  First.#″ will provide the output in the correct format.text. The ―see also:‖ section of NumberFormat includes a link to DecimalFormat. result = result + ″-″ + credits + ″-″ + myFormatter. Previously we have imported classes only from java. you provide a number to that formatting object. In our case.sun. Thus. we add the statement import java. Modify toString so it appears as follows. It will display the digit before the decimal point and will display the decimal point and digit following it only when that digit is not zero. double totalHours.‖ Exploring this class eventually leads you to a chapter in the Java tutorial. you‘ll see NumberFormat which is also an abstract base class. result = subjectAbbreviation + ″ ″ + courseNumber. you realise that this class will solve our problem.' + myFormatter. Notice that we are using a different Java package for this class. ―a concrete subclass of NumberFormat that formats decimal numbers. to Course.com/docs/books/tutorial/i18n/format/index After reading through the tutorial. specifying a pattern of ″#.DecimalFormat.format(lectureHours) + '. you create a formatting object using a specific pattern which shows how the output is to be formatted. String result. formatted according to the pattern you specified.format(seminarHours) + ')'. result = result + '\n' + title + '\n' + description + ″ (″ + myFormatter.

the last one in the list. In the previous chapter. A set would be an acceptable implementation of this collection. a first-year calculus course may also have many sections. What happens if you create a class with 10 or more hours of lectures per week? A collection of courses. continued Now that we have a Course class. An array is a type of primitive data structure found in almost all programming languages. You may insert new elements at the end of the list. For each element (except the first) there is a previous element. there is a next element. a third-year course in any subject may have only one section. there is a first element and there is a last element. we discussed which class should contain the collection of sections. 142 . ever. then create the getters and setters themselves. in which there is some ordering of the elements based on position in the list. let‘s look at another type of data structure. and we can base its implementation on our implementation of the theProfessors collection. a List. That is. I decided that it would be the College class which contains a collection of sections. A first-year English course may have many sections. What type of collection will we use? Set? List? Rather than using a Set as we did earlier. A list is a collection of elements. At a small college or university. For the last element in the list. each of which is associated with a position number or index. The Section class A course is offered in one or more sections. For each element (except the last) there is a next element. except that we do not want to remove courses. To retrieve an element from an array. you specify the name of the array and the index. Make it so. The index usually starts at 0. This is so that a student who graduated many years ago can ask for details on the course. For a circular list. Note that there is nothing wrong with a set. or in the middle of the list. An array is a collection of elements. the first element in the list. we can resume discussions on a collection of Course objects. The collection will be part of the College class. recent or ancient.Create the unit tests for the getters and setters. I simply would like to look at another type of collection. moving other elements to subsequent positions. the first element in the list has a previous element.

one which has two parameters. You said the Section doesn‘t contain a meeting time? Oops. And then declare the data structure. the object is added at the beginning of the collection rather than at the end. use an alternative form of the add method. we need only change it in one place.List. we made an error in our original analysis of the problem and designed a class which omits an important feature. We want only one copy of the Section available so that when we change a meeting time of the Section.An ArrayList is an implementation of the List interface. import java. We will correct this omission in the next chapter. If you wish to add it elsewhere. so none of the code will even compile. * @param s the Section to be added */ public void addSection(Section s) { theSections.util. the collection will expand to hold the extra values. To College. we should. you‘ll see that you have created a data structure with room for 10 elements.add(s). By what amount does it expand? Create a method. whose underlying implementation is an array.theSections = new ArrayList<Section>(). where we create a Meeting class. /** * add a section to the offerings of a course. When you read the documentation describing ArrayList.util. the position (or index) at which the object is to be added and the object itself. The code in the last few pages looks good. private List<Section> theSections. In the constructor. } The online documentation tells us that this method adds the section after already existing elements. If that position is zero. add the import statements import java. Correcting this omission is another example of refactoring. 143 . Do we need to clone the Section when we add it? Yes. which will add a section to the Course. allocate some memory to the data structure this.ArrayList. addSection. but we don‘t have a Section class yet. at the beginning of the list for example. If you add more than 10 elements to the collection.

This gives us another instance variable. So. At my college. for example. and 30. 144 . We have defined Winter as 10. and seminar sections begin with the letter S. plus something to indicate when the section is offered. 20. private String sectionNumber. One possibility is to store W2008. we need to know whether we are dealing with a lecture section. course number. Thus a Section object also needs to contain instance variables defining the semester when it is offered. Let‘s create a unique identifier (a number) instead. numbered 10. But what is ―winter‖? My college uses something similar. the semester beginning 2010 May 1 is 201020. and the semester beginning September 2010 is 201030. and the end time on that day during that semester. The semester beginning 2010 January 1 is 201010. F2008 and S2008 might also be used. There are two aspects to ―when‖. Summer as 20 and Fall as 30. and  The day of the week. the start time on that day. For our reports. We will ensure this by having a Section object contain the subjectAbbreviation and the courseNumber. We will cover the semester in this chapter. We still need the course with which a section is associated.  The semester in which the section is offered. We need to know when and where a Section object meets. the meeting details in the next. even though we use the term ―section number‖ we will not represent it with a number. private int identifier. A section of a course offered this year is different from a section of the course offered last year. That sounds complicated. The combination of subject abbreviation and course number ensures uniqueness for courses so we don‘t need a unique identifier. private String subjectAbbreviation. private int courseNumber. or a seminar section. For sections. lab section numbers begin with the letter L. a lab section. lecture sections will have a numeric section number. one possible unique identifier is subject abbreviation. to indicate the winter semester of 2008. Thus we have the beginning of a Section class.What is a section? What information do we really need to model a Section? We have used unique identifiers for professors (employee numbers) and for students (student numbers). It has three semesters in the year.

We can do that. we used an if statement to display a zero if necessary. private int startMonth. private int startYear. So long as we can remember to increment (increase by one) the value before we display it. recall the problems we had displaying birth dates.DECEMBER?). stored as at least four digits. Another is that the Field Summary portion of the documentation describing Calendar says the values for the months and days of the week are ints and we are using its constants. Thus. and month). with single integers less than 10 displaying with no leading zero. or should that be Calendar. We need to modify the constructor to accept the values of those instance variables and we need setters and getters as well as creating and/or modifying the appropriate unit tests (an exercise left to the reader). The author refuses to evaluate any classes which his students submit without a complete set of unit tests. 145 . Second. When discussing birthdates.MONDAY. Calendar. etc.MAY through Calendar.APRIL). we will be okay. that is. if necessary. also stored as at least four digits. when you display Calendar. you‘ll see zero rather than one. Why did I make these variables ints? One reason is that the values these instance variables will contain are small.AUGUST). or the summer semester (Calendar. We need to add some instance variables to the Section class. the months need to be increased by one before printing.JANUARY through Calendar.JANUARY. we mentioned the Calendar and GregorianCalendar classes. and month) as well as the end date (year. The Calendar class provides us with Calendar. We need to deal with two subtleties in toString. We represent the day of the week (needed in the next chapter) similarly. A section of a course is different when it is offered in the fall semester (At my college that is September through December. As a solution.A better. First. the winter semester (Calendar. private int endMonth.SEPTEMBER through Calendar. But now we know how to use the DecimalFormat class to print that leading zero. Warning – just because unit tests are ―left to the reader‖ doesn‘t mean they are unimportant. We need to modify the toString method so it shows the start and end dates. private int endYear.SUNDAY. But remember that the month and day-of-the-week constants in the Calendar class all begin at zero. more-generally applicable. solution is to remember the start date (year. The Calendar class has some constants representing the months of the year.

when we provide its subject abbreviation and course number.getCourseNumber()) return c.equals( c.getSubjectAbbreviation()) && courseNumber == c. as it does for Professor objects. The following statements form the body of the toString method.format(endMonth + 1) + ')'. a section. or remove. What would the output be if we used result = result + ″ (″ + startYear + '-' + startMonth + 1 + ″ to ″ + endYear + '-' + endMonth + 1 + ')'.DecimalFormat actually lets us solve both problems simultaneously. // details of the section result = identifier + ″ ″ + departmentAbbreviation + courseNumber + ″ ″ + sectionNumber. } // no matching course found return null. with the first one being zero if necessary. we are able to add sections to the courses the college offers. } Using the object returned by this method. DecimalFormat myFormatter = new DecimalFormat(″00″). as when we wish to add. Sometimes we need to retrieve single Course objects. That is.format(startMonth +1) + ″ to ″ + endYear + '-' + myFormatter. String result. int courseNumber) { for (Course c : theCourses) { if (subjectAbbreviation. + ″ (″ + startYear + '-' + myFormatter. public Course getCourse(String subjectAbbreviation. Can you explain why the output is not what you expected? The Singleton pattern revisited The College class is acting as a gatekeeper to the individual Course objects. The pattern we have used (in the constructor) causes two digits to be displayed. we need a method in the College class which returns a Course object. 146 .

or it may determine which of the graduates receive medals or scholarships. The natural order for Strings is alphabetic. employee number. hiring date). name. Of course. For example. so we make sure we compare them first. But what is the natural order for professors . you may want only the month and the day. The Comparable interface is interesting. but that is not a solution to our problem. you may have gone to the online documentation and looked up ―compare‖. by identifier. using the Unicode coding scheme. when sorting a group of people by name. family name is more important than given name which is more important than middle name.org/iso/date_and_time_format for more than you wanted to know about dates. In the context of a college. In the context of a college. or average mark. Let‘s begin by seeing how to compare Professor objects. In all comparisons. there are several orders which matter for students. The international standards for dates. we need to be able to describe how to compare two Course objects. To produce a list of the professors employed by the college in some special order. the year is probably more important than the month which is probably more important than the day. When sorting by date.iso. mentioned earlier (name. we need to be able to compare two Student objects. To produce a list of the courses offered by the college in alphabetical order by subject abbreviation. we must have some way to decide whether one element of the collection precedes another. or perhaps by hiring date? 147 . The closest match is ―Comparable‖. since Comparable only allows one way of sorting. The natural order for numbers is numeric. specified in a compareTo method. year/month/day reflects this view of importance. This one way of sorting is sometimes called the natural ordering for the data. by salary. See http://www. The mark may be for a semester. we need to be able to describe how to compare one professor to another to determine which precedes the other. there are several orders which matter for professors. Comparable Since we have used the word ―compare‖ several times.Listing a collection in order Whenever we talk about listing a collection in order. when you are producing a list of people in order by their birthday. the year may not matter.) We see that we need a technique which allows us to specify several different types of ordering for a class.by name. To produce a list of the students registered at the college. mentioned earlier (by identifier. some values are more important than others. to determine who is on the Dean‘s List or receives scholarships.

pdf. a professor is a person) create a Comparator object. Comparators The Comparator interface allows us to have many compare methods associated with one class.util. hence the term lowercase. When they are not the same. or you could notice that the String class has a compareTo method which returns the same values as a Comparator. We begin by having the Person class (after all. and a positive integer when the first is the larger. the one commonly used in English-speaking countries. When they are the same. hence the term uppercase.org/charts/PDF/U0000.What entry comes immediately after Comparable in the online listing of classes and interfaces? The Comparator interface! This is what we need. To use Comparator objects you need the statement import java. When you look at the Unicode description for the Latin alphabet. You could write this using a series of if statements. you‘ll find that the uppercase letters we need are represented by hexadecimal values between 0041 (the first three digits are the column heading on page 2 of that document) and 005A.Comparator. The logic of an alphabetical comparison is: Compare the family (last) names. The capital letters were kept in the upper part of the storage area. The String class also has a compareToIgnoreCase method which you may choose to use if you wish to ignore the difference between uppercase and lowercase letters. at http://www. compare the middle names. at the beginning of the Person class and any other classes which use them. They are named ―uppercase‖ from the olden days when printers had to make up lines of text by placing individual letters into trays. We have used the terms uppercase and lowercase in previous chapters. zero when their values are equal. All compare methods behave in the same way: they accept two parameters and return a negative integer when the first is less than the second. If the family and given names are the same. you know which is less. Similarly. the other letters were kept in the lower part of the storage area.unicode. All Comparator objects contain a method named compare. Uppercase letters are the capital letters. How are uppercase and lowercase letters stored in a computer? They are all just bit patterns. and the lowercase 148 . compare the given names.

When comparing characters. // compare family names result = p1. if (result == 0){ // family names are the same result = p1. /** * Alphabetic comparison. positive if Person p1 is <. It too should be documented. Character. Person p2) { int result = 0. Within the uppercase (and lowercase) category. =. Any statement about what must be true before a method is invoked is known as a precondition.getLastName()). * Both objects must be Person objects. Fortunately there is a method. Interesting.toUpperCase. and simply subtract the hexadecimal number 0020 from the numeric equivalent of the lowercase character. 0.getMiddleName()). */ public static final Comparator<Person> ALPHABETIC_ORDER = new Comparator<Person>() { public int compare(Person p1.getFirstName(). That is. to do this automatically for us. if (result == 0) // family and first names are the same result = p1. Any statement about what must be true after a method completes its processing is known as a postcondition. } }. compareTo(p2. compareTo(p2. } return result. note that a blank is less than a digit.getLastName().getFirstName()). treat the characters as numbers. and should be documented in the method. given name. which is less than any uppercase letter.getMiddleName(). * or > Person p2 * based on the family name. letters compare in normal alphabetical order. Why would you want to ignore case as you compare names? Perhaps you want to have Von Smitz and von Smitz appear together on the list. How would you change the method to return false if the two objects are not both Person objects? 149 . compareTo(p2. * @return negative. It will not work if this assumption is not valid. which is less than any lowercase letter. and other name. Note that this method assumes both objects being compared are of type Person. But it is easy to convert from a lowercase letter to the corresponding uppercase letter. the uppercase letters have a lower hexadecimal representation than the lowercase letters.letters are represented by hexadecimal values between 0061 and 007A.

Compile the Person. Gee". The test will succeed. That semi-colon must be there as this statement. "Gee". This Comparator is declared to be static. Here is one such test. assertTrue(Person. and Professor classes. is just declaring an object (called ALPHABETIC_ORDER). For this unit test. The first three letters of the given name are the same. How many? Each comparison can have three outcomes. and we can‘t create unit tests for abstract classes. d). "Richard". from the Student class. There may be many Person objects. since it is in an abstract class.ALPHABETIC_ORDER. or 27. a. "Richard D. s2) < 0). There is no need to test the first name when we know that the family names are different. one for each possible path through the comparator. but they all use the same method when comparing two Persons alphabetically. "Rick". "".Particularly note the semi-colon after the final brace. Gee". a. The name of the comparator is capitalised. following the convention that constants (declared using the reserved word final) are capitalised. including null. But some of the tests are unnecessary. "Rick".compare(s1. The digit on the end of it is meant to imply there will be many such tests. alphabetical order translates into ―less than. Student s2 = new Student("125". d). But we note that both Student and Professor are derived from Person. lengthy though it is. so we can place our unit tests in the tests for either of those classes. but the fourth letters are different.‖ Note the name of the unit test. public void testComparator1() { Student s1 = new Student("123". and there are three comparisons. unit tests. The family names of the two students are the same but the given (or first) name of s1 is less than the given name of s2. "Dennis". "Gee". and ―h‖ is less than ―k‖. This is only sensible. and every declaration statement must end with a semi-colon. Unit testing the comparator How do you create a unit test for a comparator? This is particularly difficult with the comparator we have written. Student. "Richard D. Thus there are theoretically three (the number of outcomes per comparison) raised to the power three (the number of comparisons). Thus we need three tests 150 . they could have any value. "Rick". } The variables a and d are the names of Address and MyDate objects. For characters. This means there is only one method with this name (ALPHABETIC_ORDER) within the Person class. there should be many unit tests. To fully test the comparator.

compareToIgnoreCase(name2).getLastName() + „ „ + p2. Thus we only need nine tests.getFirstName() + „ „ + p2. In subsequent sections. When I first wrote that method I did not include the single characters between the parts of the name.getMiddleName(). We need three more to deal with the given name where the family name is the same. This is yet another example that there are often many ways to accomplish the same result. or 81. return name1. In the section which follows. } }. we will see comparators for different classes. thus requiring three raised to the power four.getMiddleName().to deal with the family name. String name2 = p2. But now we need a different implementation since a HashSet is not sorted and cannot be sorted. 151 . If we wish to ignore the case of the names (so that we treat Von Smitz and von Smitz as identical). each of which may have three outcomes. But then I realised that there could be examples in which the space would matter. We need three more to deal with the middle name if the family and given names are the same. Alternative versions of the comparator Note the comment above about the distinction between lowercase and uppercase letters. Producing an alphabetical list of professors How do we combine our knowledge of collections and comparators so that we can produce a list of professors at the college in alphabetical order by name? We find that we have a problem.getFirstName()+ „ „ + p1. Person p2) { String name1 = p1. which will involve four or more comparisons. We have implemented theProfessors as a HashSet because of its speed. we see an alternative form of the comparator. unit tests. public static final Comparator<Person> ALPHABETIC_ORDER_ALTERNATIVE = new Comparator<Person>() { public int compare(Person p1. Consider the two names Pauly Ian Smith and Paul Yian Smith.getLastName() + „ „ + p1. You could also combine the parts of the name into one string and compare those. one which requires only three comparisons and hence only three unit tests. we replace the compareTo methods in the comparator above with compareToIgnoreCase. That gives the following comparator.

The for-each statement. 152 . consider taking a data structures course. the normal follow-up to an introductory programming course. } return result. import java.addAll(theProfessors). Then we create a new method. First. If you want more details. To use a TreeSet requires the following two changes in the College class. String prefix = "". // traverse the Set (in alphabetical order) // and compute a String String result = "". */ public String alphaProfessorList() { // create the TreeSet Set<Professor> alphaProfessors = new TreeSet<Professor>(Person.toString(). for (Professor p: alphaProfessors) { result = result + prefix + p. The addAll method transfers all the elements of the (unordered) HashSet into the (ordered) TreeSet. We will transfer the data from the HashSet to the TreeSet. but we will do the transfer only when we need the data in sorted order. we add an import statement. } The statement that creates the TreeSet indicates what type of objects will be in the set and what comparator is used to compare two such objects. prefix = "\n".ALPHABETIC_ORDER). /** * produce a professor list. in alphabetical order. Once that is complete. alphaProfessors. creating a new set ordered as the Comparator prescribes. How a TreeSet represents its elements in order is of no concern to us right now. the TreeSet. alphaProfessorList.TreeSet.So we choose a different implementation of the Set interface. Most of the time.util. revisited Note that we have again used the for-each statement to visit all the elements in a collection. we leave the set in its unsorted state. we simply need to visit the elements of the TreeSet one after the other and we will visit them in alphabetical order. We are not altering those elements so we do not need an iterator.

} We could use an iterator to process all objects in the collection but this for statement provides a shorthand way of referring to individual elements in the collection. We can run individual methods of these objects. I suggest you become a faithful reader of the Risks Digest. and places them on the Object Bench. This can be useful when we are trying to debug (fix the errors in) an object or class. You are finding and removing the errors in your program. the moth was removed. they found a moth (colloquially called a bug) had become caught in the switch. the memory was switches which actually moved.wikipedia. Many times you will see code which is undocumented. At that time. The ability to read and understand code is crucial in your career as a programmer. Hence.String result = ″″. one of the options on the menu that appears is Test Fixture to Object Bench. 153 .org/wiki/Computer_bug. The story is that one of these switches was behaving erratically. It is available online at http://catless.toString(). Debug is a term that dates back to the beginning of computers. http://en. The reason is to get you reading code and understanding it. what is the purpose of that prefix variable? Sometimes I ask questions without answering them. you are not debugging it.ncl.uk/risks or via email. which we used in the beginning of this course but haven‘t used lately. This creates all the objects you need to run your tests.ac. but you need to understand what it does. the switch was de-bugged. To fix the problem. prefix = ″\n″. String prefix = ″″ for (Professor p:alphaProfessors) { result = result + prefix + p. By the way. In any case. When you right-click a unit test on your class diagram. Having errors in your program is not funny! To get an idea of the problems that errors cause. When someone went inside the computer (Yes. Wikipedia points out the previous history of the term and notes there is some question about this story. I prefer not to use the word debug as it has somewhat humorous connotations. BlueJ revisited This may be an appropriate point to mention the Test Fixture to Object Bench menu option. independent of the unit tests. That link provides a link to subscribe. they were very large!) to check out why.

we need a second Comparator. 0. but it has its problems. To facilitate this. Person p2) { return (p1. either. This Comparator. compareTo(p2. is much simpler than the first one we created. 1 if Person p1 is <. * @return -1. or I wouldn‘t ask the question! Passing a Comparator to a method Did I hear you say ―Why can‘t we just have one professor list method and tell it which Comparator to use?‖ You can. Perhaps the largest and most expensive was the spaceship that crashed into the Martian surface due to confusion between metric and imperial measurements. and now that error is in two places. * @param theComparator The Comparator to use in sorting * the employees 154 . } }. or > Person p2 * based on the identifier */ public static final Comparator<Person> NUMERIC_ORDER = new Comparator<Person>() { public int compare(Person p1. You will probably consider copying and modifying alphaProfessorList to create numericProfessorList. in the Person class of courses. the code you copy may contain an error. and another unit test. /** * numeric comparison. its people. since this time we are comparing only the identifier values. That would be the easy way. =. Sometimes it is more appropriate to have a list of employees ordered by identifier (employee number) rather than by name.getIdentifier(). in the order specified * by the Comparator. Producing a professor list in numeric order But let‘s go back to the problem of modelling a college. You may forget to make a change in the copy. Can we avoid having the same code in two places? Of course we can. and its courses. Or. /** * produce an employee list. and you should.The errors are not just small. You will probably consider doing the same for the unit test.getIdentifier())). for example. another method in College. even worse.

println( s. perhaps you can do so now. c. // traverse the Set // and compute a String String result = ″″. Show Terminal so there is a place on the screen to display the class list. ordered.addProfessor(professor2).addProfessor(professor3).*/ public String professorList(Comparator<Person> theComparator) { // create the TreeSet Set<Professor> ordered = new TreeSet<Professor>(theComparator). System. for (Professor p: ordered) { if (needsReturn) result = result + „\n‟. public void testAlphaProfessorList1() { College c = College. } Remember to use View. A unit test for the alphabetic Comparator could look like this. c. 155 .ALPHABETIC_ORDER)). } return result.util.getInstance(). c.out. // create some professors (code not shown // here) // and remember them c. The coding in the method above is slightly different from that in alphaProfessorList. Have you found out that you can display the terminal window after putting something in it? The output will still be available. If you didn‘t figure out the use of the variable prefix in the previous version. Boolean needsReturn = false.toString() + '\n'.Comparator.addProfessor(professor1). result = result + p. needsReturn = true.professorList(Person. Once again we see that there are many ways to accomplish the same task.addProfessor(professor4). } Don‘t forget import java.addAll(theProfessors).

* @param s Student object to be added * */ public void addStudent(Student s) { theStudents. We need to add a student‘s identifier to the collection. this method works.The unit test for the numeric Comparator would be the same. so that we only have one instance of a Student object for each student (in the theStudents collection in College) and we gain access to that instance by providing the only instance of the College class with the student number. In our implementation. Thus we need the following statements. Registering students in sections A section contains students. There is no compelling reason for one over the other. sections do not contain Student objects. If we have a Student object. 156 .theStudents. and over. Sometimes we may have the identifier. That is the English description. and it comes down … set.add(s. /** * add a Student object to the section. That allows us to have a second addStudent method. Up. So we are able to remove the alphaProfessorList and numericProfessorList methods from College. replacing ALPHABETIC_ORDER with NUMERIC_ORDER. } Sometimes we may have the Student object to be added to the collection in a Section object. In the clone method we need s. we need to decide the type of the collection we will use. they contain student identifiers. There it goes. we need this. Flip a coin.theStudents). We can use either a set or a list.theStudents = new HashSet<String>(). We designed them that way. and up. private Set<String> theStudents. over.getIdentifier()).addAll(this. In the constructor. How do we create the collection of students in a section? First. and to remove their unit tests from CollegeTest.

return the student object. which provides one Student object at a time. but only when we need the data in sorted order. We have implemented a set as a HashSet because of its speed./** * add a Student object to the section. /** * @return collection of Student objects. */ public Set<Student> getStudents() { return theStudents. Most of the time. A much better way to accomplish a similar task is to give everyone access to an iterator. Instead. Producing an alphabetic class list How do we combine all our knowledge of collections so that we can produce a list of students in a Section. } But this is not a good method since it gives everyone access to all the elements in the collection. Recall that the Section collection contains student numbers. As we did before. Make it so. we choose the TreeSet.getIdentifier())) { return s. But now we need a different implementation since a HashSet is not sorted. * @param sn the student identifier to be added */ public void addStudent(String sn) { theStudents. creating a new set ordered as described by a Comparator. /** * given a student number. 157 . we must retrieve the corresponding object from the College collection of students. Once we extract an element from that collection. we will transfer the data from the HashSet to the TreeSet. the same problem we found earlier. Here‘s a method to do that.equals(s. we leave the set in its unsorted state. This calls for a getStudent method within the College class. } Soon we will need to access all the students in the collection. * @param a student number */ public Student getStudent(String identifier) { for (Student s:theStudents) { if (identifier.add(sn). in alphabetical order by name? We find that we have a problem.

revisited Note that we have again used the for-each statement. Then we create a new method. retrieve the Student objects // and arrange them in alphabetic order for (String sn:theStudents) { orderedStudents. needsReturn = true. // create the TreeSet Set<Student> orderedStudents = new TreeSet<Student>( Person.getInstance(). twice in fact. // for all student identifiers in the // section. Once we have visited all elements. } The statement that creates the TreeSet indicates what type of objects will be in the set and which comparator is used to compare two such objects. } To use a TreeSet requires two changes in the Section class.getFullName(). } // traverse the Set and compute a String String result = "".ALPHABETIC_ORDER). thus ordering them alphabetically. we add an import statement.} } return null. import java. public String alphaClasslist() { College c = College. boolean needsReturn = false. we ask the college Singleton to give us the appropriate Student object. to visit all the elements in a collection. representing the students who are registered in this section. we simply need to visit the elements of the TreeSet one after the other and we will visit them in alphabetical order. 158 . The for-each statement.add(c. alphaClassList. For each.TreeSet. for (Student st:orderedStudents) { if (needsReturn) result = result + '\n'. First. } return result. We visit each element of the collection of student numbers.getStudent(sn)).getIdentifier() + „\t‟ + st.util. result = result + st. We insert each into the TreeSet.

The first time. we can provide a comparator as a parameter to a method.getIdentifier(). or > Person p2 * based on the identifier */ public static final Comparator<Person> NUMERIC_ORDER = new Comparator<Person>() { public int compare(Person p1.getIdentifier())). for (String st:orderedStudents) { if (needsReturn) result = result + '\n'. Create unit tests for both comparators. } }.getFullName(). result = result + st. Producing a class list in numeric order Sometimes it is more appropriate to have a class list of students in a section. ordered by student number rather than by name. 1 if Person p1 is <. and so that it accepts a Comparator as a parameter. Person p2) { return (p1. } Then we visit all the elements in the orderedStudents collection. } We could use an iterator to process all objects in the collection but this for statement provides a shorthand way of referring to individual elements in the collection.getStudent(sn)). compareTo(p2.add(c. needsReturn = true. since we are comparing only the identifier values. This Comparator is much simpler than the first one we created.getIdentifier + '\t' + st. Modify alphaClassList so its name is simply classList. * @return -1. As we saw earlier. we visit the elements in the theStudents collection. =. for (Student sn:theStudents) { orderedStudents. String result = ″″. 0. 159 . /** * numeric comparison.

we are able to see how to model a college in much more detail. we can focus on the daily meetings of the class. the start time.Students enrol in sections Now that we have created a Section object which contains a collection of students (that is. we can model the association between Student and Section where a student registers in a section of a course. The challenges of producing a schedule will introduce us to the complexities and fun of string manipulation. Summary Now that a section knows the semester in which it is taught. The other side of the association is that a Section knows which students are registered in it by maintaining a collection of student identifiers. and the end time. 160 . the details of which include a room number. a collection of student identifiers). We can model that by having a Student object contain a collection of section identifiers. In particular. We will do that in the following chapter. Make it so.

a Professor object needs a collection of the subject abbreviations and course numbers of previously-taught courses. 3. we discussed modelling the sightings a birder makes. we discussed modelling playing cards. a Student object needs a collection of the section identifiers of the sections in which he/she is currently enrolled. In what order should the transactions be stored? Why do you suggest that order? How would you implement that? 5. 2. In what order should the playing cards be stored in a collection? 161 . How can that report show when the professor taught the sections? 4. That is. That is. usually in one section of each. A professor teaches many sections in a semester. Each Student object should be able to produce a currentEnrollment report listing all these sections. In a previous chapter. we discussed modelling a bank account. A student enrols in many courses. model that. In what order should the sightings be recorded? Why do you suggest that order? Note that a birder will sometimes wish to have a list in order by species and sometimes in order by date and time. a Professor object needs a collection of the section identifiers of the sections he/she currently teaches. Model that. That is. Each Professor object should be able to produce a previouslyTaught report listing all these courses. model that. with a collection of transactions. How do those ideas affect your earlier answer? 6. Each Professor object should be able to produce a currentTeachingLoad report listing all these sections. In a previous chapter. A professor who has been at the college for more than one semester has a history of the courses which he/she has taught. Using the techniques from this chapter. Using the techniques from this chapter.Exercises 1. in a semester. In a previous chapter. Sometimes a birder will only want sightings for a particular time period.

162 .Why do you suggest that order? 7. Explore the DecimalFormat class to see what other capabilities it contains.

and the days and times within the semester. we will call that a meeting. Thus the values range from 0000 to 2359 and the corresponding instance variables will be integers. we mentioned that we wish to model when a Section is offered and we mentioned there are two aspects to ―when‖. part 3 Learning objectives By the end of this chapter you will be able to:     Produce reports from collections Describe the characteristics of the StringBuffer class. The Meeting class Whenever a section occurs.Chapter 9 – Collections. We will indicate the date and time of each meeting. Thus. We changed that to three 40-minute blocks. along with the location (room number) of the meeting. This is an example of a course meeting several times in one day. the semester (which we have modelled by providing start and end dates). We must make sure we do not make that impossible. We will use a 24-hour clock to represent the start and end times. the corresponding instance variables will be integers. we will assume the room number of the meeting is simply a String. each separated with a 10-minute recess. We begin this chapter by modelling the days and times within the semester. including how it differs from String Use and manipulate the contents of a StringBuffer Describe and illustrate the difference between aggregation and composition Introduction In the previous chapter. Can a section meet twice on the same day? That would be unusual. The section in which this book was first used originally met in a 120-minute block. but it is possible. To simplify this model a little. A Section object will contain a collection of Meeting objects. We will use the constants from the Calendar class to represent the days of the week. followed by a recess. 163 .

In the first case. a duration of 50 minutes. and 955 / 100 is 9. Behaviours And what are the behaviours of a Meeting object? Aside from the obvious getters and setters. use the modulus operator (represented by %). you can subtract the start time from the end time and calculate the length immediately. An object has identity. The first statement uses division (division is represented by the /. it may be useful to have a method that computes the duration of a meeting in minutes. How do you separate a number like 0830 into its hours (08) and its minutes (30)? Probably the easiest way is as follows. the remainder when you divide 830 by 100 is 30.Instance variables Since a section meets many times a week. 830 % 100 is 30. what are its instance variables and how do they receive their values? private int dayOfWeek. int startMinutes = startTime % 100. this one called Meeting. and a Section object should contain a collection of Meeting objects. When you divide an integer by an integer. the result is an integer. A meeting may begin at 1000 and end at 1050. In each of those statements we declare a variable and give it a value at the same time. What is the state of a Meeting object? That is. private int startTime. but you cannot do this in the second case. state. any remainder in the division is dropped and no rounding takes place. private int endTime. 164 . we should create another class. 830 / 100 is 8. How do you calculate the length of a meeting? Time arithmetic There are many ways to calculate the duration of a meeting. Identity is the name of the object. and we create the name through a declaration statement. and behaviour. but all require you to have both the minutes and hours of both the beginning and ending times available. or slash) to isolate the hours. For example. private String roomNumber. int startHours = startTime / 100. That is. as we have already seen many times. also a duration of 50 minutes. 1050 / 100 is 10. 1020 / 100 is 10. To determine the remainder discarded in the integer division. so there is no problem there. But it may begin at 0830 and end at 0920.

int endMinutes = endTime % 100. the remainder when you divide 955 by 100 is 55. we will calculate an incorrect value for the duration of the meeting. due to sloppy input handling. Note that these calculations assume there are no errors (intentional or otherwise) in the times provided. but we can‘t do that right now. If a meeting runs from 1130 to 1220. Thus the first saved result is multiplied by 60 and the result of that calculation is added to the second saved result. the calculation computes (12 – 11) * 60 + (20 – 30). some calculations must be done before others. or 80 minutes. We will eventually modify the class to prevent bad data being provided. Similarly. garbage out. int endHours = endTime / 100.‖ For example. Once you have the hour and minute when the meeting begins and ends.startMinutes). in minutes. we don‘t know how to throw exceptions. it is a simple matter to calculate its duration. There is an expression ―Garbage in. It may have a start time of 1200 and an end time of 1030. That is. when a meeting runs from 0830 to 0950. 955 % 100 is 55.1020 % 100 is 20. we can calculate when the meeting ends. but only after the multiplication and division operations had been completed. the calculation computes (9 – 8) * 60 + (50 – 30) or 1 * 60 + 20. the remainder when you divide 1020 by 100 is 20. they would be evaluated left to right as well. the remainder when you divide 1050 by 100 is 50. In our case. you need to know that multiplication (indicated by an asterisk. or 1 * 60 + (– 10). 165 . Remember that the modulus operator is used only when you are doing integer division. In both cases. or 60 + (-10). 1050 % 100 is 50. or 60 + 20. Subtraction and addition have the same priority so are done left to right. It involves the idea that some calculations have priority over others. Parentheses indicate that the calculations within the parentheses should be done before any other calculations. To decide what is done with those results. This is one of the more complicated arithmetic calculations we have seen.startHours) * 60 + (endMinutes . *) has a higher priority than addition. Should a calculation use more than one multiplication operation. So too would division and so too would a mix of multiplication and division operations. return (endHours . For example. there are two parenthesised calculations which are done (the two subtractions) and the results saved in temporary storage. More-complicated calculations could use more than one addition operation. or 50 minutes. a meeting may have a start time of 3456 and an end time of 6578. they would be evaluated from left to right.

But a TreeSet is ordered and we will often want to retrieve the Meeting objects in order. or if something * is different between the two Meetings */ public boolean equals(Object o) { boolean result = false.endTime == m. Why? A Set does not allow duplicates.dayOfWeek == m. That one is easy.getDayOfWeek()) && (this. Many religious groups and calendars from Europe seem to have it right. result = (this. They are the same when they take place in the same room on the same day at the same time. (And we need an equals method for Meeting objects. for example) and the ArrayList implementation. What type of collection should we use? We have seen a List (of section identifiers added to a Course object.getEndTime()). regardless of the room. Why is that the normal order. and two meetings of a section cannot occur at the same time. we need to specify a Comparator<Meeting> which describes how to compare one Meeting object to another. equals(m. We have seen a Set (of student identifiers representing students in a section) and we have seen two implementations (HashSet and TreeSet.getStartTime()) && (this. But which implementation should we choose? Either implementation might work. you‘ll find there are other types of collections as well. For now. 166 . and room match * @return false if not both Meetings. times. In fact. following the normal North American week. you could argue they are the same if the day and time match. we will produce a schedule showing when each section of each course is offered.) When you check the online documentation. The individual meetings will be in order from Sunday through Saturday. Since we are going to use a TreeSet.roomNumber. though. I think a TreeSet is the most appropriate implementation to choose.Section uses Meeting Now that we have a Meeting class. In particular. when Saturday and Sunday form the weekend? An ―end‖ implies it is after something.startTime == m. if (o instanceof Meeting){ Meeting m = (Meeting) o. with the week beginning on Monday and ending on Sunday. Thus that is a suitable collection.) /** * is one meeting equal to another? * @return true if day.getRoomNumber())) && (this. we can attach a collection of Meeting objects to a Section object.

getDayOfWeek(). else { // both on same day of the week int s1 = m1. but that would be silly. // compare day of week if (d1 < d2) // m1 is earlier in the week result = -1. } Note that we need to use the equals method with the roomNumber. the first is less.  If both are on the same day of the week and have the same start time. using the ―and‖ operation (&&). start time. here is my Comparator<Meeting>. I suppose you could use the hashcode method to determine the hashcodes for each String and then compare the hashcodes using ==. then the meeting which ends first is less. Meeting m2) { int result = 0. in this case a String. Based on that understanding. start time.  If both are on the same day of the week. 1 if Meeting m1 is <. and end time are all the same. 167 .} return result.getStartTime(). On to the comparator. /** * which meeting is less? * @return -1. the one with the earlier start time is less. since it is an Object. 0. you can convert an int to an Integer. We combine four boolean values. If you don‘t like using both equals and ==. we use == with the day of week and the times. that is. Just because there are many ways to accomplish the same task. int d1 = m1. But that makes code that is overly complicated and hard to read. room number.  When the first is on an earlier day of the week than the second. The only time this combination will evaluate to true is when all four boolean values are true. What does it mean that one meeting is less than another? Here is my understanding. or > Meeting m2 * based on the day of week. when the day. and end time */ public static final Comparator<Meeting> TIME_ORDER = new Comparator<Meeting>() { public int compare(Meeting m1. they are not all sensible.getDayOfWeek(). =. and then use its equals method. else if (d1 > d2) // m2 is later in the week result = +1. since they are primitive datatypes. int d2 = m2.

The reason is that all the values we are examining are primitive datatypes. so an if within an if does not need braces. But an if statement is not a compound statement. This comparator is longer than the others we have seen. Many languages included special features to allow this. although you may wish to use them to increase clarity. same start time int e1 = m1. programmers were considered better when they could write shorter methods to accomplish a task. else if (s1 > s2) result = +1. We must use the less than (<) and greater than (>) operators instead. however. if (s1 < s2) result = -1. Java still includes one. For example. Thus we cannot use the compareTo method we have used with Objects. explore its use on your own. The if statement. else { // same day. if (condition) Statement to do when the condition is true else Statement to do when the condition is false The ―statement to do‖ needs to be enclosed in braces when it is a compound statement. revisited This Comparator contains several if statements. If you really want to use the conditional operator.getEndTime().getStartTime().getEndTime(). The basic structure of an if statement is as follows. // end TIME_ORDER }. the question mark (?). I prefer not to use it. } // compare end times } // compare start time return result. else result = 0. if (e1 < e2) result = -1. In the old days. 168 . else if (e1 > e2) result = +1. int e2 = m2. containing several other statements. the use of the conditional operator. I feel that clarity is reduced by the use of that operator. nested within each other. two assignment statements make a compound statement. }.int s2 = m2. and would need to be enclosed in braces.

this. without knowing the actual times the section will meet.Thus some of the else clauses in the Comparator do not need braces (because the ―statement to do‖ is a simple statement. Note that the Checkstyle extension we are using expects braces even if there is a single statement in the body of the if or the else. Consider the following badly-indented statements.TIME_ORDER). if (percentage > 90) grade = “A”. if (percentage > 90) grade = “A”. else grade = “F”. Despite that. else grade = “F”. 169 . so none of the if clauses in this example need braces because they all contain a simple statement. But sections are often planned and created. Consider the following statements. I have not modified my constructor other than to create an empty collection of meetings. Creating the collection of Meeting objects How does a Section create its TreeSet of Meeting objects? You might be inclined to add the Meeting objects to the constructor.theMeetings = new TreeSet<Meeting>(Meeting. setting the variable result to an appropriate value. Perhaps it is better to always use braces. Thus. Indentation does not do that and can imply associations which do not exist. The third assignment statement will be executed regardless of which path your program takes through the if statement. Note that the braces help tell which else is associated with which if.) Some do need braces because the ―statement to do‖ combines several assignment statements and another if. so you eliminate this ―does it or does it not‖ questioning. or is another if statement. message = “with distinction”. This will not compile since there are two statements following the if which are not enclosed in braces. private Set<Meeting> theMeetings. the rules of the Java language are well-defined. message = “with distinction”.

Wednesday. One solution is to simply remove the old meeting and replace it with a new. Assume a section meets on Monday. We have three separate Meeting objects. I have created a new method addMeeting. and Friday. from 1030 to 1120 each day.add(m2). * @param m1 the meeting to be changed * @param m2 the replacement meeting */ public void changeMeeting(Meeting m1. how do you produce a neat summary of the meeting times? We‘ll do that in a method named meetingsList. theMeetings. We wish to combine the information from these objects into a single String that reads M W F 1030 1120 XXX where XXX is the room number.To add a meeting to the collection. Meeting m2) { theMeetings. } How do you change the time of a meeting? Changing the time of a meeting may seem difficult. } How do you remove a meeting from the collection? /** * remove a Meeting object from the section. */ public void addMeeting(Meeting m) { theMeetings. * @param m the meeting to be removed. one for each day. in the same room. perhaps your college or university uses a different format. 170 .remove(m1). /** * add a meeting time.contains(m)) theMeetings. */ public void removeMeeting(Meeting m) { if (theMeetings.add(m). This is the format used at Okanagan College. } It could be even easier by using the setters of the Meeting class. Section uses Meeting – displaying the times Now we proceed to the challenging part. Explore that possibility. /** * change the time of a meeting. but it is actually easy.remove(m). assuming all three meetings are in the same room.

You should be thinking that a first step is to be able to extract individual Meeting objects from the collection. and the one after 1120. meeting at a different time (or in a different room). We will be writing a method which will create all the lines of output. Why? Remember that the smallest non-negative integer is zero. I once almost had a class that met three times a week in a different room each day. we can use an array. We have seen the idea of an array mentioned when we first saw the ArrayList class. We don‘t know in advance how many lines of output (Strings) we will need.) These spaces represent missing information (the one after M. to some degree. one after 1030. when you have an array containing five elements. At the end of the method. it made sense to start numbering at zero. since we are using the TreeSet implementation and our comparator. the one after 1030. the second has index one. This is the same zero-based numbering we found in the Calendar class. though. in which individual elements are referred to by means of an index. we can combine the (maximum) five Strings into one and return it. and two meetings on the same day will be in order by starting time. There is a tried-andtrue collection type we can use. when classes meet at the same time on different days. Often that forces us into using a collection. But not always. depending on how many different times or rooms are used. There may be two or more separate lines. once in one room and twice in a different room. the first one has index zero. When the section meets at different times on the three days. Sunday (represented by the number zero) through Saturday (represented by the number six). 171 . and it permeates computing. when memory really mattered and machines were slow. The schedule will be two lines. Recently I have had classes that meet three times a week. That is. three after F. Should a section meet five times a week. since we know that the size of the collection is small. and one after 1120. Using any of them is. they usually meet in the same rooms. but at my college. and the first two after F) and whitespace to make the output clearer (the third one after F. then we wish to produce separate lines of output. Back in the old days. a matter of overkill. or in different rooms.) I don‘t know about your school. This time. we can determine an upper bound providing we assume no section meets more than five times a week. Note that these objects will be returned according to the days of the week.Note the spaces (one after M. one after W. which will expand as needed. we might need five lines of output. and the fifth has index four. An array is a collection of data items. the one after W. Arrays So what type of collection should we use to store five Strings? The collections we have seen all can vary in size.

But a String won‘t allow this insertion. result = result + '\n' + title + '\n' + description. but nothing is referring to it.format(laboratoryHours) result = result + '. but the length and content of the sequence can be changed through certain method calls. a process called ―garbage collection‖ will be used to identify the memory which is not referred to.format(hours). How about a StringBuffer? StringBuffer The online documentation states that a StringBuffer is a ―…mutable sequence of characters. That means that once it is given a value. we use the value of result to create another variable. Note that all the changes we made involved adding characters to the end of an existing value. A StringBuffer is like a String. While summarizing meeting times. we did. But wait.‖ That‘s what we want. At some later time. result = result + ″ (″ result = result + myFormatter. } Every time we add one string to the end of another we appear to be changing the value of result. When we perform those statements in the method above. double totalHours.So perhaps we should create an array of String objects. didn‘t we say in an earlier chapter that a String is immutable? Yes. The original value is left in memory. 172 . perhaps modifying the String (by inserting new characters. result = departmentAbbreviation + ″ ″ + courseNumber. for example a slightly-modified version of the toString method in the Course class. it can‘t be given a new value.format(lectureHours) result = result + '. We then have result refer to that new variable. and return it to the pool of available memory. but we do by being wasteful of memory. We need something like a String but which one allows us to modify it.' + myFormatter. String result. Haven‘t we created a string by concatenating a number of values together? Haven‘t we done that in a series of statements? Consider. You may be wondering a little about right now.' + myFormatter. I‘m thinking of a process in which we construct a String as we read meeting details. totalHours = lectureHours + laboratoryHours + seminarHours. or changing existing ones) when we read a different meeting detail. but can be modified. return result. True.#″). public String toString() { DecimalFormat myFormatter = new DecimalFormat(″#. At any point in time it contains some particular sequence of characters. result = result + ″-″ + credits + ″-″ result = result + myFormatter.format(seminarHours) result = result + ')'.

In fact. to 5%! And now (summer 2010) the two rates are being combined into one. the four digit start time. Then the federal rate dropped to 0. and the federal (national) rate was also 0. // assumption . Now we need an array which we can use to access the individual StringBuffers. What if you ever have to change the number? Will you remember that every five is the same or do some mean something else? In Canada. other values we have considered (the subject abbreviation and the course number) may be different for other colleges too.no more than five meetings a week StringBuffer temp[] = new StringBuffer[5]. four characters).07. We‘ll use StringBuffers here and leave StringBuilders as an exercise. 173 . a space (to make the result more readable). I am thinking we should create five StringBuffers. The length of a room number may vary for a different college. we have used the number five twice already (and the word five once.06. Let‘s continue with the creation of meetingsList. Thus each StringBuffer needs to contain 18 characters (seven plus one plus four plus one plus four plus one) plus the length of a room number (in the case of my college. and use it instead. for a while we had two different sales taxes.) And then the federal rate changed again. StringBuilder. Then we need to initialize each element of the array to a string of 22 blanks. and create a constant. For that matter. for (row = 0. The provincial rate where I live was 0. the four-digit end time. row++) temp[row] = new StringBuffer(″ ″). int row = 0.07 and see whether it was the provincial rate (which didn‘t change) or the federal rate (which did.) It is better to avoid such use. Imagine how many programmers had to look at each use of 0. classes may occur on Saturday and Sunday). Adjusting to different colleges But look.07. which might be even better. a space (to make the result more readable). when you read the documentation on StringBuffer you‘ll find that the most recent versions of Java have included a new class. a total of 22 characters. There are 22 spaces (blanks) between the quotation marks in the last statement. and the room number for the meeting. each of which will contain seven characters representing the days of the week (yes. row < 5. as shown in the example above. a space (to make the result more readable).

getInstance(). we will explore how to use resource bundles to customise these values for different colleges. private final int ROOM_NUMBER_LENGTH = 4. } public int getDeptAbbreviationLength() { return DEPT_ABBREVIATION_LENGTH.getMaxMeetingsPerWeek(). Here are the additions to the College class. private final int MEETING_END_TIME_LENGTH = 4. 174 . I would suggest we place these limits in the College class. Since long sequences of capital (uppercase) letters are hard to read. In an exercise at the end of this chapter.While we are thinking about avoiding repetition of numbers. where? Since they are college-wide limits. we can use getters as we have with all our classes. let‘s deal with the other constants we have. } public int getMeetingStartTimeLength() { return MEETING_START_TIME_LENGTH. } Of course the instance variables are private. their names are capitalised.no more than maxMeetings meetings a week College c = College. with comments omitted to save trees. the length of a subject abbreviation. private final int MEETING_START_TIME_LENGTH = 4. // assumption . We mentioned the length of the start and end time of a meeting. } public int getMeetingEndTimeLength() { return MEETING_END_TIME_LENGTH. Now we can retrieve these constants wherever appropriate. public int getMaxMeetingsPerWeek() { return MAX_MEETINGS_PER_WEEK. Can we define those lengths as constants? If so. the length of a course number. private final int DEPT_ABBREVIATION_LENGTH = 4. Since we have only one instance of the College class. which we know they are since they are declared to be final. spaces within the names are replaced with underscore characters. // college-wide constants private final int MAX_MEETINGS_PER_WEEK = 5. int maxMeetings = c. As constants. and the length of a room number. } public int getRoomNumberLength() { return ROOM_NUMBER_LENGTH.

in our case. // each element of the array is empty // create an array of StringBuffers of the correct length.getRoomNumberLength().getMeetingEndTimeLength() + 1 + c. for (Meeting mt: theMeetings) { // do something } 175 . j in the second) to the value specified after the first equals sign. perform the statements in the body of the loop. j++) { temp[row]. j < lengthNeeded in the second).  When the continuation condition is not met.StringBuffer temp[] = new StringBuffer[maxMeetings]. j < lengthNeeded. Another for loop What‘s this for loop we have been using? It looks something like the for-each loops we‘ve seen when processing collections but it‘s different. Then increase the counter as shown (increment by one). row < maxMeetings. some of the blanks will be // replaced later int lengthNeeded = 7 + 1 + c.  Check that the continuation condition is met (row < maxMeetings in the first loop. this for loop is controlled by a counter. for now and for the future. " "). 1. the loop is finished. for (int j = 0. 3. Thus row takes on the values of 0. for (int row = 0. Processing all the meetings Now we need a way to visit all the Meeting objects and place them into the appropriate StringBuffer. // containing blanks. Rather than looping over all the elements in a collection.getMeetingStartTimeLength() + 1 + c. and loop back to the check. A for-each loop is good in this situation. 4 and each corresponding element in the array is set to. row++) { temp[row] = new StringBuffer(lengthNeeded). usually zero.insert(j. 2.  Whenever the continuation condition is met. } } The array is created properly. 22 spaces. The logic here is:  Initialize the counter (row in the first loop. for the current college standards and for future standards.

you can replace the comment // do something with the following.replace(8. we are replacing four blanks in the StringBuffer with the values returned by the Meeting getters. the start and end times. boolean variables! boolean first = true.Manipulating StringBuffers Placing data in StringBuffers The last snippet of code said we need to ―do something‖ as we process each meeting.getEndTime()). we need to place its details into the first StringBuffer. When there is no match to any of the existing StringBuffers. temp[0]. and the room number for the meeting).replace(13. and the room number. we need to store the day of the week. mt. We indicate which characters to replace by giving the index of the first one to be replaced. } else // do something different } From the description of the output we‘d like to create (seven characters for the days of the week. we need to modify the matching StringBuffer to indicate a meeting on a different day. so the syntax we need is the name of the object. 21. we need to compare its details to the details already in the array of StringBuffers. a space. StringBuffers are objects.getRoomNumber()). followed by a period and the name of the method we want to invoke. the four-digit end time. 16. What is the something we need to do? For the first Meeting object. for (Meeting mt: theMeetings) { if (first) { // do something first = false. how do we know we are not dealing with the first Meeting object? In answering those two questions. mt. How do we know we are dealing with the first Meeting object? Alternatively. temp[0].replace(18. and the index of the last one to be replaced. In these cases. 11. temp[0]. the four-digit start time. when there is a match of room and times. a space. mt. a space. followed by the parameters of that method. we need to begin building a new StringBuffer in the appropriate format. 176 . For each subsequent Meeting object. Right.getStartTime()). you begin to review the datatypes you know to find one that takes on only two values.

mt.1. p3b.getMeetingEndTimeLength() .getStartTime())). Thus the first digit of the start time will be position eight.getStartTime()). and the length of the room number. but early morning times will be only three.getRoomNumber()). p1b.text. uses it. The lines above will work. 18.replace(p2a.replace(p3a. mt.format(mt. roomNumber is already a four-character string.DecimalFormat library) to ensure the times are all four digits in length. The number eight is calculated as one more than the number of days in the week. myFormatter. myFormatter. We are expecting the times to be four digits. 177 .getEndTime())). Position seven will be occupied by a space. int p3b = p3a + c. Thus when we place the times and room number into the array element. p1b. We should calculate those numbers so they reflect differences between colleges. (If we had stored the times as Strings we would not have this problem but would probably have others.1.replace(p1a. int p2b = p2a + c. int p2a = p1b + 2. temp[0]. temp[0]. creates the DecimalFormat object and temp[0]. DecimalFormat myFormatter = new DecimalFormat(″0000″).getMeetingStartTimeLength() .getEndTime()). and 21 are calculated on the basis of the lengths of the start and end times of a meeting. 13. Remember that the first position in the StringBuffer is position zero.But the numbers 11. temp[0].) We will use DecimalFormat (from the java. Thus the abbreviations for the days of the week will be in positions zero through six. p2b. int p1b = p1a + c. p2b. // p1a is the location of the first digit of start time // p1b is the location of the last digit of start time // p2a ditto for end time // p2b ditto for end time // p3a ditto for room number // p3b ditto for room number int p1a = 8. In particular. temp[0].getRoomNumberLength() .format(mt. we should use these statements.replace(p1a. mt.replace(p2a.1 . 16. int p3a = p2b + 2. we would need to ensure that all times contained the same number of characters. Recall that getStartTime and getEndTime both return ints. but they don‘t give the correct result.

where one piece of code is very closely involved with another piece of code. replace works with Strings. so we need a way of converting this to the appropriate character representation of the day of the week. The week begins with Monday.getDayOfWeek())). and temp[0]. in this case by knowing and using the internal details of that other piece of code. What would be the abbreviations for the days.Converting numbers to day of the week What about the day of the week? mt. Should that implementation change. This is an example of coupling.com/library/fare/blfare109a. You provide the position within a String and charAt provides the character at that position. This is a situation we would normally avoid.getDayOfTheWeek returns an integer.getDayOfWeek().about. Note that this relies very heavily on the idea that the Calendar class uses the numbers zero through six to represent the days of the week. and how would they be provided? For example. We have used R to represent Thursday (eliminating confusion with the T representing Tuesday) and A to represent Saturday (eliminating confusion with the S representing Sunday). we may wish to consider what would happen if the college we are modelling were in an area where English is not the spoken language.setCharAt(mt. will place it in the appropriate element of the first row in the array. The String class provides a method called charAt. Since we have mentioned resource bundles and customization. dayAbbreviations. our program will cease working.getDayOfWeek())).htm says ―The days of the week (i giorni della settimana) are not capitalized in Italian. Suppose we have String dayAbbreviations = ″SMTWRFA″. setCharAt works with individual chars. Then dayAbbreviations.charAt(mt. the website http://italian. will extract the appropriate day letter.charAt(mt. lunedì—Monday martedì—Tuesday mercoledì—Wednesday giovedì—Thursday venerdì—Friday 178 .

row < maxMeetings. How many rows have we generated? Well. We should remember that.getMaxMeetingsPerWeek(). /** * produce a list of meeting times */ public String meetingsList() { College c = College.getRoomNumberLength(). Should it not find one. Note that rowsGenerated is also the number of the next row which we might generate. then it needs to create another row.getMeetingStartTimeLength() + 1 + c. for (int row = 0. we have one so far.no more than maxMeetings meetings // per week StringBuffer temp[] = new StringBuffer[maxMeetings].getMeetingEndTimeLength() + 1 + c. rowsGenerated = 1. and room) to update. row++){ 179 .sabato—Saturday domenica—Sunday‖ What are appropriate abbreviations for Tuesday and Wednesday? Processing second and subsequent meetings What happens as we process subsequent meetings? Rather than developing a mammoth method. seeking ones (with the same start and end times. A lot of code Now we have an idea of what we need to do to deal with all the Meeting objects.getInstance(). and give it a value after the first row has been generated. // assumption . // containing blanks // some of the blanks will be replaced later int lengthNeeded = 7 + 1 + c. int maxMeetings = c. Take a deep breath as there is a lot of code in the following method. This is because the array indexes start at zero. Declare a variable before the loop begins int rowsGenerated = 0. // create an array of Strings of the correct length. we are developing code snippets that we will combine to create a method which will scan through all generated rows.

so we don‟t need // to extract the same field several times String st = myFormatter. j++) { temp[row].replace(p1a. p3b.1. temp[0]. String rt = new String(mt.format(mt. // abbreviations for days of the week String dayAbbreviations = "SMTWRFA".setCharAt(dt1.replace(p3a. // days in the week plus 1 int p1b = p1a + c. int p3a = p2b + 2. char dt = dayAbbreviations. Note that we use the replace // method for Strings. // the first Meeting object is a special case if (first) { // simply place the Meeting details in the // appropriate positions of the first element // of temp.format(mt.1 . } } // remember if we are processing first Meeting boolean first = true.getMeetingStartTimeLength() .replace(p2a.getStartTime()). p1b.1. 180 . dt). et). " ").getRoomNumber()). // number of rows of output we generate int rowsGenerated = 0. // p1a is the location of the first digit of start time // p1b is the location of the last digit of start time // p2a ditto for end time // p2b ditto for end time // p3a ditto for room number // p3b ditto for romm number int p1a = 8.getEndTime()).getRoomNumberLength() . String et = myFormatter. temp[0].getMeetingEndTimeLength() . int p2b = p2a + c. st). // remember that we have generated a row rowsGenerated = 1. p2b. for (int j = 0. temp[0].insert(j.getDayOfWeek(). // ensure times are four-digits DecimalFormat myFormatter = new DecimalFormat("0000"). // examine all Meeting objects for (Meeting mt: theMeetings) { // extract fields necessary for comparison // done mainly for efficiency. and setCharAt for // a single char temp[0]. int p2a = p1b + 2. rt). j < lengthNeeded. int p3b = p3a + c. int dt1 = mt.charAt(dt1). // and remember that we are no longer // processing the first Meeting object first = false.temp[row] = new StringBuffer(lengthNeeded).

equals(et). // found will still be false if we didn‟t find // a match if (!found) { temp[rowsGenerated]. dt). p2b. 181 . // if everything matches. p3b. dt). boolean needsReturn = false.substring(p3a.setCharAt(dt1. i < rowsGenerated. The second is ONE // MORE than the end position you wish // to consider. p1b. p1b + 1). } // added new row } // end except the first }// end for all Meetings // and finallly combine all the generated rows into one // large string String result = "". we need to create // a new row of the output. boolean matchEnd = temp[i]. // scan all existing generated rows for (int i = 0. // and exit the for loop early break. rowsGenerated++.replace(p2a.substring(p1a.replace(p1a. temp[rowsGenerated].equals(st). temp[rowsGenerated]. rt). The // first is the start of the substring // you are looking for. } // end match found } // end for // if we didn't find a match.setCharAt(dt1. p3b + 1). st). temp[rowsGenerated]. boolean matchRoom = temp[i]. i++){ // check things that need to match // IMPORTANT NOTE: // Substring has two parameters. // remember we had a match found = true. p2b + 1). et). boolean matchStart = temp[i].equals(rt).replace(p3a. update the // matching room to show another day of // the week if (matchStart && matchEnd && matchRoom) { // update the matching row temp[i].} // end first else { // process all Meeting objects except the first // we‟ll be searching through the rows we // have generated and need to know if we // find a match boolean found = false.substring(p2a.

We'll address that concern in a moment. result = result + temp[row]. This is often done while searching for something. I feel there is no need to decompose it into shorter methods. Thus cohesion is at least partly in the eye of the beholder. It uses a new method. Programming Style Let‘s step back a minute and look at the style in which this method has been written. this one takes several printed pages. An example of a useless comment is i = 3.) Since the method is cohesive. Yes. } } return result. needsReturn = true. It‘s a good idea to leave a note behind explaining subtleties in your code for those who follow afterwards. the subtasks probably would not exist independently of the main task. The Checkstyle extension says it is too long. I would argue that this method is cohesive. Others suggest that a method should be cohesive. there is no point in continuing searching once you have found what you sought. This method allows us to access a portion of a StringBuffer. since it summarises a collection of Meeting objects into a String. providing they are meaningful. Does it contain too many statements? Some people will suggest that a method should fit on a page. (See the discussion on composition and aggregation later in this chapter. As in life. Are there too many comments? Some would argue yes. row < rowsGenerated. If the name requires the word ―and‖ or the word ―or‖. row++) { if (temp[row]. but I feel it is generally impossible to have too many comments.length() > 0) { if (needsReturn) result = result + '\n'. Note the comment in the code about substring. some would say it is too long. } This is the longest method we have examined so far. To check that a method is cohesive give it a name that describes what the method does. there are several subtasks involved. the substring method for StringBuffers. // assign the value of 3 to i 182 . A method is cohesive when it carries out one task. or on a screen. but they are all essential to the main task.for (int row = 0. then the method is probably not cohesive. We have also used the break statement as a tool to exit a loop before it has completed its normal processing.

listSections. for example found = true. Fortunately sectionNumber is a String and Strings will sort into that order naturally. dt1 does not quite follow that pattern. room. Did listSections list the sections in the expected order? What is the ―expected order‖? At my college. rt. and should come first. Some would argue that all declarations should be at the beginning of the method. dt1. dt) and could be better. However. And we can create a unit test to add some Sections. Notice that declaration statements are scattered throughout the method. and 003. 002. my justification is that the names are used only within this method (and within a small portion of this method) and they actually make sense. =. 0. st. which will return a String showing all the sections (but not the students in the section) in a course. we need a Comparator<Section> to do the work for us. Make it so. start. lecture sections are numbered 001. should be commented as it is perhaps unclear what the effect of the statement is. That‘s what we‘ve done here. How do you know that addSection works? Create a method. and day of the week. /** * section number comparison. but for longer methods. Are the variable names meaningful? Guilty! Some of the names are very short (et. Test it and examine the value it returns. we use the same name but follow it with a digit. Course contains Section Now we almost have a fully-functioning Section class. dt and dt1 are both related to dates. the two-letters names are temporary (hence the ―t‖) values for end. I prefer a just-in-time style where I declare variables when I need them. However. L02. When tests are testing different aspects of the same thing. when it is a short method. but it follows the pattern we have established in unit tests. S02. followed by seminar sections which are numbered S01. Sometimes I agree. Other simple statements. as we saw in the discussion on uppercase and lowercase letters. Then lab sections are numbered L01.When you are using i to represent the month of March. or > Section s2 * based on the sectionNumber */ 183 . 1 if Section s1 is <. We can go back and resume adding Section objects to a Course object. then the comment should say that. * @param s1 The first section * @param s2 The second section * @return -1.

We will explore this Mark class a little later. You would certainly need a different comparator if your college uses a different notation for the sections of a course. plus the mark earned. That transcript will list all the courses a student has taken. at the end of the student‘s studies at the college. One possible (poor) way to show this is to place a collection of Course objects in the Student class. at the end of a semester. which contains the information on the course as it was taken. 184 . it appears a good solution is to create a Mark object. or at some other time. Consider the transcript that will be produced for a student. A collection of marks represents the courses taken in the past.public static final Comparator<Section> SECTION_NUMBER_ORDER = new Comparator<Section>() { public int compare(Section s1.getSectionNumber()). Thus. and Student contains Mark A student takes many courses at one time. note that it doesn‘t make sense to have a Section object without having an associated Course object. On the other hand. compareTo(s2.getSectionNumber(). and the student‘s performance in them. We also need to remember the mark the student earned in the course. A collection of courses represents the courses being taken in the current semester. The reverse association between Section (the whole) and Student (the part) describing the students enrolled in a section is also an aggregation. organized by semesters. the section exists whether or not students are registered in it. As an aside. Section s2) { return s1. Thus the association between Course and Section is an example of composition. some once. What happens when the name of a course changes after a student completes it? The old name should appear on the student‘s transcript. the student exists even though he or she may not be registered in a section. Mark. How do we represent the courses a student took in the past? This presents an interesting problem. This is a type of association between a whole (the Course) and its parts (the Section) where the part cannot exist independently of the whole. } }. the association between Student and Section describing the sections in which a student is enrolled is an aggregation. This is a type of association between a whole (the Student) and a part (the Section) where the part can exist independently of the whole. some more than once.

we expect to need a Comparator (don‘t forget the import statement!) and an equals method. Then a Student object can contain a collection of Mark objects. This second collection could be summarised to represent the courses the professor has taught at any time in the past. course name. but it does show what you can do with a little time and care. and semesterMonth all match. The Comparator is based on the course and semester in which the mark was earned. Summary That was quite a chapter. so a Professor object contains a collection of section identifiers. A Professor object could also contain a second collection of section identifiers. both integers. Professor contains Section As a Section object contains a collection of student identifiers. The January semester comes before September. Implementing this is left as an exercise for the reader.  Implement the getters and setters Since we need a collection of Mark objects. The coding was long and complicated. we will be able to use TreeSets again. it started). representing the Sections the professor has taught in the past.  Use BlueJ to create the skeleton code for a new class. courseNumber. This represents the professor‘s teaching assignment during the current academic year. the transcript shows semesters chronologically (oldest to most recent. Implementing this is left as an exercise for the reader. regardless of when the student started his/her studies. the course taken (subject abbreviation. 185 . The next chapter continues processing collections. Credits will appear on the transcript and will be necessary to calculate the overall grade point average. What does it mean to say that two Mark objects are equal? We can define equality to mean the subjectAbbreviation. this time called Mark.). semesterYear. and the mark earned.  Implement unit tests for the getters and setters. and credits.  Implement a constructor and a toString method. Follow our usual practice when creating a class. and may include courses in two or three semesters. course number. The courses in a semester are listed alphabetically by subjectAbbreviation and courseNumber. Since there is an ordering by date to these sections.).Thus instances of the Mark class must contain the semester (perhaps the year and month.

perhaps we should consider how to implement persistence. 186 . That is. how do we save data so that it will be there when we run our program again? Persistence is the topic of chapter 12. continue to chapter 11 and then chapter 12.If you prefer to skip chapter 10. Now that the student has data which must persist over time (the marks he/she has earned in the past). and the professor has data which must persist over time (the sections and courses taught in the past).

Implement the Professor contains Section association. 10. 6. How would these differences affect the code shown in this chapter? In a previous chapter. Explore the use of the ? operator. In a previous chapter. Explore the ResourceBundle class and see how you could use a resource bundle to allow for these two customizations. 9. When your program needs a locale-specific resource. your program can load it from the resource bundle that is appropriate for the current user's locale. we discussed modelling a bank account. 2. Create a method which will allow you to display all the transactions for an account which occur between two dates which you specify.‖ While used for internationalization. instead of a for-each statement. This chapter referred to different lengths for room numbers and course abbreviations. you can write program code that is largely independent of the user's locale isolating most. 4. Use this method to create another method which will allow you to list the sightings in the current year. Implement the Student contains Mark association. Implement the Mark class. 5. resource bundles can also be used for other customizations. Explore the use of the modulus operator when either one or both of its arguments are negative. The Java documentation tells us that ―Resource bundles contain locale-specific objects. we discussed modelling the sightings a birder makes. Explore alternative ways of changing the time of a meeting. Create a method which will allow you to display all the sightings a birder has made between two dates which you specify. 3. of the locale-specific information in resource bundles. 187 . Explore the Java documentation to determine the differences between StringBuffer and StringBuilder.Exercises 1. if not all. Implement alphaClassList using an iterator. a String for example. 7. 8. Use this method to create another method which will display the transactions within the last n days. where you specify the value for n. In this way.

188 .

The second is the graduating average. and then converted them to a String for display. we have added elements to them. We can calculate how many credits a student has earned in total by summing data in all Mark objects (eliminating duplicates) but we don‘t yet know the total by semester. involving Mark objects. a record of a student‘s progress in a semester. Usually. we will be calculating an average mark. and eliminating failures. the average of all the courses taken in a semester. I‘d like to return to another collection. This has interesting issues in a program which consists of more than 60 189 . taking the higher mark in case a student repeated a course. regardless of the marks earned.Collections. At Okanagan College. part 4 Learning objectives By the end of this chapter you will be able to   Use many of the String methods Summarize collections using a variety of techniques Introduction We have seen many collections so far. Now. In one case we have done more.Chapter 10 . When do we want to know the number of credits completed in a semester? The obvious time is when we are producing a transcript. Grade Average Recall that each course has a credit value associated with it. We processed all the meeting objects associated with a section and merged them into something suitable for a timetable entry. Let‘s see how to calculate those numbers. At the same time. How do you calculate the average mark? When to calculate an average We have two types of average. The first is the semester average. the graduating average actually involves only the last 60 credits completed in a program. The graduating average involves all courses taken towards graduation.

Calculate 3 * 74 and remember the result (222). To do this. Add 352 and 81 and remember the result (433). At Okanagan College. This is what I have.original version Recall that we have a very simple transcript method in the Student class. In the first course. create a weighted sum of the percentages (the percentage earned in a course is multiplied by the number of credits the course is assigned) and divide the weighted sum by the sum of the credits. Calculate 1 * 81 and remember the result (81). For the numerator. The transcript method . For example. assume that a student takes three courses at one time. In the third course. except in the exercises at the end of the chapter. worth one credit. In the second course. * @return String representation of Marks */ 190 . You‘ll be glad to know that we will not be pursuing this. Weighted average In either case. as are the credits. add two and three and remember the result (five). you must first evaluate the numerator. /** * create a transcript. But the division below is not done as an integer division. worth two credits.17. the student earns a mark of 65%. worth three credits. we calculate a weighted average. calculate 2 * 65 and remember the result (130). Let‘s modify it to serve our needs. This is not an integer division. the student earns a mark of 81%. Add five and one and remember the result (six). the marks we submit are integers. For the average. The weighted average is calculated as 2 ∗ 65 + 3 ∗ 74 + 1 ∗ 81 2+3+1 To evaluate this expression. so the result has decimal places. the student earns a mark of 74%.credits and creates interesting programming problems as well. For the denominator. Add together 130 and 222 and remember the result (352). and then divide the numerator by the denominator. The result of the division is the grade average. divide the numerator (433) by the denominator (six) and get a result of 72. You were asked to complete it on your own. The priority of operations in a programming language is the same as the priorities in mathematics. then the denominator.

) Transcript – a skeleton for changes Thus.public String transcript() { String result ="". the objects are stored by subject abbreviation and course number. } Knowing when a semester changes Recall that the collection of Mark objects is stored in a TreeSet. we have a new semester. we have the first modifications to the transcript method.getSemesterMonth(). we assume the previous year is 0 (or some other impossible value) and the previous month is also 0 (or some other impossible value. int previousMonth = ″″. we can calculate the semester average and reset various semester totals back to zero. we simply compare the value of the year in the current Mark object to the value of the year in the previous Mark object.toString() + '\n'. we have a new semester. and the objects within that collection are stored in order by semester. Should they be different. } return result. int currentYear. To determine when we have changed semesters. But what of the first Mark object? There is no previous Mark object. In this case. we will calculate an average of all the courses taken (which may be a graduating average) and we will calculate the semester average for each semester. public String transcript() { String result ="".getSemesterYear(). for (Mark m: theMarks) { curentYear = m. Within a semester. if ((currentYear != previousYear) || ((currentYear == previousYear) && (currentMonth != previousMonth))) { // semester has changed 191 . for (Mark m: theMarks) { result = result + m. we compare the (starting) month of the current Mark object to the (starting) month of the previous Mark object. If the years are the same. Should they be different. int currentMonth. We need to be able to tell whenever a semester has changed. currentMonth = m. When a semester changes. Whenever we produce a transcript. int previousYear = 0.

The semester totals need to be added to the student totals. totalDenominator += semesterDenominator. we use == and !=.toString() + '\n'. ―When the year has changed or the semester has changed‖ becomes ―If the years are not the same or the years are the same but the months are not the same‖ which becomes if ((currentYear != previousYear) || ((currentYear == previousYear) && (!currentMonth != previousMonth))) Since the years and months are primitive datatypes. totalCredits += semesterCredits. // display semester results result += "credits earned = " + semesterCredits + " average = " + semesterAverage + „\n‟. } Note the use of || to mean ―or‖. and then the semester totals are reset to zero. When the semester changes What calculations are necessary when the semester changes? The grade average for the semester needs to be calculated and displayed. semesterDenominator = 0. semesterCredits = 0. // calculate grade average semesterAverage = (double) semesterNumerator / semesterDenominator. We need to remember the year and month of the previous semester. 192 . along with the number of credits earned for the semester. // calculate semester totals } return result.// calculate averages and reset totals } // display current Mark result = result + m. These English statements translate into the following Java statements. // reset semester totals semesterNumerator = 0. // add semester totals to overall totals totalNumerator += semesterNumerator.

76 instead of 9. To ensure that an integer divided by an integer gives a result with decimal places. When you test this method. drop it and increase the previous digit by one. Always display the decimal point and two digits after it. giving a double.‖ As I write this (Spring 2006). the track and field world is discussing how a time of 9. When the first digit to be dropped is exactly five.773 rounds to 9. A DecimalFormat object using the pattern ##0. Recall our discussion on splitting an integer into pieces. you will find that unfortunately the semester and overall averages appear with a varying number of decimal places. your result is an integer. rounding as appropriate.78 (third part of the rule). Display the digit in the tens column when it is not zero or when it is zero and the digit in the hundreds column was printed.‖ Thus 9. When you have an expression involving a variety of datatypes. 9.org/wiki/Rounding 193 . drop it and leave the previous digit unchanged. Wikipedia gives a good discussion of rounding at http://en. all these variables are ints. otherwise leave blank.// remember the previous semester previousYear = currentYear.98333 my calculator shows. it converts the other integer to a double and divides a double by a double. When the first digit to be dropped is less than five.wikipedia. most students like to see at least one or two decimal places.00 will resolve that. You see this in the first statement.77 (second part of the rule). In many cases. the Java compiler then takes over and converts them all to the ―highest‖ datatype.766 seconds was mistakenly rounded to 9. When you divide any type of integer variable by another integer variable. Integer division With the exception of the semesterAverage. change the previous digit to be even. and 9. The rule usually used is ―When the first digit to be dropped is more than five. In this case. Always display the digit in the units column. otherwise leave a blank. previousMonth = currentMonth. the third part of the rule is ignored or forgotten.775 rounds to 9.77.766 rounds to 9. rather than the 78. we cast (or convert) one of the integers to a double datatype and then do the division. 4739/60 is 78. Read the pattern as ―Display the digit in the hundreds column when it is not zero. When calculating an average mark. semesterAverage = (double) semesterNumerator / semesterDenominator.77 (first part of the rule).

How would we modify our model if different courses had different passing marks? Then we need to display the information about the current Mark. double totalAverage. The declarations Of course. When a student earns a mark of less than 50. To count this towards the graduating average.getCourseCredits(). double semesterAverage. int semesterDenominator = 0. String result ="". int percent = m.When the semester remains the same We need to calculate and accumulate the totals for the current semester. result += "total credits earned = " + totalCredits + " average = " + totalAverage. semesterNumerator += percent * credit. int credit = m. int previousYear = 0. result = result + m. 194 . semesterDenomimator += credit. semesterCredits += credit. we can display the final average. int totalDenominator = 0. totalAverage = (double) totalNumerator / totalDenominator. int semesterNumerator = 0. Usually this means 50% is the minimum passing mark. as we did before. but it does not count towards the credits earned. the course is counted towards the semester average. String previousMonth = "". we need to omit courses which the student did not pass. int totalNumerator = 0. int currentYear = 0. The overall average Once we have processed all the Mark objects associated with the student. int totalCredits = 0.getMarkEarned().toString() + '\n'. int semesterCredits = 0. String currentMonth = "". all of this requires the declarations of the variables.

the method attempts to display a semester average when it reads the first mark. fix it. The String class and its methods I find it is a great deal of fun to manipulate a String. That makes no sense. Let's look at some of these methods before we continue generating our transcript. resulting in a transcript that is hard to read. What if we want to disassemble a string? Suppose we have a string String name = “Marmaduke Archibald Cholmondley”. Instead. We can use the same technique to avoid printing an unnecessary subtotal. the summary for the semester follows the details for the semester. First of all. You would be right in thinking these methods would repeat much of the code in the transcript method. We have already seen how to use a boolean variable to tell us when we are processing the first element of a collection. Second. for example). true when the resulting String should have the semester summary appearing last. 195 . Third. Fourth.The transcript String – problems and deficiencies Like much code which people write. and false when the resulting String should have the semester summary appearing first. That would not be sensible. Nor does it add the marks and credits for the final semester into the total. we will write a method which takes the String which the transcript method calculates and manipulates it so the details about the averages appear in the correct places. Make it so. one for summary-first and one for summary-last. This may be acceptable for a printed transcript but sometimes (in the online transcript my college provides. There are so many methods available for manipulating and rearranging Strings that you can do almost anything you want to Strings. the transcript method we have produced is partly correct. the summary comes first. since any errors in one method could be repeated in the other. for example. Adding a few „\n‟ characters to the output will solve that problem. but in some other order. That‘s an error. but not wholly correct. the method does not display the semester average of the final semester. How do we tell the transcript method that the summary comes first sometimes and last other times? One way is to pass it a boolean variable which is. the vertical spacing is not very good. A second way is to have two different methods.

split(name).charAt(0). numbers. i < names.substring(0. substring does not remove characters from the original string. Since the characters which make up a string are numbered starting at zero. respectively. of letters. char firstInitial = name. breaking the original string at places which match the value of a ―regular expression‖ which you specify. String middleWord = name. How did we know which positions to use in the above statements? We counted characters. etc. Of course. possibly including wildcards. 9). " + name + " consists of ["). up to but not including the character in position nine. lastWord will be the string ―Cholmondley‖.substring(20). But there are alternative. a newline.print("broken into strings. Or we could use the indexOf method to help us find the blanks. a blank. The second retrieves the characters beginning at position 20 and extending to the end of the string. we use one of the two forms of the substring method. firstWord will be the string ―Marmaduke‖. you can use a similar statement to determine the middle word. 19). If we wish to retrieve substrings. We could use the split method. firstInitial now contains the character ‗M‘. charAt does not remove characters from the original string. What do we use to represent a backslash? 196 . Pattern p = Pattern. String[] names = p. The regular expression we want to use consists of two characters. which returns an array of String.out. Details of split The split method takes a string and returns an array of strings. A regular expression is a pattern. \s. String firstWord = name.out. which refers to any whitespace character. System.If we wish to retrieve single characters. System. collections of consecutive characters. String lastWord = name. we use the charAt method. The following statements will break the variable name into its pieces and display them. That is. That is.compile("\\s"). The first retrieves the characters beginning at position zero.out.substring(10. a tab.println("]"). Recall that previously we have used \n and \t to represent a new line and a tab. for (int i = 0.print(" " + names[i]).length. i++) System. and/or punctuation.

indexOf(“duke”). we can seek a string. 197 . the output will be ―gnirts a si ereh‖. int n = name.indexOf(„a‟). \\. In this form of indexOf. Remember that we number the positions starting at 0. write a method which will accept a string and then generate the string in reverse. returns the number 4. n). the second parameter is the position at which we begin seeking the specified string. Rather than seeking a character.indexOf(„a‟. The statements n = n + 1. returns the number 5 since the string ―duke‖ begins in the sixth position of the string we are searching. since the first character ‗a‘ in name is at the second position. To get both the backslash and the s. The first starts seeking a specified character. More details on regular expressions and patterns are in the Java documentation describing the Pattern class. With any form of the indexOf method. That is. when the string we are seeking is not in the string we are examining. the position of the next ‗a‘ in the string. for an input of ―here is a string‖. We could also specify the position at which we begin seeking the string. Why would it return -1? What is special about -1? If you wish to start at the end of the string and search towards the beginning. One possibility is to reverse a string using an iterative algorithm. the String class supports a number of different lastIndexOf methods. n = name. Reversing a String As an exercise in using various String methods. the method returns -1. as did substring. we could look at each character and process it. looking from the beginning of the string. That is. n = name. the first parameter. Details of indexOf and lastIndexOf The indexOf method comes in several forms. we use \\s.Right. returns the number 1.

in the second case it is zero. You may need to ponder this method for a while.public static String iReverse(String s) { String result = "". Both can be detected by looking at the length of the string. You will see recursion again when we look at some mathematical methods in a later chapter.length() <= 1) return s. and case) reads the same forwards and backwards. then the reverse of the string is the reverse of all of it except for the first character. we formulate a problem in terms of one or more smaller versions of the same problem plus one or more smallest versions of the problem. and there is at least on smallest version. A second possibility is to reverse the string using a recursive algorithm. Some English words (civic.charAt(0). When we use a recursive algorithm.charAt(i) + result. Palindromes While we are playing with strings. In both these smallest cases. } The method is declared static so that we can use it with any string. for which we know the answer. We have seen many examples where one method calls another. followed by the first character. as well. how about exploring palindromes? The simplest definition of a palindrome is a sequence of characters that (not counting spaces. it is one. In the first case. it is the first time that we have seen a method call itself.substring(1)) + s. since it is the first time we have used recursion. there are two smallest versions. punctuation. level. Why should a method not be able to call itself? Remember that recursion works because you are using a smaller version of the same problem. for (int i = 0.wikipedia.length(). public static String rReverse(String s) { if (s. tot. } The logic in this method is as follows: o If there is zero or one character in the string. a string which contains a single character and a string which contains no characters. o If there are several characters in the string. it is its own reverse. http://en.org/wiki/Palindrome Can we write a method that tells us whether or not a string is a palindrome? 198 . i < s. a) are palindromes. return result. else return rReverse(s. i++) result = s. That is. Wikipedia has a discussion of palindromes in other languages and music. the reverse of the string is the string itself. In this case.

equalsIgnoreCase(rReverse(target)). Yes. i < s. We have used statements like result += "total credits earned = " + totalCredits + " average = " + totalAverage. However. Try this method with some of the well-known palindromes. i++) { char ch = s. We use a method from the Character class.isLetter(ch)) target = target + ch. What‘s going on here? We explained this situation earlier.‖ ―A man.  Copy the contents of the memory to which result refers to another area of memory (call it area 1) and append ―total credits earned =‖ to the contents of area 1. Determining that the string is a palindrome takes place in the return statement. they cannot be changed. Now that we have seen some of the String methods. a plan. we can go back to the original problem of producing a transcript. But the reference itself may change. a String is immutable. isLetter. That is.Certainly. most of the method involves taking out the characters that are not letters. It uses one of the reverse methods we just created. a String is a reference to an area of memory which contains the contents of the String. 199 . public static boolean isPalindrome(String s) { String target = "". } As you can see. The transcript String – reordering But wait a minute! We‘ve said on many occasions that Strings are immutable. Change result so its reference points to area 1. Those contents may not be changed.charAt(i). // keep only those characters which are letters for (int i = 0. } return target. Convert totalCredits to a String and append that to the contents of area 2. a canal: Panama!‖ Others are given in the Wikipedia article cited earlier. in less detail. which changes a String. The way the assignment statement above is implemented might be as follows.  Copy the contents of area 1 to another area of memory (call it area 2). if (Character. to identify the characters which are letters. thus pointing to a different area of memory.length(). Change result so its reference points to area 2. I‘m Adam. ―Madam. And now we‘ve seen how to disassemble strings.

  Copy the contents of result to another area of memory (call it area 3) and append ″ average =″. int startPhrase. unreferenced) areas of memory are made available for reuse. Here is my transcriptSummaryFirst method. (Be careful that you do not find the substring beginning ―total credits earned‖. How do we use this to manipulate the String that transcript has produced? First we note that there are some special substrings we need to identify and move. // at the end of the search. you find // "credits earned" followed by // "total credits earned". Change result so its reference points to area 4. * @return transcript with summary first */ public String transcriptSummaryFirst() { String result = "". So now you see how we have been able to construct Strings from other Strings. so they are eligible for garbage collection. // where the phrase starts int endPhrase. // repeatedly search for the // phrase "credits earned" startPhrase = temp. String summaryLine = "". All others remain in the same order. But what about the areas of memory I have called area 1. and area 3? They now have no references referring to them. startPhrase is // 6 when this happens while (startPhrase !=6 ) { // extract everything up to but not // including the phrase "credits earned" 200 . String temp = "". These begin with ―credits earned‖ and end with ‗\n‘. Copy the contents of result to another area of memory (call it area 4). // where the phrase ends String semesterDetails = "". area 2.) Only these substrings need to be moved. Change result so its reference points to area 3. /** * create a transcript String in which the summary * comes before the details of the semester. Try to write the method transcriptSummaryFirst without reading on.indexOf("credits earned"). // get transcript with summary last temp = transcript(). even though Strings are immutable. Convert totalAverage to a String and append that to the contents of area 4. a process by which unused (that is.

summaryLine = temp. +1 is to ensure // the \n is included endPhrase = temp. provided the topics are different.substring(0. once we have examined all the marks. This emphasises the importance of getting your model correct before you start implementing it. // extract the summary line. we‘ll create a collection that contains only the marks we‘ll need. including the \n temp = temp. Then. Rather than saving the credits and percentages we need to calculate the overall average. continued The overall average is incorrect for a student who has repeated courses. The transcript String – problems and deficiencies. when a student takes a course twice (or more). endPhrase + 1). This will involve rethinking how the transcript method calculates the overall average. we‘ll calculate the average.substring(startPhrase). startPhrase). 201 . // and look for next "credits earned" startPhrase = temp. Actually.indexOf("credits earned"). return result. its mark counts towards the semester average for each semester in which it is taken. // build the result result += summaryLine + semesterDetails. At my college. // remove that substring temp = temp. // remove the summary line.indexOf('\n').semesterDetails = temp. the problem is even more complicated.substring(endPhrase + 1).substring(0. so we will ignore this problem. Implementing this would require us to rethink our model quite seriously. } // place the overall average first in the // output String result = temp + '\n' + result. } To understand how this method works. We have ―special topics‖ courses which may be taken more than once for credit. But only the highest mark should be included in the overall graduating average. it may help to sit down in a quiet place and draw a series of diagrams to show the steps in the process.

} } Since we don‘t care about the year and semester. credits. 1999. // if so. import java. int credits. Many datatypes allow this. except that Mark contains the year and month of the semester in which the mark was earned. m. i is zero or more. we convert it to a HighestMark object and compare it to other HighestMark objects. m.util. That is. Mark.We need a collection in which we can store objects containing a subject abbreviation. so its methods are inherited from its parent. course credits. class HighestMark extends Mark { public HighestMark(String departmentAbbreviation. the exact values we provide don‘t matter! That is all there is to the class. so let‘s use one now. "SOMETIME". the child class HighestMark is derived from its parent class Mark. and mark earned. can we use the Mark class? Yes. Each time we process a Mark object.ArrayList. If not. we just provide some values. i is -1 if (i == -1) // a mark for the course does not exist 202 . but we would like to be able to check whether there already is a mark stored for the course. h = new HighestMark(m.indexOf(h). we can. All the methods which we created for Mark will be available to HighestMark objects as well. but we haven‘t used an ArrayList for a while.getDepartmentAbbreviation(). We can extend it to create a new class. // is there a mark for this course? int i = best. So what type of collection should we use as the basis of the collection of HighestMark objects? The order in which they are stored does not matter. HighestMark h. Since the year and month don‘t matter. ArrayList<HighestMark> best = new ArrayList<HighestMark>().getCourseCredits().getMarkEarned()). HighestMark that does not concern itself with the year and semester. course number. int courseNumber. We modify our transcript method by adding the following three statements. m.getCourseNumber(). But we already have a class like that. courseNumber. int markEarned) { super(departmentAbbreviation. markEarned).

it is time to go back and cover some of the things that have been glossed-over.getMarkEarned() < m. This is a practice called regression testing.getMarkEarned()). 203 . run a unit test on it again. we need to talk about exceptions. or -1. we compute the numbers we need for the overall average.getCourseCredits(). for (HighestMark b:best) { totalNumerator += b.best.getMarkEarned()) best. Now we have a transcript method that calculates the overall average correctly. totalDenominator += b. Then we will look at persistence and then developing a graphical front-end on our program. When we have processed all the Mark objects. Now that we have experienced a serious amount of sophisticated Java code. Some String methods also return -1 to indicate a lack of success.get(i). We have seen this use of special values for invalid data when using Strings.getCourseCredits(). if it exists. totalNumerator = 0. Summary This chapter has focussed on manipulating strings. This works because the indexOf method returns the position of the mark. so that we are not so dependent on BlueJ. totalDenominator = 0. In particular. as much processing involves string manipulation. } totalCredits = totalDenominator. an invalid position.setMarkEarned(m. else // a mark for the course exists if (best. This is an important skill. But to be safe.get(i). making sure that a change you made has not broken anything else.getMarkEarned() * b. if it does not.add(h). And what if we wish the summary lines of the transcript printed before the details? Nothing we have done has changed that method.

Of course class lists may be in order by the name of the student or by student number. so ―the last 60 credits‖ refers to 20 courses. How would you modify the grade averaging process if your college assigned letter grades? How would you modify the grade averaging process if different courses at your college had different passing marks? This may entail rethinking more than a small part of the model. 5. Make it so. as well.Exercises 1. Create a method to list all the birds seen. the student may take the same special topics course more than once in a semester. How would you modify the calculations of the graduating average if it was based on only the final 60 credits completed in a program? Many programs have only three-credit courses. showing the total number of transactions in each month. What would happen if a program had a mix of one-. Make sure that the list tells how many birds have been seen each month. and three-credit courses? 4. 7. 6. You can use the ideas from creating a transcript to create a class list. 3. In a previous chapter we examined bank accounts and the collection of transactions they contain. 2. Create a method to list all the transactions for a particular account. Make it so. and each year. two-. and how many each year. as long as she/he is registered in different sections. How would you change the model to handle special topics courses? A student may take these courses more than once. In fact. In addition. In previous chapters we have looked at the data a birder collects. 204 . provide the number of species seen each month. Recently my bank has begun to show the account balance at the end of each day.

For example. which occurs during the execution of a program. that disrupts the normal flow of the program's instructions.Exceptions Learning objectives By the end of this chapter you will be able to:      Define exception Define catch and try Identify when exceptions are thrown and describe how to catch them Create.com/docs/books/tutorial/essential/exceptions/definition. The third was when we discussed preventing bad data getting into Meeting objects.Chapter 11 . but one of my favourites is Sun‘s Java tutorial. and are described at http://java. The second was when we discussed the need for a Professor object to have a hiring date. as viewed on 200605-19.sun. Exceptions are essential. Before we see these exceptions. There many other exceptions and we shall see some of them in the following chapters. The first was in the clone method where we had to handle a CloneNotSupportedException.com/docs/books/tutorial/. available at http://java. These include ClassNotFoundException. and FileNotFoundException. we have this introduction: ―What Is an Exception? ―The term exception is shorthand for the phrase ―exceptional event. we should first answer the question ―What is an exception?‖ There are many sources that will answer the question.html This section of the tutorial contains a number of quotations from the tutorial.sun. throw.‖ ―Definition: An exception is an event. IOException. One of the trails through the tutorial takes you through essential classes and features. 205 . and catch your own exceptions Use exceptions to create programs which gracefully handle erroneous input and mistakes in computation Definition We have mentioned exceptions at least three times so far.

The set of possible ―somethings‖ to handle the exception is the ordered list of methods that had been called to get to the method where the error occurred. you would want to be able to clone any object. ―The exception handler chosen is said to catch the exception. However. } In this method we have created a CloneNotSupportedException with our own message attached to it. which we will have already seen. An example would be in the College system we have been modelling. the method creates an object and hands it off to the runtime system. where we wish a collegewide policy to describe how percentages translate to letter grades. If the runtime system exhaustively searches all the methods on the call stack without finding an appropriate exception handler. you could use this clone method. Creating an exception object and handing it to the runtime system is called throwing an exception. ―After a method throws an exception. We accomplish the same result by using the Singleton pattern. The object. public SomeDataType clone() throws CloneNotSupportedException{ throw new CloneNotSupportedException (“Cloning is not supported by this object”). so there should be only one copy. contains information about the error. Everybody follows the same policy. the runtime system (and. the runtime system attempts to find something to handle it. including its type and the state of the program when the error occurred. The search begins with the method in which the error occurred and proceeds through the call stack in the reverse order in which the methods were called. An exception handler is considered appropriate if the type of the exception object thrown matches the type that can be handled by the handler. there are some cases where you want to ensure there is one and only one copy of an object. The list of methods is known as the call stack. ―The runtime system searches the call stack for a method that contains a block of code that can handle the exception. the runtime system passes the exception to the handler.―When an error occurs within a method. This block of code is called an exception handler.‖ Examples When we attempted to clone an object. If you want to prevent cloning an object. consequently. the program) terminates. 206 . called an exception object. When an appropriate handler is found. a CloneNotSupportedException may occur. Normally.

thus. Fortunately. check the documentation on Exception and its subclasses. pointer exceptions. We might have seen one if we tried to calculate a student‘s grade average for a semester in which the student was not enrolled in any courses. or a missing hiring date. although it may. perhaps naming it MissingHiringDateException.‖ Many of the Exception methods we use are actually derived from Throwable. we have not seen one of those yet. such as trying to access an array element with an index that is too large or too small. Perhaps we need to create our own type of exception. and indexing exceptions. For incorrect times. A method does not have to catch or specify runtime exceptions. Exceptions come in two flavours: runtime and nonruntime. once we create them ourselves. IOException is a nonruntime exception. there is a class named Exception and a number of subclasses derived from it. you may wish to look at the class Throwable. 0400 is a correct time. coming from a library used in compressing files. exceptions that occur during I/O are nonruntime exceptions. 2507 is an incorrect time. we wanted a way to identify incorrect or inappropriate times for the meeting. The compiler ensures that nonruntime exceptions are caught or specified. 207 . By the way. That documentation contains the sentence ―The class Exception and its subclasses are a form of Throwable that indicates conditions that a reasonable application might want to catch. but it may be inappropriate. ―Nonruntime exceptions are exceptions that occur in code outside of the Java runtime system. Runtime and nonruntime exceptions As exceptions in Java are very important. Perhaps the class should throw a DataFormatException. ―The Throwable class is the superclass (or parent class) of all errors and exceptions in the Java language. For example. This exception. The exceptions reporting incorrect and inappropriate time.‖ Reasonable. such as trying to access an object‘s members through a null reference. they are also called checked exceptions. The Java tutorial states ―Runtime exceptions occur within the Java runtime system: arithmetic exceptions. will be runtime exceptions. is one I find very useful when I don‘t want to create my own exception. such as dividing by zero. When we developed the Meeting class.‖ The CloneNotSupportedException is a runtime exception. we wanted a way to ensure that a hiring date was specified. To see a (lengthy) list of the possible exceptions available in Java. When we were developing the Professor class. we might need IncorrectTimeException and UnlikelyTimeException but I would probably just use DataFormatException.Division by zero is another place that you may want to throw an exception. indeed.

we would need a database of rooms. o When there is not an appropriate type of exception. we have two choices. and throw an exception. But what could go wrong? dayOfWeek could be an unreasonable value. To create an exception. an existing type of exception.. along with the appropriate import statement. Thus we can use the following statements in the constructor. it may be negative or it may be seven or more.roomNumber = roomNumber. String roomNumber. …. we create an object of that type. But we will have to leave that exception for another time since we don‘t have time in this textbook to see how to have a Java program talk to a database. 0100 to 0159. When the String provided is not in that database. Nothing prevents an errant program or a malicious user from specifying a value like 0875 or 4500. We can detect that. Thus.Creating and throwing exceptions Consider the constructor for the Meeting class. */ public Meeting(int dayOfWeek. and throw an exception."). } This constructor assumes it has been given clean input. though. startTime and endTime are both ints meant to represent time on a military clock. we create our own exception.6. have the College class contain a collection of available rooms and ask the College class if it knows of the room. We could. We can detect that. /** * Constructor for objects of class Meeting. To detect this. this.startTime = startTime. roomNumber is a String It could be a String which does not represent an existing room. When a bad value is provided to dayOfWeek it makes sense to use a DataFormatException. 2300 to 2359. this. due to some programming error or malicious input. this.endTime = endTime. if ((dayOfWeek < 0) || (dayOfWeek > 6)) throw new DataFormatException( "dayOfWeek may only be 0. int startTime. The intent is that it is between 0 (Sunday) and 6 (Saturday) inclusive but there is nothing to force those conditions. 208 . we have a problem and should signal it by throwing an exception. o When there is an appropriate type of exception already available. from 0000 to 0059. inclusive.dayOfWeek = dayOfWeek. int endTime) { // initialise instance variables this.

util. we need one more modification to the constructor. * * Called after every test case method.util. In this case. * * Called before every test case method. * * @author rick * @version may */ import java. Thus. public Meeting(int dayOfWeek. you throw it to some other section of your program which acknowledges the problem and fixes it. */ protected void setUp() { } /** * Tears down the test fixture.DataFormatException. the Meeting object we desired has not been created and the portion of the program which asked to create it will need to determine the correct value for dayOfWeek before the Meeting can be created.import java. Normally you don‘t create an exception and do nothing with it.TestCase { /** * Default constructor for test class MeetingTest */ public MeetingTest() { } /** * Sets up the test fixture. /** * The test class MeetingTest.DataFormatException. The tests should be something like the following. indicating that it throws an exception which must be handled in some other method.framework. public class MeetingTest extends junit.zip. String roomNumber. int endTime) throws DataFormatException You already have a unit test for an appropriate value of dayOfWeek. */ protected void tearDown() { 209 .zip. int startTime. and one for dayOfWeek too large) to check that the exception is properly thrown. Now write two unit tests (one for dayOfWeek too small.

} public void testMeetingLargeDay() throws DataFormatException { Meeting m = new Meeting(7. 1030). (When you use javadoc to generate the documentation for a class. class BadHourException extends Exception { public BadHourException(String msg){ super(msg). } } class BadMinuteException extends Exception { public BadMinuteException(String msg){ super(msg). assertNotNull("was created". to create our own exceptions. we create a small helper method to do the processing. But the same exception in thrown is both cases. 1000. since our programs will be simpler. } } We can also use a DataFormatException to indicate that the start or end times are incorrect or inappropriate. m). callable only within the Meeting class. "L322". 1000. or that it is too large. By providing our own messages (the parameter passed to the constructor).) /** * check if a time value is acceptable * @return true if okay * @return throw an exception if not */ private boolean isValidTime(int t) throws BadHourException.) But it may be better. "L322". private methods are not exposed. since it is a good idea to provide as much information as possible about errors which occur. We identify the need to throw these exceptions by modifying the Meeting constructor a little more. we can include the offending data in the message should we wish (and we should wish. } } The statements defining these exceptions will be included in the same file as the Meeting class. assertNotNull("was created". Since we need the same sort of processing for both the startTime and the endTime. BadMinuteException{ 210 . m). but after the closing brace for that class. but it may be better to create our own. more meaningfully-named exceptions. 1030).} public void testMeetingSmallDay() throws DataFormatException { Meeting m = new Meeting(-1. Note that the DataFormatException we have created can tell us about two problems – that the input is too small. This helper method is a private method.

DataFormatException { Meeting m = new Meeting(3. hours too small. That is what catch clauses do. if ((minutes < 0) || (minutes > 59)) throw new BadMinuteException("For time " + t + " minutes should be between 00 and 59."). m).endTime = endTime. int endTime) throws DataFormatException. public void testMeetingLargeHour() throws BadHourException.int hours = t / 100. described below) and the method. BadHourException. You‘ll need three tests. what happens if someone wanted to be able to provide military time as well as civilian time? Can you create a method to handle such times? Now we can create and throw exceptions. its calling method. } When an exception is thrown. 211 . or a method before it in the calling stack. Why don‘t you need a test for minutes too small? The unit tests look like this. if (isValidTime(startTime)) this. assertNotNull("was created". the processing in the current block of code ceases (unless there is a finally clause. if (isValidTime(endTime)) this. int minutes = t % 100.? That is. return true.m. hours too large. BadMinuteException Write unit tests to attempt to create Meeting objects with bad times.″ + " inclusive. 1030). } How would you handle a time like 10:30 p. BadMinuteException. public Meeting(int dayOfWeek. the constructor must indicate that the exceptions may be thrown.startTime = startTime. and minutes too large. We invoke the isValidTime method as follows. is expected to handle the exception. But how do we handle the exception when it occurs. if ((hours < 0) || (hours > 23)) throw new BadHourException("For time " + t + " hours should be between 00 and 23 inclusive"). String roomNumber. Since isValidTime may throw exceptions and the constructor doesn‘t handle them. int startTime. "L322". 2500.

It is repeated below. 212 . Thus some piece of code must handle it. In this case. water polo. when you throw the ball. we place the code which could cause an exception inside a try block. In a general way. we handle it ourselves.clone(). Since we know it cannot happen. the processing we do is minimal. That‘s the theory behind throwing and catching exceptions. the CloneNotSupportedException may be thrown by super. // can not happen } } In this case. /** * clone * @return a copy of the Address */ public final Object clone() { try { return super. in this situation the code in the catch block will never be executed. basketball. rugby. and lacrosse. we show this as try { Some statements which can throw exceptions } catch (one type of exception) { } catch (another type of exception){ } CloneNotSupportedException You have already seen a catch clause in the clone method.Catching exceptions In baseball. To repeat. That is not the case for the majority of exceptions. } catch (CloneNotSupportedException e) { return null. football. When the problem is something we can handle ourselves immediately.clone(). someone else catches it (unless you have scored a goal).

// so there should not be anything in the // catch block here! } Rather than handling the exception yourself here. you need to pass it back to the method which called this one.Bad input data But suppose you have gathered the information to create a Course object. This process uses exceptions extensively. Summary Exceptions are the powerful technique Java uses to handle errors. // That can not be done here. // The exception must be handled elsewhere. The following two chapters involve writing data to external devices. 213 . but there is some information which is missing or otherwise ―bad.‖ Your program will look somewhat like this. We will see many more exceptions in the chapters that follow. try { c = new Course(information). // do something with the course object } catch (anException) { // what can you do? // You need to have the person/method // which created the information correct it. // gather information Course c.

The payroll system threw exceptions for one-character names. That worked well until a person with the last name A joined the organization. 2. 214 . A second story was about the person who didn‘t have a long first and middle name. One story is about a payroll system in which last names with only one character were used for testing purposes.Exercises 1. Modify the constructor for Person so that it throws one or more exceptions if there is a birth date provided but it is an inappropriate date. In Indonesia. The people who wrote the system stripped out unusual characters from the input. many people go by just one name. His name was something like R B Jones. 3. Explore the Exception class to see what other types of exceptions are available to you. How could you determine that you are in a country where people use only one name? There are many stories about programs that have difficulty with names. Thus R B Jones became Ronly Bonly Jones. Modify the constructor for Person so that it determines that both a first and a last name are provided and throws exceptions if either name is missing. So the data entry people entered the name as R(only) B(only) Jones.

Of the two chapters. we need to investigate ways to ensure the persistence of objects. ranging through ―doggedness‖ and ―a tendency to continue. it is the ability to save an object and retrieve it at a later time. BlueJ allows us to place the objects it creates on the Object Bench.Chapter 12 – Persistence. and then restarted BlueJ. Suppose we wish to create several objects and have them available at a later time. and the next.‖ In computing. If you prefer to skip this chapter. this one describes an older technique which is becoming less common as time goes by. Yes. Persistence has many meanings. We need a way to create objects and then save and restore them so we can use them again. part 1 Learning objectives By the end of this chapter you will be able to:   Define persistence Implement persistence through object serialization Warning to the reader This chapter and the next explore some advanced concepts which many people would prefer to omit from an introductory programming course. turned the computer off. I feel it makes perfect sense to include the subject of persistence. Why persistence? Unit testing provides a way to create and destroy objects. Chapter 13 describes a technique which is being used more and more. However. but they exist only until you recompile the object or exit BlueJ. but only for the duration of the test. In short. persistence is closer to the second definition. perhaps the next day. after we have ended BlueJ. 215 . you should be aware there is a small section in the mathematical chapters which you will need to omit should you omit the subject of persistence now. If you need to skip a chapter. given the model we are building. make it this one.

216 . we must consider the external devices we will use and their characteristics. The terms used in Java are serialization and deserialization. Thus RAM is not suitable for persisting data. Serializing an object involves writing it to an external storage device. We will not explore that option here. what does saving an object mean? Saving an object involves converting the object‘s state (the values of its instance variables) to a stream (a continuous sequence) of bytes and writing those bytes onto a medium which will not lose its contents when the power is removed. The ability to save data has been required since the earliest days of computing. it will be given a name and will have behaviour (as specified in the class definition). The use of databases is possible as well. Java is a more generalized language. You can think of streams as sequences of characters. and then closed. CDs. It too requires the processing of data saved by other programs. Notice that there are other ways of saving data. but is the origin of the type of serialization we are considering in this chapter. supporting many types of processing of data. and behaviour.The random access memory (RAM) in a computer is volatile. hard drives. and memory sticks. you would need to ensure that the supply of electricity is uninterrupted. Traditional file processing is possible. The external devices could also be other computers. Java allows us to serialize an object. and its state will be reconstituted from what was previously saved. in real time. Streams Writing to and reading from external devices is done through streams. when it loses power. Thus we have seen the use of non-volatile memory (punched cards.) There are programming languages (COBOL and RPG are examples) designed to simplify the processing of such data. but we will not discuss that here. written to (or read from). it loses its contents. Files have names. perhaps including special characters. thus granting it persistence. DVDs. state. it is a topic for more-advanced study. When an object is restored. You can use serialization to send objects from one computer to another. floppy disks. These files must be opened. but that is much more complicated and we will not discuss it here. The external devices are mostly disk drives and the files they contain. local or somewhere else on the Internet. External devices Before we can look at serialization. Deserializing an object involves reading it back from that external storage device. magnetic tapes. Since an object has identity.

Thus.com/javase/6/docs/api/. If so. As the documentation says. look into the documentation and see if it implements the Serializable interface. another class available in the java. before we can serialize a Person object. it isn‘t. and Java Class Libraries. Persistence via object serialization Note that we can only serialize (save) and deserialize (restore or rebuild) objects all of whose components are serializable. Miscellaneous to provide the Java documentation URL. All the instance variables of Address objects 217 .‖ Think of a graph as the instructions for recreating the structure of the object. Click Help.io package which allows us to connect a stream to an actual file.io package. Methods in ObjectOutputStream allow us to translate the objects into a stream. we need to ensure that all its instance variables are serializable. If you prefer. Now we are ready to see how to do object serialization. it is serializable.So we need streams to which we can write and from which we can read and we need a way to associate a stream with an external device. If not. Preferences. Object serialization . ―A file output stream is an output stream for writing data to a File…‖ Remember that BlueJ helps you access the online documentation. its class must implement the Serializable interface as noted above and all its instance variables must be serializable. we find that FileOutputStream is a class in the java. Your default browser opens http://java. Similarly. A Person object contains  Several Strings which are all serializable by design. If you want to see if a class is serializable.Address For an object to be serializable. Looking from the operating system level first.sun. you can download this documentation onto your own computer and then use Tools. ―An ObjectOutputStream writes primitive data types and graphs of Java objects to an OutputStream.  An Address object which is not yet serializable. Which streams will we need for object serialization? This technique requires writing objects to streams. and the FileOutputStream connects that stream to a file on the underlying operating system.  A MyDate object which is not yet serializable. As the documentation says. Let‘s begin by considering the Address class and making it serializable. Associated with the FileOutputStream will be an ObjectOutputStream. we can use FileInputStream and ObjectInputStream to retrieve and reconstruct the objects.

"RD". You‘re ready to create a unit test to confirm that an address is serializable. "Canada". The deserialization test. "". import java. Serializable That‘s it! Due to the simple nature of the instance variables of Address. In some cases (the instance variables are single-valued.dat"). implementing the Serializable interface is all you need to do to make a class serializable. public class Address implements Cloneable. Serializable is what is called a marker interface. Address a. 218 . public void testSerialization(){ int i = 0. Begin by creating two Address objects within the Address unit test.are Strings. Address a1. and modify the class heading to indicate the class implements the Serializable interface. you need do nothing else to make an Address object serializable. "BC". but it doesn‘t bring along methods and instance variables. "SE". i++. below.io. in the setUp method. Here is the unit test method to check that we can serialize these two Address objects. a1 = new Address("1000". "V1Y4X8"). look at the Serializable interface itself for its details. // write a second object and remember that oos. "T0L0M0").writeObject(a1). "CA". "". simply add a statement at the beginning of the class. It will attempt to write out the two objects and then check that two objects were really written. "AB". it says something about the class which implements it. ObjectOutputStream oos = new ObjectOutputStream(out). "Fifth". and are all serializable). a = new Address("1234". not collections. To make Address serializable. While you are looking in the Java documentation. try { FileOutputStream out = new FileOutputStream("address. // write one object and remember that oos. will check that the correct data was written. Examine the Java documentation to confirm that String does implement the Serializable interface. "Calgary".Serializable. "X". "Avenue".writeObject(a). "KLO". "Kelowna".

an Address knows how to serialize itself.io. } catch (FileNotFoundException e) { System.io. The writeObject method is a method in the ObjectOutputStream class. The asterisk is a wildcard.println("problem with address.toString()).‖ In this case. For this unit test to compile.dat " + e. } Note that in order to use serialization we must also use exceptions.*. make sure that you open the BlueJ Terminal window. // output may be held in memory until a buffer // is full. when you need to import many classes from one package.close().ObjectOutputStream.io. java.err. Before you run any methods which use exceptions. Here‘s a suggestion. Since an Address is made of serializable objects and Address implements Serializable. import java. 2).flush(). to just use import java. which we saw in the previous chapter. but not any packages within java.* means ―every class in the java.io. But it is easier.‖ Checkstyle will complain if you use a wildcard to import classes.io. A wildcard means ―any value that matches this pattern.println("problem with ObjectOutput " + e. The unit test uses the writeObject method to actually write an Address object. import java. so that the messages displayed in the catch clauses have a place to 219 . // we don‟t need the stream any more oos. } // check that we were able to write two objects assertEquals(i.toString()).err.io.FileOutputStream. We have no more output so ensure // the buffer is written to a disk somewhere oos. } catch(IOException e) { System.IOException.io package.i++. we need to include the statements import java. where any value can replace the asterisk.

should there be an error of some kind. public void testDeserialization() { try { FileInputStream in = new FileInputStream("address.readObject(). But note there is something unusual going on here. } catch (FileNotFoundException e) { System. To do this. or press + T.display. "Calgary"). Here is a unit test to check that we can deserialize Address objects. a = (Address)ois.err. by casting to an Address.) We can do this because both are Address objects. an error. you‘ll see that we serialized the two Address objects in one order (a and then a1).toString()). Usually this will not happen. If you look closely at the code. assertEquals(a.err. choose View. ois.println("Can not find address. // we use the same file name as in writeObject ObjectInputStream ois = new ObjectInputStream(in). The deserialization takes place at a later time. their order would be restored.dat " + e. a1 = (Address)ois. } The readObject method is a method in ObjectInputStream. } catch (IOException e) { System. after all the existing objects become null. or have ceased to exist.close().readObject(). It reads an object from the stream (throwing an exception. But serialization is not designed to work quite like this. Note that any method which casts an Object to some other datatype must handle a possible ClassNotFoundException.getCity(). when we recreated the collection. 220 .dat"). Both of these tests succeed.getCity(). but the casting process requires us to handle that possibility. We have talked about saving and then restoring an object. then we would have many objects in the stream. but restored them in the reverse order (a1 and then a. "Kelowna"). with one method serializing and another immediately deserializing. and we must then indicate the type of object. If we were to serialize a collection.toString()). Show Terminal. } catch (ClassNotFoundException e) { // will not happen but must be caught } assertEquals(a1. when the stream cannot be opened).println( "file problem with ObjectInput " + e.

In particular. The Person class is abstract. A Person object contains Strings (all serializable. only one in fact. We have seen some static constants. and a MyDate (not yet serializable. That will be implemented as a static class variable. all this involves is asking the class to implement the Serializable interface. by design).Object serialization – MyDate Recall that we began by discussing how to serialize a Person object. Since a MyDate object only contains single-valued instance variables. static class variables are accessible to all objects of the class. This is because they each contain collections. Student. Consider the interest rate paid on all bank accounts. they work when there are no static or transient variables (a fact not already mentioned). Professor Assuming the code you created to serialize MyDate (and perhaps Mark) works. an Address (now serializable). as they contain only single-valued instance variables with no collections. Create the unit tests to show the serialization and deserialization of MyDate objects works. but we know how to do that. and when there are no collections (a fact already mentioned). We will explore how to deal with the collections in a few moments. Object serialization – Meeting and Mark You may have implemented these two classes. since the rate changes from time to time but is common for all bank accounts. 221 . But that fact is not particularly useful to us right now. We have seen very few of them yet. Object serialization – Person. in the College class. they are like Address and MyDate. If so. Are they serializable? No. Object serialization – some subtleties The readObject and writeObject methods we have used so far work well for simple situations. static instance variables persist from one method call to another. Make it so. all the instance variables of a Person are now serializable. It is very easy to make them serializable. Person is the parent class of Student and Professor and we can create instances of Student and Professor.) Make the MyDate class serializable. we cannot create instances of a Person object.

we will need to provide replacements for writeObject and readObject. to use that technique we will need to write some extra methods. Object serialization – creating writeObject and readObject methods Some classes contain collections.ObjectInputStream stream) throws IOException. Like encryption. used to identify variables whose state should not be saved.io. ―Classes that require special handling during the serialization and deserialization process must implement special methods with these exact signatures: private void readObject(java.ObjectInputStream and ObjectOutputStream instead of java.But writeObject does not serialize static instance variables and thus readObject cannot deserialize them.ObjectOutputStream stream) throws IOException ‖ Assuming we have the appropriate import statements. We can handle collections on our own. a topic which we will not discuss further here.io. When we have static variables. we can just use ObjectInputStream instead of java. private void writeObject(ObjectOutputStream oos) throws IOException{ // write instance variables } // end writeObject 222 . The standard readObject and writeObject methods won‘t work with those classes. we will need to create our own methods to read and write objects.ObjectOutputStream. transient is a reserved word. We‘ll override those methods with our own.security package. In particular. usually because they can be calculated (like iterators or retirement dates). We can serialize static variables ourselves.io. using the appropriate write methods of the ObjectOutputStream class and the read methods of the ObjectInputStream class. How do we create our own readObject and writeObject methods? The signatures of these methods are specified in the ObjectOutputStream documentation as follows. or because they require special handling (like encryption). We can encrypt variables using the java. ClassNotFoundException.io. private void writeObject(java. We will need to deal with such variables on our own. so the skeleton for the writeObject method we need to create looks like this. too.

223 . corresponding to the students in the class. we could use. } where oos has been opened earlier. first writing the number of elements in the collection and then the elements of that collection. The Course class contains a collection of student identifiers. Similarly.writeObject(theStudents. for (Student s:theStudents) { oos.println("Unable to deserialize " + e. If we are serializing that class. private void readObject(ObjectInputStream ois) throws IOException { try { // read instance variables here } catch (ClassNotFoundException e) { System. we create our own readObject method. first.err. the ones which are not collections. } where oos has been opened earlier. for (String s:theStudents) { oos. This assumes Student objects are serializable. Set<Student> theStudents = new HashSet<Student>(). should there be any. This assumes student identifiers are serializable. they are since they are Strings.size()). we could use the following statement. i < n. Then I write the collections. we could use the following statement. they will be soon. for example. My style is to write out the singlevalued instance variables. This is a generic method and needs to be modified for each class in which we use it.readObject(). i++) { theStudents.toString()).readObject()).writeObject(s).writeObject(s).writeObject(theStudents. for (int i = 0. If we are serializing that class. in the College class.size()). oos. The only place that we should have a collection of Student objects is the College class.add((Student) oos. oos.The comment indicates where we write the instance variables. } } // end readObject To use this method. int n = (Integer) oos.

writeObject(s1). ObjectOutputStream oos = new ObjectOutputStream(out). i++. oos. perhaps as members of a collection. } catch(IOException e) { 224 .} Any special handling required by transient or encrypted variables will need to be included in the method as well. For both of these classes. One (theStudents) is a collection of student identifiers (serializable. illustrated below for the Section class. to the ones which contain collections.out. we use the same logic.obj " + e.toString()).println("s1 = " + s1. which is serializable. Section is a class which contains two collections. System. System. i++. Student is also a class which contains two collections. try { FileOutputStream out = new FileOutputStream("sections.obj").close(). in particular. Let‘s see how this applies to the classes we have developed.toString()).writeObject(s2). As we have seen in the examples above.err.flush(). which look after opening and closing the streams. both the readObject and the writeObject methods will be called by other methods. } catch (FileNotFoundException e) { System. oos. Object serialization – Section and Student Due to the similarities between these two classes we‘ll discuss them together.println("Problem with sections. the other (theMeetings) is a collection of Meeting objects (which we just made serializable). as well as extracting the objects and saving them with unique identities. Why?). the other (theMarks) is a collection of Mark objects (which we just made serializable). This class is derived from Person. oos. Following the idea of creating the unit test first.println("s2 = " + s2. One (theSections) is a collection of section identifiers (serializable.toString()). oos.out. public void testObjectSerialization() { int i = 0. Why?). we have the following method in SectionTest.

writeObject(s). oos.writeObject(departmentAbbreviation). in the Section class. oos.writeObject(startMonth). if (howManyMeetings() > 0) for (Meeting m:theMeetings) oos.writeObject(m). oos.writeObject(howManyMeetings()). oos. 2). The other appears as a private method in the Section class. // write the collections oos.writeObject(getStudentCount()). Much of it is taken up with processing the collections which are part of the object.writeObject(courseNumber). oos. oos. but how do you deserialize it? 225 . as private void writeObject(ObjectOutputStream oos) throws IOException The first is automatically translated into a call to the second.System. Run the unit test and confirm that you can serialize a Section.toString()). oos.println("Problem with ObjectOutput " + e.writeObject(endYear). One appears in testObjectSerialization as oos.writeObject(endMonth). } assertEquals(i.writeObject(s2). Now you can serialize a section. private void writeObject(ObjectOutputStream oos) throws IOException { // write the single-valued instance variables oos.err. if (getStudentCount() > 0) for (String s:theStudents) oos. }. } Now we can create the writeObject method itself.writeObject(identifier). Note that we have two writeObject methods.writeObject(startYear).writeObject(sectionNumber). oos.

readObject(). } catch (FileNotFoundException e) { System. this. assertEquals(s1. s2 = (Section)ois.startMonth = (Integer) ios.students = new HashSet<Student>(). i < n.readObject().sectionNumber = (String) ios. private void readObject(ObjectInputStream ios) throws IOException. s1 = (Section)ois.println("Can not find sections. Much of it is again taken up with processing the collections which are part of the object.readObject().startYear = (Integer) ios.readObject().close(). ObjectInputStream ois = new ObjectInputStream(in). this.obj"). "COSC"). } catch (IOException e) { System.endYear = (Integer) ios.err.toString()).identifier = (Integer)ios. this.readObject().readObject().readObject(). public void testObjectDeserialization() { try { FileInputStream in = new FileInputStream("sections.readObject(). for (int i = 0.endMonth = (Integer) ios.readObject(). this.getDepartmentAbbreviation().err. this.obj " + e. } catch (ClassNotFoundException e) { // will not happen but must be caught } assertEquals(s2. ois. this. int n = (Integer) ios.readObject(). this. ClassNotFoundException { // single-valued instance variables this.departmentAbbreviation = (String)ios.readObject().getDepartmentAbbreviation().courseNumber = (Integer) ios. } Finally. we create the readObject method itself. // collection instance variables this.toString()). i++) { 226 .println( "file problem with ObjectInput " + e. "PHYS").Object deserialization – Section and Student First we create the unit test for the readObject method.

Object o = ios.intValue().meetings = new TreeSet<Meeting>(Meeting. i < n.0 (also known as Java 5). collections contain objects. autoboxing and autounboxing. and then insert iObject into the collection. the first is translated into the second. In many places we need to convert primitive datatypes like int to their corresponding object. This appears a little unusual. We could convert an int variable i to an Integer object iObject with the statement Integer iObject = new Integer(i). We could extract the int from the object with the statement i = iObject. theMeetings.TIME_ORDER). The one in the testObjectDeserialization method appears in s1 = (Section)ois. Autoboxing carries out the first statement for us and thus makes it easier to convert primitive datatypes to the corresponding object. not primitive datatypes.readObject(). When would we need to do this? Well. this. } } Note that we again have two readObject methods. The one in the Section class is readObject(ObjectInputStream ios) Again. theStudents. 227 .readObject(). since the left side of the assignment statement is a primitive datatype and the right side is an object. Autounboxing carries out the second statement for us and thus makes it easier to extract primitive datatypes from objects. in this case Integer. i++) { Object o = ios. n = (Integer) ios.readObject(). } this.5.readObject(). for (int i = 0.add((Meeting) o). Note also that we have used statements like this.readObject(). Two new concepts were added to Java beginning with Java 1.add((String) o).identifier = (Integer)ios.

We will do so.Programming style Should you have one large data file which contains many objects of different types and you don‘t know the order of the types. Strings. As I review this section. Instead. We simply serialize a zero if the collection is empty.) Make Professor serializable. and it is not advisable. using individualized writeObject and readObject methods because of the collections. For example. It contains various collections so we had to wait until all their elements are serializable. Object serialization – Professor Since Professor is derived from Person (which is serializable). We will follow those standards. the sections are all in place and their meeting times have been set. (We mentioned adding some collections to a Professor object. In fact. we may be serializing a section before it has its meeting times determined and/or before students have registered. it is important to know that the file contains objects of only one class. The collection of courses taught in the past is a collection of Strings. we can make the College class serializable. not because they contain Strings. Our way of writing a collection (record the number of items in the collection. many programming standards forbid this use of instanceof. 228 . and they finally are. Object serialization – College Now that all the classes we have built are serializable. if any) accommodates this nicely. Professor objects are serializable. in particular. The collections require separate processing. and any additional instance variables (birthDate and retirementDate) are serializable. Make it so. Object serialization – Section and Student. it is better to have an idea ahead of time of the structure of the file. a course may not have any sections. and then the items themselves. but because they are collections. This gives rise to very complicated programs. particularly before the scheduling of those sections occurs. The collection of current sections taught is a collection of section identifiers. Similarly. revisited We may be serializing a class while its collections are empty. But the students don‘t start registering until next week. you may extract objects one at a time from the file and then use instanceof to determine the datatype of the object before you cast it appropriately.

229 .Summary In this chapter we have seen one way to save the state of our objects. In many cases it might be better if the file could be read by a program written in a language other than Java. Perhaps so that we could create printed material from the data we read. We‘ll explore a technique which allows this in the next chapter. Why would we want to do this? Perhaps so that we could create a webpage from the data we read. The problem with the particular technique is that it produces files which are only readable by another Java program.

230 . 5. Make the BankAccount class serializable. 2. Make the MyDate class serializable.Exercises 1. Make the class Sighting serializable. Make the Meeting class serializable. 8. Make the AngloAmericanPlayingCard class serializable. In a previous chapter we discussed modelling the sightings a birder makes.security package to see how you can encrypt data when you serialize it. Make the Mark class serializable. Explore the java. make it serializable. In a previous chapter we discussed modelling bank accounts. 7. Is the Transaction class serializable? If not. If you have implemented a Department class. make it so. 6. 4. In a previous chapter we discussed modelling playing cards. 3.

But it is a less-common technique. A Digression . In other words: XML is a way of describing data and an XML file can contain the data too. If so.org/wiki/XML) defines XML as follows: ―The Extensible Markup Language (XML) is a W3C-recommended general-purpose markup language for creating special-purpose markup languages.Scalable Vector Graphics Scalable Vector Graphics (SVG) files are an interesting application of XML files. What sort of picture? It could be as simple as a bar graph.Chapter 13 – Persistence. ―XML is a way of describing data and an XML file can contain the data too‖. Thus you can examine them in a text editor. or it could be an animated movie. Why would we wish to use XML? The files containing XML are plain text files. You can display XML files on the web. Is this chapter we will see that XML serialization is an alternative way to do this and much more. 231 .wikipedia. These contain the instructions to paint a picture. there is no problem. The serialization in the previous chapter allows us to store the structure of objects and to remember the data they contain.‖ We are particularly interested in the ―in other words‖ portion of that definition. written in different languages? And wouldn‘t it be great if a file were also human-readable? There is a way to do all that. It could be a logo. since that is what we wish to do. capable of describing many different kinds of data. the Extensible Markup Language. so you may have skipped that chapter. Wikipedia (http://en. as in a database. and it involves the use of XML. You can write programs to process the files containing XML in languages other than Java. part 2 Learning objectives By the end of this chapter you will be able to:   Define XML and describe its characteristics Implement persistence using XML Persistence via XML Wouldn‘t it be great to have a way to write a file so that it contained both data and a description of that data? What if a file could be read by many different programs.

XMLDecoder. Here‘s a method within the Address class which translates an Address object into XML. Using an XMLEncoder is similar to serialization with its writeObject method. Our classes are not JavaBeans. are different because they are in different classes. These methods. while sharing the same name. Note that these classes are designed for use with JavaBeans. classes which have a no-parameter constructor and setters for all instance variables. there must be some other code elsewhere. Since the method we created is very short. It‘s in the unit test. } // end writeXML This method is named writeObject and it calls a method also named writeObject.setContextClassLoader( 232 .beans. The advantage of them is that they are very small.beans.XMLEncoder. we will use an object of the XMLEncoder class. It translates an object into the instructions necessary to restore it and provides the value of the object‘s instance variables to be used when restoring it. public void writeObject(XMLEncoder e){ e. The class Address contains a writeObject method. which is associated with a file. and uses an XMLEncoder which has miraculously appeared from nowhere. Similar methods work with all of our classes which do not contain collections. import java. There are even pictures you can create using a Java program. public void testXMLSerialization() { Thread.writeObject(this). To carry out its task. Using an XMLDecoder is similar to deserialization with its readObject method.no collections To translate an object into the appropriate XML statements. search the web for terms like SVG and create. For more details on SVG files. it delegates responsibility to the writeObject method from the XMLEncoder class.You could create a picture using something as simple as Notepad or as complicated as Adobe Illustrator.beans package so we need to import them into any class which will be using XMLEncoder and XMLDecoder. To reconstitute the objects using the data and instructions in a file we will use an object of the XMLDecoder class. It processes the instructions the decoder created. but we‘ll convert them to JavaBeans in a moment. import java. Most modern browsers will display SVG graphics. Using an XMLEncoder .currentThread(). Both XMLEncoder and XMLDecoder are in the java.

we simply use that statement whenever we wish to use an XMLEncoder or an XMLDecoder. try { XMLEncoder e = new XMLEncoder( new BufferedOutputStream( new FileOutputStream("address.toString()). "X".5. it can prepare output for all instance variables which have setter methods. there are no setters for the collections.XMLDecoder"> <object class="Address"> <void property="city"> <string>Calgary</string> 233 .xml"))).html.eclipse.getClassLoader()). The heading lines may change as different versions of XML and Java appear. We need to do that ourselves and we will see how in a few moments. e.org/mhonarc/lists/gef-dev/msg00469. include this statement in any method which creates either an XMLEncoder or XMLDecoder object. "SE". // the variable a is an Address and has been // defined in the setUp method a.currentThread(). "Calgary". <?xml version="1. Your method will generate a ClassNotFoundException error. "Avenue".close().writeObject(e). We will explore threads in a later chapter. or perhaps using separate processors.getClassLoader()). Once the XMLEncoder is aware of the class it is processing. it‘s just values I made up. Without that line.setContextClassLoader(getClass(). Threads are a mechanism by which a program can be doing several things at once. } } Note the line that reads Thread. "Canada".getClass(). "AB". Suppose we create an address object with the statement Address a1 = new Address("1234".0_01" class="java. } catch (FileNotFoundException fe) { System. Note that when our objects contain collections. This hint was provided through an answer to a question at http://dev. "T0L0M0").err. so the collections are not output. For now. To avoid this error.0" encoding="UTF-8"?> <java version="1.beans. This is not a real address. the XMLEncoder is unaware of the class Address. "Fifth". The file created when we pass a1 to the XMLEncoder is shown below.println(fe. perhaps sharing a processor.

</void> <void property="country"> <string>Canada</string> </void> <void property="direction"> <string>SE</string> </void> <void property="name"> <string>Fifth</string> </void> <void property="number"> <string>1234</string> </void> <void property="postalCode"> <string>T0L0M0</string> </void> <void property="province"> <string>AB</string> </void> <void property="suffix"> <string>X</string> </void> <void property="type"> <string>Avenue</string> </void> </object> </java>

You can see how the file encodes the class name and instance variables. The <object> tag indicates the class of the object. The property tags indicate, in alphabetical order, the instance variables and <string> indicates the datatype of the instance variables. Other datatypes will appear when necessary. Each tag has its corresponding closing tag, beginning with </. You can display an XML file in a text editor (like Notepad), in a browser (like Internet Explorer or Mozilla Firefox), or in an XML editor (like XMLSpy) or, as noted earlier, you can write a program in some other language to read and display the contents of the file. Using an XMLDecoder - no collections Once we have created a file containing XML statements, we can create a method to retrieve information from it. An XMLDecoder works by assuming that you have a no-parameter constructor plus setters for all the instance variables. We don‘t have a no-parameter constructor yet, so we need to create one.
/** * no-parameter constructor for an Address, * used with XMLEncoder. */ public Address() {

234

}

This no-parameter constructor creates the object, but none of the instance variables have values. It might be better if we at least gave the instance variables the value of blank, or zero, or null, depending on their datatype. If the class contains any collections (this one does not), your no-parameter constructor must create them (as empty collections) too, as we will see in a few moments. Check that you have setters for all your instance variables. Check also that the name of the setter is the word ―set‖ followed by the name of the instance variable. If you need to rename any of your setters, change (and rerun, just to be sure) the appropriate unit test as well. Here is a method which retrieves a single Address object from the file address.xml, assuming the no-parameter constructor and all setters exist.
/** * restore an Address from XML. */ public void readObject(){ Thread.currentThread().setContextClassLoader( getClass().getClassLoader()); try { XMLDecoder d = new XMLDecoder( new BufferedInputStream( new FileInputStream("address.xml"))); Address a = (Address) d.readObject(); d.close(); // a has been created as a temporary variable. // now copy its contents to the variable we // really want. this.number = new String(a.number); this.suffix = new String(a.suffix); this.name = new String(a.name); this.type = new String(a.type); this.direction = new String(a.direction); this.city = new String(a.city); this.province = new String(a.province); this.country = new String(a.country); this.postalCode = new String(a.postalCode); } catch (IOException e) { System.out.println("Error reading address " + e.toString()); }// end catch return; } // end readAddressXML

If we used a statement like this.number = a.number; we would have two variables both referencing the same area of memory. By writing this.number = new String(a.number); we have

235

two variables, referencing different areas of memory, with the different areas containing the same data. We could use a clone method to copy the variables if we prefer. We can test this decoding with simple unit tests. Create two Address objects in the setUp method, containing different values. Then write one out, and retrieve its value into the other.
public void testXMLSerialization() { Thread.currentThread().setContextClassLoader( getClass().getClassLoader()); try { XMLEncoder e = new XMLEncoder( new BufferedOutputStream( new FileOutputStream("address.xml"))); a.writeObject(e); e.close(); } catch (FileNotFoundException fe) { System.err.println(fe.toString()); } } public void testXMLDeserialization() { Thread.currentThread().setContextClassLoader( getClass().getClassLoader()); try { XMLDecoder e = new XMLDecoder( new BufferedInputStream( new FileInputStream("address.xml"))); a1.readObject(e); e.close(); } catch (FileNotFoundException fe) { System.err.println("unable to create file"); } System.out.println(a1.toString()); assertEquals("addresses match", a.toString(), a1.toString()); }

Does this method work?
/** * Possible alternative to restoring an Address from XML. */ public void readObject(){ Thread.currentThread().setContextClassLoader( getClass().getClassLoader()); try { XMLDecoder d = new XMLDecoder( new BufferedInputStream( new FileInputStream("address.xml")));

236

Address a = (Address) d.readObject(); d.close(); // this part of the method is different! this = a; } catch (IOException e) { System.out.println("Error reading address " + e.toString()); }// end catch return; } // end readAddressXML

Why or why not? Using an XMLEncoder - with a collection Most of our classes include collections. The collections are instance variables which have neither setters nor getters. Instead, they have methods for adding elements to the collection. This lack of getters and setters causes problems with XML serialization, since the XMLEncoder and XMLDecoder use the setters and getters. However, Java provides an alternative mechanism we can use in this case, the DefaultPersistenceDelegate class. A DefaultPersistenceDelegate determines the statements the XMLEncoder produces for us. Unknowingly, we have been using a DefaultPersistenceDelegate, a simple one which assumes the class is a JavaBean, when we saved Address objects using XML. It knew what to do with the noparameter constructor, the getters, and the setters. But we must provide an alternative DefaultPersistenceDelegate whenever we are dealing with a class which contains one or more collections. Let‘s see how this works with the Section class. Remember that the Section class contains two collections, one (theStudents) of student identifiers and the other (theMeetings) of Meeting objects. First, we must make modifications to the Section class. Create a no-parameter constructor. This constructor creates the empty collections.
public Section() { this.theStudents = new HashSet<Student>(); this.theMeetings = new TreeSet<Meeting>(Meeting.TIME_ORDER); };

Then we extend the DefaultPersistenceDelegate class within the file containing the Section class. That is, Section.java will now contain two classes.
class SectionPersistenceDelegate extends DefaultPersistenceDelegate{

237

// create XML statements to define instance // variables and their values // each statement includes the method to be called and // its arguments, as an array protected void initialize(Class type, Object oldInstance, Object newInstance, Encoder out) { // single-valued instance variables Section s = (Section) oldInstance; out.writeStatement(new Statement(oldInstance, "setIdentifier", new Object[]{s.getIdentifier()})); out.writeStatement(new Statement(oldInstance, "setDepartmentAbbreviation", new Object[]{s.getDepartmentAbbreviation()})); out.writeStatement(new Statement(oldInstance, "setCourseNumber", new Object[]{s.getCourseNumber()})); out.writeStatement(new Statement(oldInstance, "setSectionNumber", new Object[]{s.getSectionNumber()})); out.writeStatement(new Statement(oldInstance, "setStartYear", new Object[]{s.getStartYear()})); out.writeStatement(new Statement(oldInstance, "setStartMonth", new Object[]{s.getStartMonth()})); out.writeStatement(new Statement(oldInstance, "setEndYear", new Object[]{s.getEndYear()})); out.writeStatement(new Statement(oldInstance, "setEndMonth", new Object[]{s.getEndMonth()})); // collections for (Student st:s.getStudents()) { out.writeStatement(new Statement(oldInstance, "addStudent", new Object[]{st})); } for (Meeting mt:s.getMeetings()){ out.writeStatement(new Statement(oldInstance, "addMeeting", new Object[]{mt})); } } }

238

Recall that the theStudents and theMeetings collections both have private visibility. To access their elements, we need two more methods in the Section class, getStudents and getMeetings.
public Set<String> getStudents() { return theStudents; } public Set<Meeting> getMeetings() { return theMeetings; }

As noted in an earlier chapter, it would be better style if we created iterators allowing us to access individual elements of the collections. Make it so. Finally we create a DefaultPersistenceDelegate object and attach it to the XMLEncoder we are using.
/** * save a Section as XML. * @param e The XMLEncoder which will create the file * @return nothing */ public void writeObject(XMLEncoder e){ // need a DefaultPersistenceDelegate because of // students and meetings e.setPersistenceDelegate(Section.class, new SectionPersistenceDelegate()); e.writeObject(this); } // end writeObject XML

That‘s it. Except of course there are some import statements we need.
import java.beans.DefaultPersistenceDelegate; import java.beans.Statement; import java.beans.Encoder;

Yes, there is a unit test which defines the file to which the XMLEncoder is connected.
public void testXMLSerialization() { Thread.currentThread().setContextClassLoader( getClass().getClassLoader()); try { XMLEncoder e = new XMLEncoder( new BufferedOutputStream( new FileOutputStream("section.xml"))); // create a Section object

239

// specific instance variables are not shown here // to save space // and save the object s.writeObject(e); e.flush(); e.close(); } catch (FileNotFoundException fe) { System.err.println(fe.toString()); } }

Now we are able to write a Section object to an XML file, sometimes called an archive. If you wish to see the XML file produced by the writeObject method, simply navigate to the folder or directory in which it was placed (the default is the one in which your project is located) and use any of the programs noted above. The file we have just created contains many lines, but is not that complicated. Here is sample output, describing a section containing four students, meeting twice a week.
<?xml version="1.0" encoding="UTF-8" ?> - <java version="1.5.0_01" class="java.beans.XMLDecoder"> - <object class="Section"> - <void property="identifier"> <int>123</int> </void> - <void property="departmentAbbreviation"> <string>COSC</string> </void> - <void property="courseNumber"> <int>111</int> </void> - <void property="sectionNumber"> <string>001</string> </void> - <void property="startYear"> <int>2005</int> </void> - <void property="startMonth"> <int>8</int> </void> - <void property="endYear"> <int>2005</int> </void> - <void property="endMonth"> <int>11</int> </void> - <void method="addStudent">

240

<string>3</string> </void> - <void method="addStudent"> <string>2</string> </void> - <void method="addStudent"> <string>1</string> </void> - <void method="addStudent"> <string>4</string> </void> - <void method="addMeeting"> - <object class="Meeting"> - <void property="dayOfWeek"> <int>1</int> </void> - <void property="endTime"> <int>1250</int> </void> - <void property="roomNumber"> <string>L322</string> </void> - <void property="startTime"> <int>1200</int> </void> </object> </void> - <void method="addMeeting"> - <object class="Meeting"> - <void property="dayOfWeek"> <int>3</int> </void> - <void property="endTime"> <int>1250</int> </void> - <void property="roomNumber"> <string>L322</string> </void> - <void property="startTime"> <int>1100</int> </void> </object> </void> </object> </java>

You can simplify the display somewhat (when you are using internet Explorer) by clicking the minus sign beside each line that begins <object class =

241

endMonth.with a collection The archive contains all the instructions necessary to reconstitute a Section object.theStudents.add(mt. To see more details about the instance variables of an object. this. this.add(st. this.endYear = s.theMeetings. } for (Meeting mt:s. /** * restore a Section from XML. <?xml version=‖1.5.This gives the following file.startYear.XMLEncoder‖> + <object class=‖Section‖> </java> The plus and minus signs are from the editor.sectionNumber = new String(s.<java version=‖1. unlike when we were using object serialization. for (String st:s.identifier.identifier = s. Using an XMLDecoder .departmentAbbreviation = new String(s.getStudents()) { this. this. The following method does the reconstituting. } The statement Section s = (Section) d.readObject(). click the plus sign. this.endMonth = s.startYear = s. this. To suppress the details.courseNumber = s. implements the instructions we placed in the archive to create a temporary object of the appropriate type and we copy that temporary object into our object. They tell us that the file contains an object of type Section and nothing else. click the minus sign which replaces the plus sign.sectionNumber).readObject().beans.courseNumber. * @param d The XMLDecoder being used */ public void readObject(XMLDecoder d){ Section s = (Section) d.clone()).0_01‖ class=‖java.startMonth = s. this.clone()).startMonth. 242 .endYear.0‖ encoding=‖UTF-8‖ ?> . this.departmentAbbreviation).getMeetings()) { this.

org/  An O‘Reilly (a publisher of well-received computer science books) website on XML. As these methods have different signatures. The code above shows how to deal with collections which are lists or sets. http://www. XSL is a stylesheet 243 .asp  A list of links and resources. to present our saved information in many different ways. http://www. http://www. http://xml.org. Similarly.com/  A collection of XML resources and tutorials. I have readObject (having an ObjectInputStream object as a parameter) and writeObject (having an ObjectOutputStream object as a parameter) methods in all my classes. Thus we need to use new String for Strings.Entry interface provides an easy way to retrieve the key-value pairs. If you have not implemented the clone method for Meeting. we actually have the ability. Programming Style I have adopted the practice of having readObject (having an XMLDecoder object as a parameter) and writeObject (having an XLEncoder object as a parameter) methods in all my classes. There is much more to learn in this area. http://www. The Map. The other instance variables are numbers. through the use of a technology called XSLT.org/  ―The Guide to the XML Galaxy‖. What about maps. now would be a good time to do so. if I had covered the previous chapter. primitive datatypes. We simply use an assignment statement for them.com/xml/default.xml. The corresponding unit tests are called testXMLSerialization and testXMLDeserialization. Using XML – summary This is only a brief introduction to using XML as a tool to provide persistence for objects.While copying elements from the temporary copy into our object.org/  XMLSpy. Java does not get confused. if we had any? One possible solution is to save each key-value pair. and then reconstruct the map.html Besides providing persistence. and the clone method for the Meeting objects. found at http://www. we ensure the object contains its own elements. The corresponding unit tests are called testObjectSerialization and testObjectDeserialization.coverpages.xml.org/XML  XML.w3. I find it useful to use the similar names for similar methods.zvon.altova.w3schools.com/xmlspy. not just references to the elements of the temporary copy.  The World Wide Web Consortium. http://www. Online sources you may wish to explore include the following.

com/javase/technologies/database/index. At Okanagan College. Summary This chapter covered what is perhaps the most-advanced topic in this book. it is time to look at how we allow the users to provide the data to create classes. we need to see how to build data entry screens. Now that we know how to create classes.com/docs/books/tutorial/essential/io/index. Persistence via databases There is another option to providing persistence. XSLT is XSL Transformations.sun. start exploring Java Database Connectivity at http://java. this is a third-year or fourth-year course. This is definitely a topic better left to another course.html. a language for translating one XML document into another. In particular. and how to persist them. If you are interested in this subject. 244 . Many will include this topic in an introductory course but I have chosen to omit it. Persistence via traditional files There is yet another option to providing persistence. This topic is much too complicated to consider in an introductory course. If you are interested in this subject. by writing data into a database. by writing data into a series of traditional files. start by exploring the Java IO tutorial at http://java.language for XML.sun. But it is a topic which will become more and more important as the role of XML increases.

w3. Implement the XML serialization of a Sighting. 6. 3. In previous chapters. 4.sun. In previous chapters. Remember that we have about 10 different classes from which you can choose.org/Style/XSL/ Explore the topic of using databases to persist Java objects. You will need it for the Student class when you use XML to persist the College class. A good place to begin is http://www. we discussed modelling the sightings a birder makes. A good place to begin is http://www. Implement the XML serialization of a Transaction. you would need to implement XML serialization for all of the classes. A good place to begin is http://java. if this were a real model. Implement the XML serialization of a BankAccount.com/javase/technologies/database/ 2.Exercises 1. we discussed modelling a bank account. Explore the topic of Scalable Vector Graphics. 245 . Implement the XML serialization of a YardList. Of course. Check your knowledge of XML serialization by using it with some of the other classes we have in our college model. 5. Implement the clone method in the Student and Meeting classes.org/Graphics/SVG/ Explore the topic of XSL and XSLT. 7.w3.

246 .

Chapter 14 . I feel we should also look at how the objects receive their values in the first place.‖ 247 . We need to explore the world of the graphical user interface. they won‘t always have their values defined in unit tests. While BlueJ uses windows and buttons. An alternative name which is becoming common is ―user experience. since we have been discussing saving and retrieving objects. After all.Creating a GUI – Data entry screens. We need to develop a way in which the program can present a prettier face to the world. no buttons. Use Swing components to create data entry screens Describe some of the considerations involved in data entry screen design Describe the role of a layout manager in creating data entry screens Use a layout manager to create data entry screens Use ActionEvents and ActionListeners Use InputVerifiers Warning to the reader This chapter and the two following it contain information which some people feel should not be in an introductory course. the code we have been creating has no windows. However. part 1 Learning objectives By the end of this chapter you will be able to:        Describe the parts of a Graphical User Interface. I disagree. and no labels. Introduction You may have noticed that the way we have been running our program is not the way you normally run a program. You may omit these three chapters should you wish.

and JPanel. and different versions of Windows have a different look and feel. ―A placeholder name for any unspecified device or good‖ and ―a component of a graphical user interface that the user interacts with. which divide the interface into logical sections.  Panels. work the same on all platforms. with several meanings.‖ The two names are actually related. which provide a way to enter commands using a mouse or other pointing device. The toolkit you use to build a GUI provides the widgets. 248 . These parts are standard (although the terminology may change somewhat) regardless of the language you are using to create the GUI. some progress bars have square ends while others have rounded ends. JPanel. JMenuItem. JCheckBox. the widgets in Swing all have names beginning with the letter J.swing package. GUIs are built using a toolkit of predefined widgets. this package ―Provides a set of "lightweight" (all-Java language) components that. JButton. When I looked up the word in Wikipedia (on 2006-05-23). In case you missed it. the widgets mentioned above are called JFrame. it provides a specific style of widget. Windows programs have a different look and feel from those designed to run on a Macintosh. The toolkit we will use is called Swing. To quote from the documentation.  Checkboxes. Even within Windows. to the maximum degree possible.GUI A graphical user interface (usually abbreviated GUI and pronounced ―gooey‖) is one way by which we can enter data that exists in the real world into the program we have created. which allow you to make zero or more choices from a collection. Within the Swing toolkit. and checkboxes‖. JMenu. The major parts of a GUI are:  A frame which contains all the pieces of the interface.  Radio buttons.  Labels. In addition to these widgets we will (in later chapters) use JApplet. which identify data you should provide.‖ That is. or AWT) contained widgets which used code that was dependent on the processor you were using. rather than refer to ―labels. JMenuBar. JTextField. ―Widget‖ is a generic term. I found two appropriate meanings. you might simply call them widgets. and JRadioButton. which allow you to make a single choice from a collection.  Textboxes.  Buttons. radio buttons. and  A layout manager.‖ An earlier toolkit (Abstract Window Toolkit. JLabel. but it also provides a ―look and feel. which models that real world. which provide a space where you provide data. which helps you position all the parts of the interface. and is available in the javax.

you may not see colours the same way others see them. random (or non-columnar) arrangements are bad. and they should be in standard places. http://www. are colour-blind. It‘s okay when the top of the screen contains more than the bottom. and top to bottom.Layout managers are not widgets. particularly men. That means that the important information a user must enter should be at the top.‖ A container is something (like a JPanel or a JFrame) into 249 . neatness counts. Don‘t present an interface suitable for a Macintosh unless the computer actually is a Macintosh. but garish is not nice. which we will explore in the next chapter. Columns are good. Commonly.  Most Western cultures read from left to right. The left and right sides of a screen should be balanced with approximately the same number of visible widgets and the same amount of whitespace (the background) on each. should use standard terms. It also means that those rules don‘t apply when your market is a culture that is not Western. It also means that a product designed for international use should be customizable.  Colours are nice. A cluttered screen is not good. Menus. Your mother was right. Many people. Help is the last. it confuses people. When you are colour-blind. and any buttons should be at the bottom. Here is a brief list of some of the HCI issues you should consider. The Wikipedia article on color blindness goes into a great deal of detail on this subject. A common problem is an inability to distinguish between red and green. Some prefer to call it CHI. so pay attention to the colours you use. Java is designed to run on many different operating systems.) Whatever the abbreviation. SIGCHI. Some HCI considerations HCI is an abbreviation of Human-Computer Interaction. a layout manager ―[d]efines the interface for classes that know how to lay out Containers. (One such group is the ACM‘s Special Interest Group on Computer-Human Interaction.sigchi. the field involves decisions you should consider when building an interface which will be used by a person to interact with a computer. so the GUI for your program should respect that. File is the first item on a menu. What is a layout manager? To once again quote the Java tutorial.org/. Balance is good. A layout manager helps us to follow these rules.     Layout managers Some of the rules above affect the positioning of widgets within your frame.

Of course.) GridBagLayout is considered the most complicated layout manager.which you can place widgets. South. all of the same size. and Center. It divides the frame into equal-sized rectangles. You might consider using GridLayout to divide the frame into a single column of rectangles. widgets may move from one line to another. This could be confusing for many of the people using your GUI. Because the rectangles are the same size. the next widget will simply continue onto the next one. 4)). including other containers. some very simple and some very complicated. or at fixed percentages from the left and top of the surrounding container. GridBagLayout is useful when you are creating a more complicated screen. a ® telephone. It places its widgets in left-to-right (or right- to-left. GridLayout might be useful should you be creating a Minesweeper -clone. This can be useful. it will also serve for multiline layouts. we won‘t be using GridLayout here. where we design a screen that has three sections. 250 . and a layout manager controls the placement of those widgets. East.setLayout(new GridLayout(5. It can be useful if you are placing checkboxes beside each other. FlowLayout also works for columns of widgets. North. I prefer a layout manager which lets you place widgets in relation to one another. If there are too many widgets on one line. We will use FlowLayout only in special situations. We will use this layout in a later chapter. Consider the buttons on the left side of the main BlueJ window. Of course. the rectangles will be the same size. Ideally. and that doesn‘t lend itself to the type of GUI we will be building. South. but it is very complicated to use. should you choose) order. (Search the web for Java GUI builder to get an idea of what is available. for example. or a chess game. BorderLayout breaks its container into five regions. a calculator. You will find the screen divided into 20 small rectangles. Java provides a couple of choices. and allows you to place widgets in each. and Center regions. I‘ll bet they are laid out using a FlowLayout layout manager. There are many different layout managers. which we can conveniently place in the North. you will find a tool which lets you draw the screen and then creates the appropriate Java code for you. For example. This can be very useful when you are placing a series of buttons side-by-side. FlowLayout is one of the simpler layout managers. if you resize the container. West. if you have a JFrame called jf and you use GridLayout jf. place the buttons on your screen in the South region. While this layout manager is often used for widgets in a single line. Again. five rows each containing four rectangles.

onjava. Click one and then choose Open.com/p/relativelayout/. However. The name appears in the list of libraries. but easier-to-use. To let BlueJ know that the jar files are available.4. which matches the way I think but is not supplied by Sun. you can open it with a standard compression program. Java also provides the SpringLayout class. Installing the RelativeLayout layout manager To use this layout manager.html While this layout manager has many features. but the documentation for this class clearly advises against writing code using SpringLayout. is RelativeLayout.google. simply by providing a new library which implements that feature. The webpage describes the layout manager using these words. ―RelativeLayout is a free layout manager for Java SE 1. Repeat for the other. described several years ago at http://www. Choose Ok. everyone has his or her own idea of the way it should be done.2). like SpringLayout.5. You can think of it as a zipped file of classes. and virtually any interface you can imagine can be easily created this way. Preferences. A jar file contains compiled Java classes. A more-detailed explanation about how this layout manager works is at http://www. note where you save them. and GridBagLayout.html?page=1.‖ One of the strengths of Java is that you can add new features to it.‖ This and the subsequent two chapters will use the layout manager from Google. In fact. if only to understand the underlying principles. Rather than relying on grids or nested boxes. we won‘t use them here. ―Due to the painstaking nature of writing layout code by hand.0 and higher (with limited support for Java 1. RelativeLayout lets you lay out components relative to each other and the window that contains them.GroupLayout is described in the Java tutorial as ―… a layout manager that was developed for use by GUI builder tools. 251 .google. but it can also be used manually. you need to download two jar files from http://code.onjava. One layout manager.‖ Yes. there are builder tools which will assist us in laying out a GUI. However. using this layout manager requires attention to detail. Choose Add. This turns out to be a much more intuitive way of going about it.com/pub/a/onjava/2002/11/27/layout2.com/pub/a/onjava/2002/09/18/relativelayout. Navigate to the jar files. choose Tools. it is strongly recommended that you use the SpringLayout layout manager combined with a builder tool to lay out your GUI. if you want. Libraries. it is also a little challenging to use. That‘s why there are so many layout managers. GroupLayout.com/p/relativelayout/. The experience of laying out a GUI yourself is something everyone should do at least once. A similar. layout manager is available from http://code.

You will want to review the website cited above to have some idea how to use RelativeLayout and its bindings (or constraints. what we will be doing is identifying widgets and then positioning each in terms of the container and/or the other widgets in the container. RelativeLayout is shown as being available. Should you be a cautious person. Yes. I unzipped mine and saved it somewhere I could find it again. just as I do with all other Java documentation. and JTextFields in a second column providing space to enter the data. Actually. How the data entry screen should appear How should our data entry screen look? Let‘s make something simple. 252 . JLabels in one column identifying the data to enter. Note that this GUI would not be part of a real program. Perhaps it would look something like this. it is being used simply as a teaching device. Which is our simplest class? That is.A message box appears. choose Tools. so I can refer to its documentation. what it means is ―You can‘t use RelativeLayout until you restart BlueJ. Download the jar file. Preferences. which has the fewest instance variables? I think MyDate provides a good example of the process of creating a simple GUI. We don‘t need the source code (unless we are curious) but we need the documentation which comes with the source code.‖ So exit from BlueJ and restart it.) To summarise. the one that contains the source code for the layout manager. Libraries again. Creating a data entry screen For our first data entry screen we should begin with a simple example. you should download a third jar file.

import java. here are the import statements. The first of these additional statements provides the widgets we will be using. here are the additional import statements we need. These are ―better‖ widgets than those in the Abstract Window Toolkit.cmu. import javax. import edu. This provides the layout manager and its associated components.*. The first is that there is probably too much space between a label and its textfield.*. or AWT.matrix.*.There are several things wrong with this illustration.event. Import statements To use the RelativeLayout layout manager.relativelayout. 253 . The second provides the AWT events to which we can respond. More details on events will be given later. Can you spot the other errors? There at least two.relativelayout.swing.cmu.awt.*. To use Swing components. import edu.

setLayout(new RelativeLayout()). Finally. // add the constraints to the collection labelYearConstraints. the constraints are relative to the JFrame or to other widgets. the JLabels. Binding topEdge = bf. // Bindings (constraints) // leftEdge is relative to the last leftMargin // established. and minimize. first create the JFrame and attach a layout manager to it. // a collection of constraints RelativeConstraints labelYearConstraints = new RelativeConstraints().addBinding(leftEdge). Binding leftEdge = bf. /** * create a JFrame to allow data entry. // create the first label JLabel labelYear = new JLabel("Year – four digits"). maximize. For each widget you wish to add to the JFrame. and the JTextFields. To summarise the process. As we are using a relative layout. */ public static JFrame buildFrame() { // create a frame JFrame jf = new JFrame("Enter MyDate").topEdge(). Below is a method to create the JFrame.the JFrame (including a title bar.setDefaultCloseOperation( JFrame. and the textfields (implemented as JTextFields). // create a RelativeConstraints object. the labels (implemented as JLabels). // and set its layout manager jf. the default is the left edge // of the frame. 254 . // ditto for top edge.HIDE_ON_CLOSE). and exit buttons). // create a BindingFactory to create various // Binding objects (constraints) to control the // position of the widgets BindingFactory bf = new BindingFactory(). The method is explained line-by-line on subsequent pages.Creating the JFrame We begin by creating what we see .leftEdge(). jf. create the widget and the constraints which specify its location. attach the widgets to the JFrame and the constraints to the layout manager.

textYearConstraints. 255 .add(labelYear. labelDayConstraints). textYearConstraints. // and place it below the first // using just the first statement below has the // effect of making the left edge at the edge of // the Frame.addBinding(topEdge). leftEdge = bf.add(labelMonth.add(labelDay.addBinding(topEdge).addBinding(topEdge). // this Binding makes the two labels share // a common left edge leftEdge = bf. labelMonthConstraints. // second label JLabel labelMonth = new JLabel("Month – two digits"). textYearConstraints).topAlign(labelYear). RelativeConstraints labelDayConstraints = new RelativeConstraints(). labelMonthConstraints).addBinding(leftEdge).addBinding(leftEdge). // third label JLabel labelDay = new JLabel("Day – two digits").setLeftMargin(200).add(textYear. RelativeConstraints labelMonthConstraints = new RelativeConstraints(). leftEdge = bf. jf.leftEdge(). labelYearConstraints). labelDayConstraints.below(label2). jf. // add the label and its constraints to the // frame jf. topEdge = bf. labelMonthConstraints.leftAlignedWith(label1). RelativeConstraints textYearConstraints = new RelativeConstraints().leftAlignedWith(label2). labelDayConstraints. // top edge is aligned with its label topEdge = bf. topEdge = bf.labelYearConstraints. // textfields will begin 200 pixels from the // left edge of the frame bf. jf. // firstTextfield (year) JTextField textYear = new JTextField(4).addBinding(leftEdge).addBinding(topEdge).below(label1).

addBinding(topEdge).setPreferredSize(new Dimension(500.addBinding(leftEdge). leftEdge = bf.pack(). 300)). } 256 .topAlign(labelMonth).addBinding(topEdge). leftEdge = bf. jf. // ditto for a third textfield (day) JTextField textDay = new JTextField(2).exit(0). /** * show the Frame.setVisible(true).add(textMonth.// ditto for a second textfield (month) JTextField textMonth = new JTextField(2). topEdge = bf. textMonthConstraints). textDayConstraints). box.topAlign(labelDay). System. textDayConstraints. textMonthConstraints. textMonthConstraints.leftAlignedWith(textYear). topEdge = bf. */ public static void showFrame() { JFrame box = buildFrame(). } Making the JFrame visible Finally. RelativeConstraints textDayConstraints = new RelativeConstraints().leftAlignedWith(textYear).add(textDay. RelativeConstraints textMonthConstraints = new RelativeConstraints(). 100). while (box. box. box. here‘s a method to create and make the JFrame visible. jf.addBinding(leftEdge). // done return jf. box.isVisible()). textDayConstraints.setLocation(100.

Notice that building a frame and displaying it are done in two separate methods.‖ // create a BindingFactory to create various // Binding objects (constraints) to control the 257 . is a window that typically has decorations such as a border. The package documentation says ―A Binding represents a dependency of some component's position on the position either of another component or of the surrounding container.setDefaultCloseOperation(JFrame. Thus it will be available quickly should we need it again. The package documentation says ―A factory for quickly creating Bindings to lay out simple interfaces. The RelativeLayout layout manager will interpret those rules for us.HIDE_ON_CLOSE).‖ I see a BindingFactory as a class which creates bindings to our specifications. Associated with the JFrame are the rules that govern the placement of widgets in the JFrame. BindingFactory I see a Binding as an instruction which the layout manager uses to control the positioning of widgets.setLayout(new RelativeLayout()).‖ The JFrame we create has the title ―Enter MyDate.Explaining the code Let‘s examine these methods in some detail. We‘ll give a few lines of code and then explain them. the JFrame will hide itself. a title. as implemented by a layout manager. and buttons for closing and iconifying the window. The layout manager jf. The JFrame Let‘s begin with the creation of the JFrame. You have seen frames whenever you have used a computer with a windowing system. When you click the X button in the top right. implemented as an instance of the JFrame class. Applications with a GUI typically use at least one frame. It also tracks the relationship between widgets.‖ jf. The Java tutorial says ―A frame. final JFrame jf = new JFrame("Enter MyDate").

the default is the left edge // of the frame. The label Bindings // Bindings (constraints) // leftEdge is relative to the last leftMargin // established. Binding leftEdge = bf.) But neither naming strategy is a good one.getBindingFactory().topEdge(). we begin to create and place widgets. Create the bindings related to the position of the widget. and so on. Singleton allows you no access to the constructor.// position of the widgets BindingFactory bf = new BindingFactory(). BindingFactory bf = BindingFactory. beta. Since this is a relative layout manager. Binding topEdge = bf. In the code above. I suppose you could name them after the letters in the Greek alphabet (alpha. // ditto for top edge. But one or more widgets 258 . and Louie. there should be a label. When you look in the documentation for BindingFactory. (Perhaps it‘s time for a joke about getting your ducks in a row. we create a JLabel containing the words ―Year – four digits‖. The most common bindings are those which specify the top edge of the widget and left edge of the widget. The labels Continuing through the method. // create the first label JLabel labelYear = new JLabel("Year – four digits"). BindingFactory has two constructors you can use.leftEdge(). after Donald Duck‘s nephews. The way in which we create and place widgets is the same for all widgets. We create two bindings to describe the position of the JLabel. If you had only three widgets I suppose you could name them Huey.) If you had many widgets. delta. you‘ll find there is a default BindingFactory object and you can access it. o o o Create a widget. Thus. and Add the widget and those bindings to the container‘s layout manager. we usually position widgets relative to other widgets. the last statement above could be replaced with this one. This is different from the Singleton pattern. starting with a label. For each piece of data we wish to enter. gamma. Dewey.

JLabels have a default height.addBinding(topEdge). Once we have created the bindings for the label.must be anchored to the frame itself. 10% of the way down the JFrame. depending on the direction of motion. we place those labels in a collection. labelYearConstraints). This could be modified. and their width expands to display the contents. The first binding (constraint) positions the left edge of the JLabel a certain number of pixels from the left edge of the JFrame. The second binding positions the top edge of the JLabel a certain number of pixels down from the top edge of the frame. note that we are positioning the widget in an absolute position. it does not appear that this layout manager supports that method of placement. we add the label and its collection of bindings to the frame. When the JFrame is made visible.addBinding(leftEdge). // a collection of constraints RelativeConstraints labelYearConstraints = new RelativeConstraints(). We could create bindings describing the height and width of the JLabel but there is no need to do so. See the setLeftMargin method within the BindingFactory class. 0) in this measurement system. // add the constraints to the collection labelYearConstraints. The upper left corner of the JFrame is the origin (or 0. say. Unfortunately. Similarly any negative number represents measurement to the left or up. We use this first JLabel as the anchor and then position other widgets relative to it. we can place the other widgets relative to the anchor. it may be better to position it. you could modify it if you wanted more or less space between the widget and the edge of the form.add(labelYear. the layout manager will process all the bindings and position the widget properly. Finally. Also. If we specify numeric pixel values (as we will soon). // create a RelativeConstraints object. Now that we have our first widget anchored relative to the frame. labelYearConstraints. a positive value represents measurement to the right or down. // add the label and its bindings to the // frame jf. 259 . This margin is the default value.

add(labelMonth. giving it enough space to accommodate four characters. jf. RelativeConstraints labelMonthConstraints = new RelativeConstraints(). we create the collection of bindings.leftAlignedWith(labelYear).below(labelYear). topEdge = bf. saying. How would you do that? Finally. so is omitted here. Textfields Once we have the JLabels in position. leftEdge = bf. This problem usually comes when we are sloppy in our cutting and pasting. Now we create another JLabel. We need to create a binding describing its top edge. whenever we provide too little information or inconsistent information about the positioning of a widget. labelMonthConstraints). in which you will enter data. jf. How much below is a based on the height of the label. ensuring its left edge lines up with the left edge of the previous label. in this case. and don‘t change all the names we need to change. The layout manager will tell us. the BindingFactory determines the precise value. We create the JTextField.The other labels JLabel labelMonth = new JLabel("Month – two digits"). The code to create the third JLabel is almost identical to the code for the second.addBinding(leftEdge). Finally we add the label and its collection of bindings to the frame. this one representing the month. labelMonthConstraints. thus leaving one of the bindings attached to the wrong widget. labelMonthConstraints. via InconsistentConstraintExceptions and AmbiguousLayoutExceptions. 260 . after all. JTextField yearText = new JTextField(4). we deal with the JTextFields.addBinding(topEdge). This width of four characters is based on the average width of the characters in the font you are using. that it is below the year JLabel. We create a second binding.add(labelMonth. labelMonthConstraints). Note that some people prefer to have the right edges of the labels line up.

RelativeConstraints textMonthConstraints = new RelativeConstraints(). We have used the first.addBindings(topEdge. repeated for all widgets. we could have used textMonthConstraints. the width of a label is determined by the typeface and point size. leftEdge). textMonthConstraints).addBinding(leftEdge). The second step is actually a series of steps. 261 . Finally. textMonthConstraints. Done! Once we have created the JFrame.setLeftMargin(200). We create the appropriate bindings. The first step is to create a JFrame and associate a layout manager with it. Thus. But there is also addBindings which allows us to add more than one Binding. In the same way.a ―W‖ is wider than an ―I‖. leftEdge = bf.  Create a widget which we wish to place on the frame. Note that RelativeConstraints contains two methods for adding Bindings. Their top edges are aligned with the correct labels. A more complete version appears in the next chapter. jf. Other textfields Similarly. // top edge is aligned with its label topEdge = bf. // textfields will begin 200 pixels from the // left edge of the frame bf.leftEdge(). The order in which we add the bindings does not matter. Thus the actual width (in pixels) may vary depending on the typeface and point size you are using. we add the textfield and its collection of bindings to the frame. we place the other two JTextFields on the content pane. and their left edges are aligned with previous textfields. Summarizing building a data entry screen This is a simplified version of the process.addBinding(topEdge). textMonthConstraints.topAlign(labelYear). which adds one Binding to the collection. we return it to the calling method. and add them to the textfield‘s collection of bindings.add(textMonth. a font is the combination of typeface and point size.

awt. Simply change the parameter to false. We have not specified its location of the screen. 100 pixels down from the top of the screen).setPreferredSize(new Dimension(500. First we create the JFrame using the method we just finished examining. 300)). 100). Add the widget and its collection of bindings to the frame.Dimension. Create a collection for the bindings and add the bindings to the collection. Make it visible box. and 1/3 its height. We specify the location of the top left-hand corner of the frame (100 pixels in from the left edge of the screen. so the JFrame will be approximately 1/3 the width of the screen. There may be times when you wish to make it invisible. giving it the name box. If you are using a resolution larger than this. Displaying the frame Note that we have not yet specified the size of the JFrame. You might say we have created the blueprint for the JFrame and now we need another method to size and position it. Position and size the frame box. your JFrame will occupy less of the screen. your JFrame will occupy more of the screen. 262 . As I write this. We specify its size (500 pixels wide by 300 pixels high. and to make it visible. I‘m running my screen at 1680 by 1050 resolution. box.setVisible(true). Create the frame JFrame box = buildDataEntryFrame(). as something else becomes visible. And then we make it visible. Let‘s examine its statements. If you are using a resolution lower than this. import java.   Create the bindings for the widget. We have not even made it visible.) You‘ll need another import statement here.setLocation(100. The showDataEntryFrame method does that.

Depending on your screen resolution and the size of the frame.isVisible()) {} The while loop simply ensures the JFrame remains visible until we click the X in the top right corner to dismiss the frame. 263 . Of course.Keep it visible while (box. the program exits gracefully.exit(0). how do you place a widget 10% of the way down the JFrame? My reading of the documentation for this layout manager tells me that we cannot do this. right-click the class in the class diagram. we must set the preferred size of the JFrame. And once the frame disappears. How do we change the position of the JFrame when it appears? First. Normally. Displaying the frame Compile MyDate. The left edge of the JFrame is 700 pixels from the left edge of the screen. 400). of course. placing the JFrame near the top left corner of the screen. having the left edge at 700 pixels may mean that part of the frame is invisible since it is off your screen. the mouse (or other pointing device) is available to resize and reposition it. This is something we have given up in favour of a simpler-to-use layout manager. Exit System. I would use setLocation with small values (like 100) for the arguments. should the person using your program not like the size or position of your frame. and the top of the JFrame is 400 from the top of the screen. box. Answering some questions How do you place a widget without using pixel numbers? For example.setLocation(700. and run the showDataEntryFrame method. The following statement gives a specific location on the screen.setLocationRelativeTo(null). box. Once that is done. the following method call places the frame in the centre of the screen.

not by taking your hands off the keyboard to click the one you want.MAXIMIZED_BOTH). and what about editing the data provided? 264 . How do we use hot-keys to move to a specific JTextField? Sometimes.setDisplayedMnemonic(KeyEvent. I feel it is not a good idea to start a frame full-size. and then use the statement box. There are two biggies – what about buttons (did you notice they were missing from the frame we built?).setExtendedState(Frame. If you wish the frame to start minimized. But these are minor questions. Should you wish to ignore this advice (and many programs do). For example. box.VK_Y). textYear. We first specify the mnemonic. Hot-keys allow you to do this. not by tabbing through the others. indeed obscuring. you have many widgets on the screen and you wish to move to a specific one. the letter in the JLabel caption which is to be underlined (if your interface underlines mnemonics) and which will function as a hot-key. labelYear. Here we assign Y as the mnemonic representing year.setToolTipText ("Please enter the year . You just want to press a combination of keys which will take you to the correct widget. It‘s rude.setExtendedState(Frame.Is it appropriate to have the labels contain prompts about the corresponding JTextFields? No. the cursor will move to the JTextField. labelYear.Frame class and then use this statement. intruding on.Frame class if you have not already done so. import the java. Then specify the JTextField with which the JLabel is associated.setLabelFor(textYear). small balloons of text that appear when the mouse hovers over the JTextField. it isn‘t.awt. whatever a person is doing.awt. It‘s much better to use JToolTips.four digits"). import the java. you may wish to remove the hint from the label and add this statement to your method. The documentation of the KeyEvent class lists all the mnemonics you may use. and the How do I start the frame full-screen? Minimized? In general.ICONIFIED). When you press mnemonic.

Buttons The JFrame we created is quite unusual. 10.addBinding(buttonCancelRight). When we create a button. This caption may be specified here. buttonCancelConstraints. and o Add the widget and those bindings to the container‘s layout manager.BOTTOM. Edge. It has JLabels and JTextFields. Create the collection to hold the bindings. Direction. Notice how the parameters in the method calls match the wording in the English statements. jf). Create the button JButton buttonCancel = new JButton("Cancel"). 25. the right edge of the button is 25 pixels to the left of the right edge of the frame. Edge.LEFT. o Create the bindings related to the position of the widget. Create the button’s bindings Binding buttonCancelRight = new Binding(Edge. The button is placed near the bottom of the frame.addBinding(buttonCancelBottom). Cancel button Let‘s create the Cancel button first. o Create a widget. We would expect at least an OK button and a Cancel button. Note the idiom we have seen throughout this chapter. In particular. 265 .RIGHT. but it has no JButtons. or it may be retrieved from a resource bundle. buttonCancelConstraints.ABOVE. Direction.BOTTOM. The bottom edge of the button is 10 pixels above the bottom edge of the frame. Binding buttonCancelBottom = new Binding(Edge.RIGHT. jf). we provide its caption. RelativeConstraints buttonCancelConstraints = new RelativeConstraints(). And place the bindings in the collection. off to the right.

At this point.addBinding(buttonOkayRight).LEFT. jf.getRootPane(). we have only one button so of course it is the default button. buttonOkayConstraints.topAlign(buttonCancel). This is exactly the same process we used with all our other widgets. The default button And one of the buttons should be the default. Place it to the left of the ―Cancel‖ button.setMnemonic(KeyEvent. in this case the letter C. Button action What should happen when we click the Cancel button (or press )? The same actions as when we click the X button to exit the JFrame. buttonOkayConstraints. The OK Button We use similar statements to create an ―OK‖ button.add(buttonCancel.LEFT. But when we have many (two or more) buttons the default button is usually the one which causes the least damage when it is pressed accidentally. // tops of the two buttons are aligned Binding buttonOkayTop = bf. buttonCancel). // right edge of the button is 10 pixels to // the left of the right edge of buttonCancel Binding buttonOkayRight = new Binding(Edge. 266 .addBinding(buttonOkayTop). buttonCancelConstraints). Create a mnemonic Buttons have mnemonics too. Edge. Direction.Add the button and its bindings to the frame jf.VK_C).setDefaultButton(buttonCancel). buttonCancel. How we make this happen is shown below. RelativeConstraints buttonOkayConstraints = new RelativeConstraints().RIGHT. 10. the button which will be deemed to have been clicked when you press .

for each of our buttons. let‘s have it just tell us that it has been clicked. What does an ActionListener do? When an action occurs.addActionListener(buttonCancelActionListener). Let‘s begin with an ActionListener for the cancel button. and has the responsibility of doing something in response to the ActionEvent. and ActionListeners How do we tell that a button has been clicked? This leads us to the world of ActionEvents and ActionListeners. Creating an ActionListener We need to create an ActionListener. an ActionEvent occurs. ActionEvents. When an ActionEvent occurs. ActionListener buttonCancelActionListener = new ActionListener () { public void actionPerformed(ActionEvent e) { // do something } }. A JTextField which has focus allows input. using FlowLayout. Linking an ActionListener to a JButton We need to connect the ActionListener to each JButton. the ActionListener notices. an object which processes ActionEvents. the component containing the widget is notified. The ActionListener will be notified each time the JButton is clicked. We may need them for our textfields. When a JTextField gains or loses focus.Alternative layout managers We have used RelativeLayout to place these buttons. Replace // do something 267 . When a button is clicked. an ActionEvent occurs. buttonCancel. What should happen when we click the cancel button? For now. A later example will show how to place them within a JPanel.

as a promise that the setters and constructors will not be changing the values provided to them. Go back through your code and ensure the parameters for your setters and constructors are final. as a promise that we will not change a variable within an inner class. Now click the button. Now it reads final JFrame jf = new JFrame("Enter MyDate"). JOptionPane. This use of final as a promise is something Checkstyle checks and it may get upset with our setters and constructors. and then click either JButton. The parameters to all setters and constructors should be final. But we are not declaring a constant here nor are we working with a parameter. continued? Compile MyDate. 268 . we‘ll just follow its advice. in connection with the declaration of constants and as a promise that the method will not change the value of a parameter. But it doesn‘t compile! The error message is ―local variable jf is accessed from inner class. "Cancel". run the showDataEntryFrame method. "Clicked cancel". needs to be declared final. We are using final in a different sense. Find the line where you declared jf and add the word final to it. right-click the class in the class diagram.showMessageDialog(jf. What does an ActionListener do.with JOptionPane.INFORMATION_MESSAGE).) But go ahead and give the okay button an ActionListener. We have seen the word final before. An informational message appears.‖ Without going into the details of inner classes. What happens? Nothing happens when you click the okay button (unless you thought ahead and gave it an ActionListener. The intent is that this should simply display a message for us. I‘ll wait.

A good example is when you are installing software. The second argument is the message which appears beside the icon.setVisible(false). The third argument is the title which will appear in the message dialog frame. The dialog is modal. then the message is centred on the screen. not display a message. This icon will change depending on the value of the fourth argument. You should use modal dialogs when it makes no sense to allow you to continue without responding. How does the dialog appear and how is it related to the statement you copied? o The first argument to showMessageDialog is the name of the parent component. You probably should not be doing anything else while installing new programs. o o o Behind the Cancel Button But we wanted the cancel button to cancel the frame. to close it. The fourth argument indicates that the message is one of information only. Should the name be null. Replace the showMessageDialog call in the ActionListener with jf.Note the different colours or shading in the titles of the two frames. The message which appears will be centred on that component. you must click the OK button within it before you can continue and do anything else with this application. 269 . and will result in an information icon appearing in the message dialog frame. This may not be a good idea since it may not show a clear association between the parent and the message.

and the JFrame will no longer be visible when you click the cancel button. Editing data There are two times as you are entering data when it may be appropriate to test it is reasonable. This is done with an InputVerifier. In a normal application. The main feature of an InputVerifier is a verify method. 270 .length() == 0) { // no data provided JOptionPane. JOptionPane. The verify method will return true if it finds no errors with the data provided in the JComponent. A JComponent is the parent of the parent of JTextField. it does use up memory. Verifying year and month Here is the InputVerifier for the year. While this technique creates a snappier application. "Need to supply a year". which accepts a JComponent as a parameter. Modern authors suggest that you not intercept keystrokes as they are typed. One is as it is being entered.getText(). we must cast to the // appropriate type to extract the contents String text = ((JTextField) input). We cannot check that the month JTextField contains only the numbers from 1 through 12 until the JTextField is complete. false if there is a problem with the data provided. InputVerifier verifierYear = new InputVerifier() { public boolean verify(JComponent input) { int screenYear. and we do not know the order in which the data will be provided. the program would not terminate. but you verify the contents of a JTextField as you attempt to leave it. the other is when an Okay button is clicked. We cannot check that the day JTextField is appropriate to the month (30 days hath September …) until all three JTextFields (year. Thus showDataEntryFrame exits. Why do we need both times? Consider the MyDateEntry frame. "Missing data". if (text.ERROR_MESSAGE).showMessageDialog(jf. and you must remember to close the data entry frame eventually. month and day) have been provided. // because an InputVerifer can be attached to many // types of Components. It would continue running with some other frame visible and the invisible one (or ones) waiting their chance to reappear. We can check that the JTextFields contain only numbers.

″Year should be four digits in length.ERROR_MESSAGE). "Bad year". in the order listed.showMessageDialog(jf. } } catch (Exception e) { JOptionPane. } // end catch return true. Once we have created the InputVerifier.showMessageDialog(jf.". Of course there is a method (intValue) to extract the underlying int. it takes the primitive datatype and converts it to a class. The InputVerifier checks each.intValue()) to convert a String into an int. }. 271 . We have already used the Integer class in our discussion of autoboxing. // is it reasonable? // reasonable is defined as between 1000 and // 9999 inclusive if ((screenYear < 1000) || (screenYear > 9999)) { JOptionPane. The Integer class is a wrapper class for int. return false. we must attach it to the appropriate widget. // the data contains an integer. Is it an integer? screenYear = (new Integer(text). catching an exception should it be unsuccessful. "Bad year". o You could enter non-numeric data. // length = 0 try { // data was provided. // end verifierYear What could go wrong while entering a year? o You could neglect to enter anything. } // end verify }.ERROR_MESSAGE). "Year contains non-numeric characters. textYear.return false. o You could enter a numeric value which is too small or too large. Note the use of (new Integer(text).intValue()). We attempt to make the conversion. JOptionPane. JOptionPane.".setInputVerifier(verifierYear). return false.

Why does this happen? More importantly. "Bad day". you are able to leave the data entry screen with no problem. Test your data entry screen. JOptionPane. 0 or a negative // number is a bad day JOptionPane. String text = ((JTextField) input). JOptionPane. month.ERROR_MESSAGE).getText(). int screenMonth = 0. // length = 0 try { screenDay = (new Integer(text).intValue()). "Day number is too small. how can you correct it? Hint. if (screenDay < 1) { // regardless of the month. Verifying the day of the month The InputVerifier for the day of the month is a little more complicated since the upper limit for the day depends on the month and the year. and day have been // specified check maximum value for day int screenYear = 0.setVerifyInputWhenFocusTarget(false). } // if the year.InputVerifiers are almost always associated with only one widget. If you choose the X in the top-right corner. return false. "Missing data". How is that for the name of a method? What does that method do? The InputVerifier for the month is similar and is left as an exercise.length() == 0) { // no day has been provided JOptionPane. "Need to supply a day". consider this statement. All the year fields could share the same InputVerifier. InputVerifier verifierDay = new InputVerifier() { public boolean verify(JComponent input) { int screenDay.". }. buttonCancel.showMessageDialog(jf. try { // do we have a year? 272 . Note that you cannot use the cancel button to exit unless a valid year has been provided. But if you choose the cancel button.ERROR_MESSAGE). if (text. an error message appears.showMessageDialog(jf. return false. An obvious exception to this generalisation would occur on a data entry screen which requires the entry of several dates.

ERROR_MESSAGE). return false.getText())).". if ((screenMonth == 9) || (screenMonth == 4) || (screenMonth == 6) || (screenMonth == 11)) maxDays = 30.".showMessageDialog( jf. } // end verify }. so // the following if statement will not be // executed } if ((screenYear > 0) && (screenMonth > 0)) { int maxDays = 31. intValue(). } // end too many } // end year and month provided } // end try catch (Exception e) { JOptionPane.showMessageDialog(jf.screenYear = (new Integer(textYear. } // end non-numeric return true. JOptionPane. JOptionPane. return false. } catch (Exception e) { // some part of the date is missing. "Bad day". "Bad day". "Too many days in the month. // end verifierDay 273 . else maxDays = 28. if (screenMonth == 2) if (isLeapYear(screenYear)) // isLeapYear follows this method maxDays = 29. // do no more day editing // screenYear or screenMonth is zero.ERROR_MESSAGE). // do we have a month? screenMonth = (new Integer(textMonth. intValue(). // now we know the maximum number of // days in the month if (screenDay > maxDays) { // too many days JOptionPane.getText())). "Day number contains non-numeric characters.

is it appropriate?). (as you see when you compile this code) you will need to declare textYear. and textDay variables as final. Mark. 274 . The logic for checking the upper limit is a little more complicated since it depends on the year and the month.The logic verifying the day is similar to that verifying the year and month (Is there anything provided? If so. textDay. and have seen how to create one simple data entry screen. for example. we will see how to create more-complicated data entry screens. http://en.wikipedia.util. College. Student.setInputVerifier(verifierDay). Don‘t forget the import statement. First. textMonth. and Address. so we‘ll examine its data entry screen next. false if not */ public static boolean isLeapYear(int year) { return (new GregorianCalendar()). you can create simple data entry screens for the other classes which require them. /** * calculate if a year is a leap year.isLeapYear(year). we have focussed on the basics of creating data entry screens. Of course. I have chosen to use the GregorianCalendar class and its isLeapYear method. Professor. we attach this InputIdentifier to its widget. is it numeric? If so. * @param year The year which we are checking * @return true if so.GregorianCalendar. embodying the logic necessary to decide when a year is a leap year (see. Section has some interesting aspects. it determines the correct number of days in the month and compares the value provided to that number.org/wiki/Leap_year). Most of these will be left as exercises for the reader. And yes. this method checks that a year and month have been provided. Note the isLeapYear method. } Rather than writing yet another leap year routine. Summary In this chapter. Data entry for other classes Using the ideas above. If so. Meeting. Course. In the next chapter. import java.

2. but not registration information. collecting personal information but nothing on the sections and courses the professor teaches. Complete the InputVerifier for the month textfield. What options do you have with the Swing toolkit? What are the differences between the options? What are some of the other layout managers you can use? When would you use each? Could you use any of them to create the data entry screen we have seen in this chapter? 11. Create a data entry screen for the Address class. 275 . (Hard and maybe pointless) Use the GridBagLayout manager to recreate the data entry screen we have created in this chapter. In previous chapters we discussed modelling a bank account. 10. It will allow you to enter its address and website. Create a data entry screen for the Professor class. including both the common and scientific name. Explore the subject of ―look and feel‖. omitting the choice of the account to which the transaction applies. In previous chapters we discussed modelling a bank account. 7. 3.Exercises 1. but nothing about employees. 4. students. but not associating it with a section just yet. Create a data entry screen for the Mark class. Create a data entry screen for the Meeting class. Which layout manager do you prefer? 12. Create a data entry screen for the Student class. Create a data entry screen for entering the personal information for the holder of the account. Create a data entry screen for entering a transaction. Create a data entry screen for entering a species of bird. but not collecting any information about the sections of the courses which are offered. collecting personal information. 14. 9. 8. but not associating it with a student and course just yet. 13. In previous chapters we discussed modelling the sightings a birder makes. or courses. 5. Create a data entry screen for the College class. 6. Create a data entry screen for the Course class. In the next chapter we will add the account.

you could perhaps link to the AOU site and choose from a list. These include. 276 . Find a GUI builder and use it to create a data entry screen. 16. the British Columbia Field Ornithologists (http://www.bcfo. Create a data entry screen for entering a sighting. You should also know about your local birding groups. for example. 15.If you are serious about birding. you should know about the American Ornithologists‘ Union and their website at http://www. omitting the choice of the species which was sighted.org/.org). In previous chapters we discussed modelling the sightings a birder makes.ca/) and Bird Studies Canada (http://www.aou. It may be possible to use this list to make the data entry screen in this question redundant.055 (as of 2010-05-13) bird species seen in North America. In the next chapter we will add the species.bsc-eoc. This site makes available a list of the 2.

They include checkboxes and radio buttons. To build this screen. including the JRadioButton. They include lists of items. Let‘s see how we create these data entry screens. JList.Chapter 15 . and a collection of buttons.Creating a GUI – Data entry screens. JPanel. and JCheckBox components. It contains some labels. and some buttons. Building the Section data entry screen The data entry screen for a Section naturally divides itself into several portions: the course with which the section is associated. JScrollPane. 277 . the meeting times for the section. some textfields. But more complicated data entry screens are very common. The data entry screen we will create is shown below. They include panels to separate portions of the frame. part 2 Learning objectives By the end of this chapter you will be able to:      Use Swing components to create complicated data entry screens Describe the role of a layout manager in creating data entry screens Use a layout manager to create complicated data entry screens Use ActionEvents and ActionListeners Use InputVerifiers Introduction The data entry screen we created in the previous chapter is relatively simple. additional Swing components are necessary.

The second JPanel contains the radio buttons. right. labels. and bottom borders. The first JPanel is the portion of the screen containing the course list and section number.You can see the three JPanels in the image above. right. The third JPanel contains the buttons. It is clearly separated from the rest of the screen by a border. I have omitted the border on the third panel because it seems to be superfluous. It also has a border. 278 . textfields. Let‘s examine parts of the method necessary to build this screen. a few statements at a time. and checkboxes associated with meeting times. and bottom borders of the frame itself serve as the left. The bottom border of the second panel serves as a top border and the left.

Create the frame
public static JFrame buildDataEntryFrame() { // create the JFrame. final JFrame sectionInput = new JFrame("Enter Section Information"); sectionInput.setDefaultCloseOperation (JFrame.HIDE_ON_CLOSE);

We have created the frame (In the previous chapter, I used the nondescript variable name jf. Here I use the more informative sectionInput.) and specified that it will hide itself when we click the X icon in the top-left corner of the frame. These statements are common to most data entry screens you create. Create a column of panels
// use the BorderLayout to create a column of JPanels. // Actually BorderLayout gives five sections of the // frame but we will not use the EAST and WEST. sectionInput.setLayout(new BorderLayout());

Recall that the BorderLayout divides the form into five regions, a central region and four surrounding regions. The comment notes this. Create the three panels
// create three panels for the frame // at the top - choose a course and enter a section // number // in the middle - meeting times // at the bottom - buttons JPanel topPanel = new JPanel(); JPanel middlePanel = new JPanel(); JPanel bottomPanel = new JPanel(); // and add the panels to the Box in the // correct order, from top to bottom sectionInput.add(topPanel, BorderLayout.NORTH); sectionInput.add(middlePanel, BorderLayout.CENTER); sectionInput.add(bottomPanel, BorderLayout.SOUTH);

The BorderLayout layout manager (imported from java.awt.BorderLayout. Don‘t forget the import statement!) divides the frame into five sections. We are using three sections and our panels will expand to fill those section. The EAST and WEST sections will still exist, but will be empty (and disappear). While I like the RelativeLayout layout manager, there are times where it is the best tool and times where other layout managers are the best tools. I am trying to show you other layout managers

279

whenever their use is appropriate. As we build this frame, we will also use the BoxLayout and the FlowLayout layout managers. Notice that we have created the three JPanels and placed them within the frame, but we have not yet specified what the JPanels contain. We‘ll do that in a moment, starting with the top JPanel. Populate the top panel
// the top panel contains two Boxes, one containing a // JLabel and a JList to choose the course, // the other containing a JLabel and a // JTextField to enter a section number Box courseSelector = Box.createVerticalBox(); Box sectionSelector = Box.createVerticalBox();

Looking back at the sample screen, you‘ll see that the top JPanel contains two columns of Objects. A Box is a container into which you can place Objects either vertically or horizontally. More correctly, a Box is a container which uses the BoxLayout layout manager, a manager which stacks widgets on top of each other, or beside each other, depending on the orientation of the Box. When you have columns of widgets, it may be easier to use a VerticalBox to contain and position them than to use some other layout manager. Like all other advice I give here, take this with a grain of salt. You‘ll soon see that I don‘t always follow my own advice.

// courseSelector Box JLabel courseLabel = new JLabel("Course"); courseSelector.add(courseLabel); // the course JList, a list of items from which // the user can choose. First prepare // some default values, stored in an array. // These values should come from a database, but we // don‟t know how to use databases yet so we will // juts provide some value here String[] data = {"COSC 109", "COSC 111", "MATH 139", "NTEN 112", "BUAD 123", "PSYC 123", "GEOG 111", "POLI 100", "BUAD 123", "BUAD 128", "BUAD 111"}; // create the list box and place the contents // of the array in the JList JList coursesList = new JList(data); // allow user to make only one selection coursesList.setSelectionMode( ListSelectionModel.SINGLE_SELECTION);

280

// embed the JList in a JScrollPane to allow // for scrolling JScrollPane courses = new JScrollPane(coursesList); // add the JScrollPane to the panel courseSelector.add(courses); // done with courseSelector Box

So the courseSelector Box contains a JList (which scrolls, and allows only one choice to be made). We don‘t have a database of courses, which we would normally use to populate the JList. Instead, we simply create an array containing some courses, and use that array to initialize the JList, using enough courses that we will see the scroll bars appear. We have seen arrays before, and will see them again.
// sectionSelector Box JLabel sectionLabel = new JLabel("Section"); sectionSelector.add(sectionLabel); // the section JTextField final JTextField sectionText = new JTextField(4); sectionSelector.add(sectionText);

Similarly, we create and place the widgets in the second VerticalBox.

Place boxes in the panel
// and add both Boxes to the top JPanel top.add(courseSelector); top.add(sectionSelector);

And we place both Boxes in the JPanel. Note that the BoxLayout manager does not require the bindings that RelativeLayout does. It simply places widgets one after the other. Decorate the panel We would like to separate the first two panels from the rest of the frame by surrounding each with a border. So we need to create the borders.
// create borders for the JPanels Border raisedBevel = BorderFactory.createRaisedBevelBorder(); Border loweredBevel = BorderFactory.createLoweredBevelBorder(); Border compound = BorderFactory.createCompoundBorder( raisedBevel, loweredBevel);

281

Border is a Swing interface used to describe a border around a JPanel. A BorderFactory is a class which creates objects implementing the Border interface. To use these objects, you must include two import statements at the beginning of the class. import javax.swing.border.*; import javax.swing.BorderFactory;

Explore BorderFactory to see the kinds of borders it can create. If you find a more appealing border, use it in place of what I have created. Continuing with our method,
// finish with a border top.setBorder(compound);

Now that we have a Border available, we place it around the JPanel and the appearance of the top JPanel is complete. Create the middle panel This panel is more complex than anything we have seen. Because of its complexity, we will use RelativeLayout to design it. I suppose we could have built it using 11 vertical boxes, or six horizontal ones.
middle.setLayout(new RelativeLayout());

Labels
Note that there is a row of labels. For each label, we follow our usual practice; create a widget and its bindings, add the bindings to a collection, and then add the widget and its collection of bindings to the frame or, in this case, panel. In this case, the top edge of all the labels is the same, so we create a constraint for that, and then use it for each label.
middlePanel.setLayout(new RelativeLayout()); BindingFactory bf = new BindingFactory(); JLabel dayLabel = new JLabel("Day of the week"); Binding dayLabelLeft = new Binding(Edge.LEFT, 10, Direction.RIGHT, Edge.LEFT, middlePanel); Binding dayLabelTop = new Binding(Edge.TOP, 10, Direction.BELOW, Edge.TOP, middlePanel); RelativeConstraints theBindings = new RelativeConstraints(); theBindings.addBindings(dayLabelTop, dayLabelLeft); middlePanel.add(dayLabel, theBindings);

282

JLabel startLabel = new JLabel("Start time"); Binding startLabelTop = bf.topAlign(dayLabel); Binding startLabelLeft = new Binding(Edge.LEFT, 275, Direction.RIGHT, Edge.LEFT, dayLabel); theBindings = new RelativeConstraints(); theBindings.addBindings(startLabelTop, startLabelLeft); middlePanel.add(startLabel, theBindings); JLabel endLabel = new JLabel("End time"); Binding endLabelTop = bf.topAlign(dayLabel); Binding endLabelLeft = new Binding(Edge.LEFT, 75, Direction.RIGHT, Edge.LEFT, startLabel); theBindings = new RelativeConstraints(); theBindings.addBindings(endLabelTop, endLabelLeft); middlePanel.add(endLabel, theBindings); JLabel roomLabel = new JLabel("Room"); Binding roomLabelTop = bf.topAlign(dayLabel); Binding roomLabelLeft = new Binding(Edge.LEFT, 75, Direction.RIGHT, Edge.LEFT, endLabel); theBindings = new RelativeConstraints(); theBindings.addBindings(roomLabelTop, roomLabelLeft); middlePanel.add(roomLabel, theBindings);

Notice something new in these statements. Rather than having separate collections for the bindings of each widget, we use only one collection, named theBindings. There is no way to remove bindings from a collection, so we simply allocate new memory for it each time we wish to erase the previous bindings.

The meetings
The labels are followed by several similar rows for the different meetings of the section. The actual number of rows which appear is available from the College class. For each meeting of the section (for each of the rows), we need seven JRadioButtons (corresponding to the days of the week), and three JTextFields (the start and end times of the meeting, and the room in which it will take place.) We‘ll see how to do the checkboxes in a moment. So we have several rows of widgets, each row of which appears identical. Intuition (another name for learning from past mistakes) tells me that a good way to do this is to use a data structure of some kind, perhaps an array or a Vector or a List, with each element of the collection corresponding to one row on the data entry screen. Continuing with intuition, we realise there are seven radio buttons. They could make a collection too. Since the data structure or collection is quite simple and there is no real processing of the elements in the collection, we can use an array. To do that, we should examine arrays more fully before we continue.

283

Arrays We have used collections (and arrays) before. A Student object contains a collection of Mark objects. A Course object contains a number of Section objects. A Section object contains a number of student identifiers. Generally we needed to go through all the elements in the collection, starting at the first and ending at the last. But what if we need to access the elements of the collection randomly? That is, we want the fourth element, then the eighth, then the first. It would be very inefficient (slow) to have to process all preceding elements in the collection to retrieves a specific one. Fortunately, there is a very traditional data structure which supports random access. This is the array. An array has two parts. The first is the collection of data items. The second is the subscript or index, a number used to indicate which element of the collection we wish. Suppose we have a collection of Student objects, which we wish to store as an array because we need to access the Student objects randomly. Consider the statement
Student[] theStudents = new Student[50];

This array, whose name is theStudents, contains space for 50 Student objects. The objects are numbered zero through 49. The index always starts at zero. In memory, these 50 objects are stored next to each other. When we wish to retrieve the last Student object we retrieve theStudents[49]. If we wish to retrieve the first Student object, we retrieve theStudents[0]. When we wish to retrieve all the Student objects, we use a for statement.
for (int i = 0; i < 50; i++) { // do something with theStudents[i] }

But why stop at an array of Student objects? We can have an array of anything, primitive datatypes like int or char (Did you realise that you can think of a String as an array of char? You probably did since we inspected a String and saw its array of char.), or an array of arrays. An array of arrays? Yes, each element of one array is itself a second array. You have probably seen this structure often. The board on which you play chess or checkers is a two-dimensional array. The rows are elements of an array; but each row contains an array, each element of which is a column. Each sheet of a workbook (a spreadsheet) is a two-dimensional array, whose elements are much more complicated than those of a chessboard.

284

That is, these are arrays in which you can think of each array element consisting of an array.

Were we to create a variable to represent a chessboard, we might use something like this.
int [][] chessboard = new int [8][8];

The model of a chessboard and its pieces could represent an empty cell with a zero, a cell containing a white piece with a negative number (different numbers correspond to different pieces), and a cell containing a black piece with a positive number. If you stretch your mind you can imagine ragged arrays, in which each row may not have the same number of cells. Imagine this histogram turned on its side.

So, now that we know a little more about arrays, let‘s continue building the data entry screen.

Create the middle panel, continued
Radio buttons When I look at the screen we are building, experience helps me see that the radio buttons form a two-dimensional array (several rows, seven columns), while the start time, end time, and room each form one-dimensional arrays (several rows each). Most importantly, the arrays are associated. That is, an element in one row of one of the arrays is associated with the corresponding element in the other arrays. When you look at the data in, for example, the third elements of these arrays, you will find the day of the week on which the third meeting takes place, the time it starts, the time it ends, and the room in which it occurs.

285

ButtonGroup
Note that radio buttons occur in groups. When you select one button in a group, all the others are deselected. That‘s the traditional way you choose which radio station to listen to on your vehicle radio. Push one button, you hear one station; push another button and you hear another station. When you have more than one group of radio buttons on a screen, selecting and deselecting in one group does not influence your choices in the other groups. We accomplish this by placing the buttons for each of the possible meetings in different ButtonGroups.
ButtonGroup aGroup = null;

We will see how to add JButtons to ButtonGroups in a moment. When first created, all the buttons in a button group will be deselected. Note that there are some applications in which choosing a button in one group may affect the contents of another group. For example, a washing machine I recently purchased lets you choose the type of material you are washing. Depending on your choice, you may not be able to use hot water. The ―hot water‖ choice in the temperature group is disabled.

An array of radio buttons
Since we have arrays, we need to have values which tell us the bounds of the loops which we will use to process the elements of the arrays.
College c = College.getInstance(); final int MAX_MEETINGS = c.getMaxMeetingsPerWeek(); final int DAYS_IN_WEEK = 7;

And then we create the arrays.
final JRadioButton[][] aRadioButton = new JRadioButton[MAX_MEETINGS][DAYS_IN_WEEK];

Note that we have created the possibility of the array; the individual array elements do not yet exist.

An array of textfields
Similarly, we create arrays of textfields for the start and end times, and the room numbers.
final JTextField[] startText = new JTextField[MAX_MEETINGS]; final JTextField[] endText = new JTextField[MAX_MEETINGS]; final JTextField[] roomText = new JTextField[MAX_MEETINGS];

286

j++) { String text = "" + ("SMTWRFA").below(dayLabel). Whenever the data entry person chooses a day. for (int j = 0. j < DAYS_IN_WEEK . theBindings. Binding top = bf. So I decided to place a column of checkboxes down the right side of the screen. i++) { // the radio buttons aGroup = new ButtonGroup(). // for all the meetings for (int i = 0. You may have noticed that all these arrays are declared to be final. This requires another array. theBindings). the individual array elements do not yet exist. Placing the arrays in the frame At last we are able to begin creating the individual elements of the arrays and placing them on the screen. Checkboxes In thinking about this screen.charAt(j). the individual array elements do not yet exist. i < MAX_MEETINGS. left = bf. We saw this in the previous chapter. final JCheckBox[] hasMeeting = new JCheckBox[MAX_MEETINGS]. aGroup. or a time.leftEdge(). Binding left = null. or a room. Note that we have created the possibility of the array.add(aRadioButton[i][j]. (When the data entry person unchecks a checkbox. we will process only those rows which have the checkbox checked.rightOf(aRadioButton[i] [j]). 287 . left = bf. This is so that the ActionListeners we will need are able to access them properly. the appropriate time and room will be erased from the screen. I realised it could be difficult to tell which of the five meeting possibilities are actually being used and it would be inconvenient to change many values when a meeting is removed. aRadioButton[i][j] = new JRadioButton(text).) When the data entry person clicks the OK button. middlePanel. the appropriate checkbox will be checked by the method.Note that we have created the possibility of the arrays.addBindings(left.add(aRadioButton[i][j]). top). theBindings = new RelativeConstraints().

} The core of this code is a pair of nested for loops. The second ellipsis indicates there are some statements that must be done after the radio buttons are created. theBindings. middlePanel. specifically related to the textboxes for the start and end times.leftAlignedWith(startLabel).add(hasMeeting[i]. theBindings. i < MAX_MEETINGS. // and the checkbox hasMeeting[i] = new JCheckBox(). middlePanel.) indicates there are some statements that must be done to make the radio buttons appear. j++) { . 288 . top). theBindings). theBindings = new RelativeConstraints(). j < DAYS_IN_WEEK . for (int i = 0.leftAlignedWith(endLabel). left = bf. top = bf.addBindings(left. and the room...addBindings(left. theBindings. left = bf.add(roomText[i]. theBindings). theBindings). theBindings = new RelativeConstraints()..} // and the text fields startText[i] = new JTextField(4). left = bf.leftAlignedWith(roomLabel). and the checkboxes. i++) { for (int j = 0. middlePanel. roomText[i] = new JTextField(4).addBindings(left. theBindings = new RelativeConstraints().. } . theBindings)..addBindings(left. theBindings = new RelativeConstraints().add(startText[i].add(endText[i].rightOf(roomText[i]). The first ellipsis (the . } The first loop. theBindings. The inner loop deals with the radio buttons for the seven days of the week. top).. endText[i] = new JTextField(4). middlePanel. top). top). the outer one deals with the rows to be displayed. left = bf.below(aRadioButton[i] [0]).

The label on the radio button is determined for the English-speaking world. left = bf. all of which are aligned along their top edges. The checkboxes are placed to the right of the last textfield. The variable names left and top are used over and over again. top = bf. taking into account the default margin. for all the arrays and we need to place them in the correct locations. methods which check that the data we enter is reasonable.leftAlignedWith(startLabel). left = bf. String text = ((JTextField) input). How do we do that? In particular. InputVerifiers But wait a moment! We realize that we will need InputVerifiers for the textfields. 289 . What do we do for the individual widgets in a row? The radio buttons begin at the left edge of the panel.rightOf(aRadioButton[i] [j]). left = bf. left = bf. how do we deal with the bindings? We can use a binding to describe the top of all widgets in a row. The textfields line up with their respective labels. This keeps the columns of radio buttons aligned on their left edge as all radio buttons are the same width.below(dayLabel).rightOf(roomText[i]). Binding top = bf. For example. The first meeting row is below the row labels. Subsequent radio buttons are to the right of the previous radio button.below(aRadioButton[i] [0]).getText(). Notice that every widget has a left and top binding. // InputVerifier for the times InputVerifier verifierTime = new InputVerifier() { public boolean verify(JComponent input) { int screenTime.leftEdge().We definitely need to create the individual array elements. Subsequent rows are below the previous row.

a small piece of code which will be completed at a later time. "Missing data". } // end verify }.". return false. "Bad time".23\n" + "Second two 00 . }. return false. // length = 0 try { // is there a numeric time screenTime = (new Integer(text). } } catch (Exception e) { JOptionPane.showMessageDialog( sectionInput. // and is it reasonable? int screenHour = screenTime/100. "Time should be four digits.59".\n" + "First two 00 . This InputVerifier is simply a stub. The InputVerifier simply returns true. int screenMinutes = screenTime % 100. whenever we supply a room.getText(). JOptionPane. "Need to supply some time".ERROR_MESSAGE). if ((screenTime < 0000) || (screenTime > 2359) || (screenMinutes > 59)) { JOptionPane. "Time contains non-numeric characters.ERROR_MESSAGE). } // end catch return true. JOptionPane.showMessageDialog (sectionInput. // InputVerifier for the room InputVerifier verifierRoom = new InputVerifier() { public boolean verify(JComponent input) { int screenRoom.ERROR_MESSAGE).length() == 0) { // no time specified JOptionPane. "Bad time". 290 . // end verifierTime The InputVerifier below. String text = ((JTextField) input).showMessageDialog( sectionInput.if (text. is incomplete. the room is acceptable. return false. for the rooms.intValue()). JOptionPane. as we do not have any way of storing and retrieving a list of allowable rooms.

The String needs to identify the row in which the radio button is located. we can check this specific String with the getActionCommand method.length() != 0) { // should check if the room is in // a database. } // end verify }.if (text. but we don't have one yet return true. Instead of just creating a radio button aRadioButton[i][j] = new JRadioButton(text). Similarly. } return false.setActionCommand( ). endText[i].toString(i)). When an ActionListener is executed. But we need an additional feature of ActionListeners. so we can use aRadioButton[i][j].setInputVerifier(verifierTime). i < MAX_MEETINGS. if a check box is unchecked. How can we link these components together? We have seen ActionListeners in the previous chapter and we need them here as well.setInputVerifier(verifierTime). // end verifierRoom Of course each InputVerifier must be attached to the appropriate widget. If we click a radio button or enter a start or end time. 291 . for (int i = 0. end time. } ActionListeners for radio buttons Recall that the check boxes work in conjunction with the radio buttons and textfields. roomText[i]. we would like the check box for that row to become checked. and room number to vanish.setActionCommand(Integer.setInputVerifier(verifierRoom). or a room. the ability to identify a specific String with each widget. we would like to have the radio buttons become unchecked and the start time. i++) { startText[i]. with some unique String within the parentheses. we need an additional statement aRadioButton[i][j].

endText[row]. startText[row].getActionCommand()). one which applies to all the radio buttons. // if unchecked if (!selected) { try { int row = new Integer(e. hasMeeting[i]. ActionListeners for checkboxes We need ActionListeners for the checkboxes.setText(""). hasMeeting[row].Here is the appropriate ActionListener.toString(i)).setSelected(true).isSelected().getSource(). roomText[row]. // ActionListener for the radio buttons ActionListener actionListenerRadioButton = new ActionListener () { public void actionPerformed(ActionEvent e) { try { int row = new Integer(e. intValue(). } catch (Exception x) { } } 292 .getActionCommand()). Then we can associate this ActionListener with all the check boxes. we will erase all the information associated with that meeting. When a checkbox is deselected. we need the ActionCommand to be set so we can tell which checkbox is checked.setActionCommand(Integer. Don‘t forget to add it to each radio button. // ActionListener for the checkboxes ActionListener actionListenerCheck = new ActionListener() { public void actionPerformed(ActionEvent e) { // which button AbstractButton abstractButton = (AbstractButton)e. // was it checked or unchecked? boolean selected = abstractButton. } catch (Exception x) { } } }.getModel().setText(""). intValue().setText(""). For this to work.

setMnemonic(KeyEvent. in the order in which they are added to the JPanel. so will be moved to the left when we add the cancel button.} }.RIGHT)). Decorate the middle panel Place a border around the middle JPanel and we are done with it.getRootPane(). The bottom panel Let‘s continue and build the bottom JPanel.setLayout( new FlowLayout(FlowLayout. sectionInput. cancelButton. We need an array of ButtonGroups. but leaves the radio buttons checked. at the specified end of the panel. This ActionListener erases the values we provided for the start time. // build the bottom JPanel. components are placed side by side. we will use FlowLayout. With this layout manager. bottom. Instead.setMnemonic(KeyEvent.add(okayButton). Make it so. middle. 293 . JButton okayButton = new JButton("OK"). it contains JButtons // use FlowLayout placing components at the right. bottom. But we have a small problem.VK_K). setDefaultButton(cancelButton). which we don‘t have yet.add(cancelButton). okayButton. That is. We can clear all the buttons in a group using the clearSelection method but to do that we need to know the ButtonGroup with which we are dealing. JButton cancelButton = new JButton("Cancel").VK_C).setBorder(compound). Which layout manager should we choose? The panel contains only two JButtons. the okay button is added first. end time. the one containing the buttons. // the standard order (left to right) is // OK and then cancel bottomPanel. and room number. RelativeLayout would be overkill for such a simple situation.

/** * show the Frame. // done return sectionInput. cancelButton. buttons need ActionListeners too. JOptionPane. */ public static void showDataEntryFrame() { JFrame box = buildDataEntryFrame().Button ActionListeners Of course. box. okayButton. } }. while (box.setPreferredSize(600. } Create a method to display it.pack(). } 294 .addActionListener( actionListenerCancel). 500). "Clicked okay.showMessageDialog(sectionInput. 100).". box.INFORMATION_MESSAGE). Yes. ActionListener actionListenerOkay = new ActionListener () { public void actionPerformed(ActionEvent e) { JOptionPane. ActionListener actionListenerCancel = new ActionListener () { public void actionPerformed(ActionEvent e) { sectionInput.setLocation(100. Done! And then the screen is complete.addActionListener(actionListenerOkay).exit(0). } }. box. this is exactly the same technique we used to display the MyDate data entry screen. box.setVisible(true).isVisible()) {} System. "Okay".setVisible(false).

you may find the JOptionPanes that appear from the InputVerifiers when you make errors interrupt the flow of typing. You may need different layout managers to create the different parts of the screen. The sixth step is to test that everything works properly. Repeat this step as many times as necessary. The fifth step is to add InputVerifiers to all the textfields and ActionListeners to all the buttons. Create their positioning information and add them to the panel. you may wish to avoid the use of JOptionPanes. If that is so. or American Social Security Numbers. you may customise the data entry screen to suit your preference. but for now. The fourth step is to examine all the panels. Summarizing building a data entry screen This is a longer summary than the one you saw in the previous chapter. be it phone numbers. we create the bindings (constraints) associated with each widget. particularly if there are nested panels. The third step is to create any panels which we wish to place within other panels. create the (non-panel) widgets the panel contains. For each. The first step in building a data entry screen is to create a JFrame and associate a layout manager with it. If we use the RelativeLayout layout manager. Then we add the widgets and their positioning information to the frame. Other layout managers use different terms to control the position of the widgets. something you have been doing throughout all the steps. Add the panels and their positioning information to their containers. Canadian Social Insurance Numbers. haven‘t you? Some general comments on data entry You may need to accept data in a special format. When you are entering a large amount of data. 295 . which will need their own layout managers) which we wish to place in the frame. The second step is to create any widgets (including panels. Some companies have design standards to which you must adhere.Test it. Create the positioning information associated with each panel. postal codes. be they radio buttons or JButtons. You will find the JFormattedTextField makes your life easier. ―Their container‖ may be the frame or it may be another panel. Modify it as you think appropriate. It is described in the online Java documentation.

How can you fix it? You may be forced to change to a time which is correct and then change it back. As you leave the day JTextField you will receive an error message. You meant to enter 2009/03/30. you will need to verify all the fields when you attempt to accept the data on the screen. But if you choose the cancel button. perhaps by clicking the okay button. place an error message in it and make it visible whenever the input is in error.Instead. A person might do this when there were many data entry screens and the person accidentally chose the wrong one. For example. and click in the month JTextField. How is that for the name of a method? What does that method do? Here‘s another problem: assume you have entered 2009/02/30 as the date on the Meeting data entry screen you created in the previous chapter. and return to the day field to enter the number 30. you are able to leave the data entry screen with no problem. Attempt to leave the data entry screen without entering any data. but you entered the start time incorrectly. how can you correct it? Hint. Why does this happen? More importantly. cancelButton. 296 .setVerifyInputWhenFocusTarget(false). an error message appears. one of which we have already seen. when you meant to enter 1030 and 1120. Summary But a complete system does not involve only data entry screens! A complete system probably involves a splash screen (something to watch as the rest of the program loads). and screens containing a menu. If you adopt this method. But the day error message reappears. allowing you access to other parts of the system. or you will not be able to exit from the field. The InputVerifier method will need to return true always. The only way to leave the day JTextField is to provide a valid day within February 2009. You acknowledge it. If you choose the X in the top-right corner. add a normally-invisible label to the data entry screen. Creating a screen containing a menu is the subject of the next chapter. consider this statement. Here are a couple of interesting problems. Then you may change the month to March. Why does this happen? How can you avoid it? Similarly. a start time of 1130 with an end time of 1120. suppose your Section data entry screen checks that the end time is after the start time.

Modify a data entry screen to use that approach.Exercises 1. 7. In the previous chapter you created a data entry screen for entering a transaction. 3. Develop a screen which allows you to display details on a specific account. Assume that this has grown into a system which has many accounts. In previous chapters we discussed modelling the sightings a birder makes. whose name you must provide. Develop a screen which allows you to display the sightings of a particular species. Complete that screen adding the choice of the species which was sighted. Assume this has grown into a system containing many sightings. In the previous chapter you created a data entry screen for entering a sighting. The section ―Some general comments on data entry‖ speaks about JFormattedTextField. In previous chapters we discussed modelling the sightings a birder makes. 2. Explore the capabilities of that class and create a small data entry screen that illustrates those capabilities. whose number you must provide. end time. Modify your program so that the appropriate checkbox is checked. In previous chapters we discussed modelling a bank account. 297 . the appropriate checkbox is not checked. Which layout manager do you prefer? When you enter data into the start time. or room number textfield. 6. In previous chapters we discussed modelling a bank account. adding the choice of the account to which the transaction applies. 5. 4. 8. The section ―Some general comments on data entry‖ speaks about using invisible fields which become visible to display error information. Complete that screen. Use the GridBagLayout manager to recreate one of the data entry screens we have created in this chapter.

298 .

usually horizontal lines. but how do you access them? In modern computer applications.Creating a GUI – Menus Learning objectives By the end of this chapter you will be able to:     Use Swing widgets to create menus Describe some of the considerations involved in designing a menu Describe the role of a layout manager in creating menus Use ActionEvents and ActionListeners with menus Introduction Having data entry screens is fine. BlueJ has menus.‖ That is. a JMenu can also contain JSeparators. you often have a menu system that allows you to access the various parts of your system. JSeparators are the visual dividers. containing a collection of JMenu objects. and BlueJ is a Java application. In this chapter.Chapter 16 . A JMenu object is the vertical list of JMenuItems and JSeparators which appears when you click an item in the JMenuBar.a popup window containing JMenuItems that is displayed when the user selects an item on the JMenuBar. In addition to JMenuItems. a JMenuBar object is the horizontal menu. you see separating JMenuItems into logical groups. 299 . we will focus on creating a menu system. In particular. How did the developers make those menus? Creating the menus Definitions A menu appears across the top of a frame and is implemented through the JMenuBar class. The Java documentation says that the JMenuBar class is ―An implementation of a menu .

If we were to implement this in its entirety. A third method. transcripts. to allow us to display timetables.swing.Designing the menu system So what do we want our menu system to contain? We need to answer that question before we begin to implement the menu system. as a minimum. new student. It contains only a few methods.  Save. etc. to provide access to documents describing how to use our program  About. import javax. we need the Swing library for the widgets and the AWT library for the events associated with them.  Open. containing all choices relating to the files in which we are storing data  Edit. we would need new professor. If we were to implement this in its entirety.  Print. I would suggest:  editing an existing professor  editing an existing student  editing an existing course  editing an existing section On the Help JMenu. containing all choices relating to data entry  Help. http://java. I would suggest these items.  New.  Exit. we don‘t want a menu created except under the control of the createAndShowGUI method. shown below. to provide a brief blurb about the developers of the program Implementing the menu So. containing a help system On the File JMenu. On the JMenuBar.sun. and new section. The constructor uses a helper method to create the JMenuBar. As in the previous chapters. createAndShowGUI. displays the JMenuBar within a JFrame.event. Note that the constructor is private. to save any unsaved work. to create a new college or a new semester.*. The Java tutorial provides us guidance.  Help.com/docs/books/tutorial/uiswing/components/menu Create a class named CollegeMenu.awt. these items.  File. to work with an existing college or semester.*. import java. we would need open professor. open student. and open section. let‘s begin. if there is any. But note that we will not be implementing all the functionality behind the menus. 300 . to shut down our program On the Edit JMenu. I would suggest these items. list of professors. I would suggest.

but it is empty. The menu will contain the word which appears in the menu bar.VK_F). Now the menu bar contains one choice. } Now we can create the menu and submenus. public JMenuBar getBar() } return bar. Once fileMenu has been created add it to the menu bar. Recall that we used mnemonics when we established shortcuts in our data entry screens. JMenu fileMenu = new JMenu("File"). We define a variable to contain the File menu. It does not contain any of the vertical menus yet. bar = new JMenuBar(). private JMenuBar createMenuBar() { Create the horizontal menu.add(fileMenu).setMnemonic(KeyEvent. private CollegeMenu() { bar = createMenuBar().getAccessibleContext().public class CollegeMenu { The only instance variable in this class is the JMenuBar. fileMenu. but let‘s first create a getter to retrieve it. along with all the choices in the vertical menu. save. } We‘ll create the menu in a moment. The constructor calls the createMenuBar method and stores the menu which is created in the variable named bar. The accessibility methods are described below.open. private JMenuBar bar. etc"). setAccessibleDescription ("Deal with files . bar. but the vertical menu is empty. 301 . which will appear across the top of the frame. fileMenu. The createMenuBar method does all the work.

*/ public static void createAndShowGUI() { // provide a frame in which to display the menu JFrame frame = new JFrame("COSC 111/121 Example″). // create the menu system // and add it to the appropriate JFrame frame. frame.EXIT_ON_CLOSE). test the menu system by compiling the CollegeMenu class and then executing its createAndShowGUI method.setLocation(100. } As we did with the data entry screens. the method above creates the menu bar but does not display it. We need another method which will create the frame into which we can place the menu.VK_N). but it is incomplete. menuItem. And then we create the choices.getAccessibleContext(). We‘ll see what is missing below. 260).We define a variable which will be used to successively create the choices on the File menu. fileMenu. //Display the frame frame. } } The code as shown will work. KeyEvent. setAccessibleDescription ("Create a new file"). JMenuItem menuItem.setVisible(true).setJMenuBar(new CollegeMenu(). /** * Create the GUI and show it.setMinimumSize(450. // create JMenuItems for fileMenu menuItem = new JMenuItem("New". 100). 302 .add(menuItem). First.setDefaultCloseOperation (JFrame. frame. frame.getBar()). though. // repeat for other JMenuItems (see below) // repeat for other JMenus (see below) // done return bar.

you shouldn‘t have the same mnemonic for two selections on the same menu. Do this with JSeparators. we are providing access for those with serious vision problems. 303 . what mnemonics did you use for Student and Section? As a general rule. I used T for student and S for section. adding one to the menu wherever appropriate. We have seen that a mnemonic is a single letter abbreviation you can use to choose a selection from a menu.setToolTipText("Create a new file"). On the Edit menu.setAccessibleDescription would be to use tooltips for those who don‘t use a screen reader. Or you could use S for both. drop-down. the duplication of mnemonics.add(new JSeparator()). Accessibility refers to making computers easier to use by those with different types of sensory challenges. menus are divided into logical sections (New. In this case. relating to accessibility. we saw them in an earlier chapter. You could use S for student and E for section if you prefer. An example is menuItem. fileMenu. and one before Exit. When you have duplicates and you cannot find suitable different mnemonics.Accessibility We have used some new methods here. you may run across an interesting challenge. pressing and the mnemonic repeatedly will switch from one of the duplicate entries to the next. in a circular fashion. I added a separator after Save. Open. Tooltips appear when you rest your mouse over a choice but do not click a button on the mouse. you should use both AccessibleDescriptions and ToolTips. The other problem you run across is that the vertical. To avoid this. As you do this. An alternative to getAccessibleContext(). who may use a screen reader to identify the mouse location and the text on which it is located. S for Save and P for Print are common mnemonics. Completing the menu Now complete the other parts of the menu system. To accommodate all users. and Save all deal with files) and you usually wish to separate one logical group from another.

} // do something for each other possibility return. or query screens (but we don‘t have any of those yet).equals("about")) { // display message box JOptionPane. Don‘t forget the import statement! We have seen where each widget implements an ActionListener. We use the setActionCommand method to identify each menu choice. For example. by returning the word which it displays. menuItem.demo program for COSC 111/121". If you wish. When one object acts as a listener for many other objects. The word this refers to the current object. The listener uses the ActionPerformed method to identify which menu selection is made. menuItem. This is done to expand your knowledge of tools available to you. "About". Should you be planning to internationalise this system. however. lead to data entry screens.getText().addActionListener(this). Others. } if (source. Here the CollegeMenu class itself will implement the ActionListener interface.showMessageDialog(null. if (source. "CollegeMenu . so that the menu 304 . listening only for the Exit and About JMenuItems. }. which is an ActionListener.Performing actions Some of the choices on a menu simply lead to other choices. the menu itself.getSource()).getText(). JOptionPane.exit(0).INFORMATION_MESSAGE). How do we invoke methods to do these actions? We use ActionListeners again. we must be able to distinguish between the ―many other objects‖.setActionCommand("exit"). The getText method allows us to identify which menu item has been chosen. you could have an ActionListener to each menu item. public void actionPerformed(ActionEvent e) { JMenuItem source = (JMenuItem)(e. since it implements the ActionListener interface. public class CollegeMenu implements ActionListener Each menuItem variable must register itself with the listener. This is a simple version.equals("Exit")) { System.

since there are 18 characters between the first and last letters of internationalization. Would it be better after all to have separate listeners for each menu item? What changes would you need to make to your menu to make this possible? Help Implementing a help system is a complicated task. Rather than going into great detail about implementing a help system. These will be removed from your program (replaced by generic terms) and stored in a properties file.selections will appear in other languages. you need someone to do the translation. Internationalization Definition Seeing data entry screens and a menu system in English raises the question ―what does it take to use a different language?‖ How would I translate this system into French? Into Russian? Into Japanese? Let me introduce a common abbreviation – i18n.sun. It will have to recognise the other languages.html. Second. 305 . be prepared to change this method. components. platform-independent. a portion of the Java tutorials dealing with i18n.‖ Note that there has not been a lot of development work on this package for several years. I haven‘t used them.sun. since it should be able to answer any questions that the user has about your program. I‘ll refer you to the website for JavaHelp.com/docs/books/tutorial/i18n/index. extensible help system that enables you to incorporate online help in applets. First. This trail goes into more details than I will here. operating systems. This is a common geeky abbreviation for internationalization. see http://java. Steps to follow So how do you translate a system into another language? A good place to get general information is http://java. This is described as ―an open source software.com/javase/technologies/desktop/javahelp/ Other similar packages may be available. and devices. you need to identify the words which need to be translated. a full-featured. For more details on JavaHelp. applications.

with the vocabulary differing between countries. Nouveau has been provided by your translator. your File menu contains the option New.htm. but with the translations in the native alphabet. Note that one language may be used in different countries. The second and third parts of the name are the international abbreviation for the language and the international abbreviation for the country. Note that the mnemonic may change as well as the term. Fourth.For example.iso. Ouvrir has been provided by your translator. if we were making a program that could be used in those four countries. you will place a line that says openAFile = Ouvrir. For the word Open.properties For languages which do not use the Latin alphabet (alphabetic characters whose ASCII values are between 0 and 127) you need an additional couple of steps before you create the properties file.createAFile = Новый 306 . Thus you may need createAFileMnemonic = N and openAFileMnemonic = O.properties MessagesBundle_fr_BF. Note also that the translated term may be longer than the term it is replacing. in Russian. insert the translations into the properties file. you need save your properties file. The language abbreviations are available at http://www.) Thus.org/iso/country_codes/iso_3166_code_lists/english_country_names_and_code_el ements. create a generic term openAFile.gov/standards/iso639-2/php/code_list. Perhaps you will choose the generic term createAFile. In a properties file for a French translation. Its name must be MessagesBundle_xx_yy.properties. the French spoken in Quebec (a province of Canada) has differences from the French spoken in France. and from that in Burkina Faso (a landlocked country in West Africa which gained its independence from France in 1960.properties MessagesBundle_fr_FR. For example. Third. we would need four properties files. In a properties file for a French translation. according to one of my students. This may have implications for the spacing between widgets on your data entry screens. MessagesBundle_fr_CA. from that spoken in Switzerland. MessagesBundle is the name chosen to reflect the fact that this file contains a collection (colloquially called a bundle) of messages. here is the line for New. For example.php and the country abbreviations (in English) are available at http://www. First you need to create a file (whose name doesn‘t matter) containing the statements you would expect to see in the properties file.properties MessagesBundle_fr_CH. file. you will place a line that says createAFile = Nouveau.loc.

currentLocale). The fifth and final step in internationalization (the simple form we are considering) involves Java code to replace the generic terms you chose (createAFile.Create this file. Notepad. as it is the first method which should be run. The easiest way is through parameters to the method. That is. declare two variables. Once the file is created.‖ Details on the UTF-8 format are at http://en. Thank you. for example) with the appropriate word. I used the command native2ascii sergey.util. MessagesBundle_ru_RU. ensuring that it is saved using the UTF-8 standard. provided with Windows. one for the language and one for the country. To use native2ascii. final String country) { Use these two variables to create a Locale object and a ResourceBundle object. Both are Strings. The Java statements to make the magic happen In the method which shows the menu (createAndShowGUI).wikipedia. In my case.properties MessagesBundle_ru_RU. Remember to import java. run it at the command line.getBundle( "MessagesBundle". replace the method header public static void createAndShowGUI() { with public static void createAndShowGUI(final String language.createAFile = \u041d\u043e\u0432\u044b\u0439 All the Cyrillic characters have been replaced with Unicode characters. use the native2ascii program (available as part of the Java download) to convert its contents to a file which contains only ASCII characters and Unicode characters. These variables need to be given values.Locale and java.properties now contains a line which says file.util.org/wiki/UTF-8. 307 . ResourceBundle messages = ResourceBundle. You do not need a fancy program to do this. will save in UTF-8 as long as you click UTF-8 in the dropdown list labelled ―Encoding. Sergey. country).ResourceBundle. Locale currentLocale = new Locale(language.properties since Sergey was the student who did the translation.

How do you deal with error messages that are put together from smaller messages? The order in which the words occur may differ from culture to culture. Conclusion This is only an introduction to the subject of i18n. some cultures use one format for numbers.com/. frame. Alternatively. Who did the translation? You didn‘t have someone to do the translation for you? You could simply create a file for English as it is spoken in Canada. When you display your menu and data entry screens. That is. Can you use a name other than MessagesBundle.getString("createAFile")). Many other cultural differences need to be considered. the first of which is the constructor.The getBundle method looks for the properties file that corresponds to the correct language and country. how do you deal with different formats for numbers.getBar()). you could use an online source like http://webtranslation. There is much more to using ResourceBundles. The generic term we used (createAFile. } The createMenuBar method (note that it now has messages as a parameter) then uses statements like JMenuItem openMenuItem = new JMenuItem(messages. Note that a ResourceBundle is actually an instance of a map.paralink. 308 .setJMenuBar(new CollegeMenu(messages). all the text now comes from the translation.yahoo. others use a different format. The constructor becomes public CollegeMenu(ResourceBundle messages) { bar = createMenuBar(messages). for example) is the key and the translation is the value. For example. language would be entered as ―en‖ and the country as ―CA‖. the standard name? The variable messages becomes a parameter to any method that has been internationalized.com/ or http://babelfish. to extract the appropriate text from the ResourceBundle.

working system. However. and manipulating data. 309 . storing data. there are additional aspects of programming. You have seen the basics (and more) of how to design a program. but there are other ideas we should pursue. we‘ll set the college. its students. You have seen a large amount of Java. which do not fit well into this example of a college. Thus.Summary There is still a lot of work to do to make this system a complete. and its professors aside as we consider other ideas and examples. and of Java. entering data.

Other languages may have such challenges. Create a menu system for a banking system involving many accounts. In previous chapters we discussed modelling the sightings a birder makes.‖ in which the same word may appear as both a noun and a verb. Remember there are English sentences like ―She saw that saw. 4. As the world‘s economies become more and more interrelated. Complete the CollegeMenu class started in this chapter. Explore the subject of internationalization. You will notice that I have placed my menu in one frame. how well do the translation websites I mentioned work? Find someone who speaks a language different from you and explore the accuracy and appropriateness of the translations. Create a menu system for a birding system involving many sightings. 5. 310 . How would you place the menu and data entry on the same frame? In previous chapters we discussed modelling a bank account.Exercises 1 2. internationalization will become more and more important. How does the length of your translation compare to the English words? Does that affect your screen design? 3. and the data entry screen in other frames. In particular.

and online. 311 . The GUI is part of the application and so are all the classes. They are described in most books on Java.sun. not an ordinary class. These are small programs. Then create a new class in that project. for example at http://java. Let‘s see how we can create an applet.Applets Learning objectives By the end of this chapter you will be able to:    Define applet Use the predefined methods which applets provide Create applets to carry out a variety of tasks Introduction Up to now. This site includes many sample applets. so we will use that name for the first applet you write. But Java can also be used to create applets.com/applets. Traditionally. the first program students write is named HelloWorld. but make sure it is an applet.Chapter 17 . we have been building parts of an application as a stand-alone program which runs on its own. Creating an applet Open BlueJ and create a new project. used as part of a web page.

right-click the applet and choose Compile the Applet. applet for us. and then right-click the applet again and choose Run Applet.Well. but it is clearly marked as an applet. it looks like a class on its class diagram. but BlueJ has created a complete. To see this. Running an applet I know we have added no code to the applet. 312 . The window below appears. workable. although minimally-functional.

and the applet opens. in particular. using an application called AppletViewer.The appropriate radio button has been chosen. Much of what you see comes from AppletViewer. 313 . Click Ok. and the height and width are fine. The output of the applet is two lines of text. Terminate AppletViewer. the menu allowing you to control the applet comes from AppletViewer.

/** * Class HelloWorld . we‘ll examine the parts of the applet in detail. The applet runs. Most of the length is documentation. as Firefox was already running. JRootPane rootPane = this. import java. but don‘t be concerned.replace the example // below with your own private int x. Due to the font chosen and the width of the frame.awt.write a description of the class here * * @author (your name) * @version (a version number) */ public class HelloWorld extends JApplet { // instance variables .‖ Then click Ok.getRootPane(). but this time choose ―Run applet in web browser.putClientProperty( "defeatSystemEventQueueCheck". After this code. rootPane. Run the applet again. It is always called before the first * time that the start method is called.In my case. If the browser was not running. import javax. // May not be necessary with your browser. Run the applet a third time.TRUE). How does the applet do its work? Let‘s open it in the editor and see. it started on a new tab in Firefox. but make its width larger. the name in the title bar was truncated.*.) This is much longer than most applets you‘ll see in textbooks. but this time in your default web browser.swing. there was not enough room to display the full name. /** * Called by the browser or applet viewer to * inform this JApplet that it has been loaded into * the system. it would have started. In my case. The three dots at the end of the name (an ellipsis. which we have seen before) indicate this truncation. 314 . An applet (as created by BlueJ) under the microscope Here is the code as it appears in the editor (formatted as usual to fit on the printed page.*. Boolean. */ public void init() { // this is a workaround for a security conflict // with some browsers including some versions of // Netscape & Internet Explorer which do not // allow access to the AWT system event queue // which JApplets do on startup to check access. I set the width to 600 and the complete title appeared.

setColor(Color.drawString("created by BlueJ". and also just before the * JApplet is to be destroyed. g.// provide any initialisation necessary // for your JApplet } /** * Called by the browser or applet viewer to * inform this JApplet that it should start its * execution. 100). The stop method will always 315 .drawString("Sample Applet".white).fillRect(0. */ public void stop() { // provide any code that needs to be run // when page is replaced by another page or // before JApplet is destroyed } /** * Paint method for applet. g. It is called when the Web page that * contains this JApplet has been replaced by * another page. 20. 200. 20. 40).blue). * * @param g the Graphics object for this applet */ public void paint(Graphics g) { // simple text displayed on applet g. g.black). 20).setColor(Color. It is called after the init method and * each time the JApplet is revisited in a Web page. } /** * Called by the browser or applet viewer to * inform this JApplet that it is being reclaimed * and that it should destroy any resources that it * has allocated. */ public void start() { // provide any code required to run each time // web page is visited } /** * Called by the browser or applet viewer * to inform this JApplet that it should stop * its execution. g. 0.setColor(Color. g.

". version. "1-10". * An applet should override this method to * return a String containing information about * the author. */ public void destroy() { // provide code to be run when JApplet // is about to be destroyed. return paramInfo. the type. "boolean". } /** * Returns information about this applet. * * @return a String representation of * information about this JApplet */ public String getAppletInfo() { // provide information about the applet return "Title: \nAuthor: \n″ + ″A simple applet example description. An applet should * override this method to return an array of Strings * describing these parameters. } /** * Returns parameter information about this JApplet. {"status". "description of first parameter"}. * Returns information about the parameters than * are understood by this JApplet. {"images". "description of third parameter"}}. * Each element of the array should be a set of * three Strings containing the name. * and a description. "url". } } Whew! 316 . and copyright of the JApplet. "description of second parameter"}. * * @return a String[] representation of * parameter information about this JApplet */ public String[][] getParameterInfo() { // provide parameter information about the applet String paramInfo[][] = { {"firstParameter".* be called before destroy.

Applets use both. We look at each in turn below.) A JApplet must implement several methods. Should you have an applet that requires a specific version of a browser (or a specific browser or operating system). start. getAppletInfo and getParameterInfo should be implemented as a favour to people who wish to use the applet. start The documentation BlueJ creates gives the purpose of the start method. * It is called after the init method and each time * the JApplet is revisited in a Web page. We look at each in turn below. When you have any GUI components in your applet. */ 317 . and destroy. As we have seen in the previous chapters. JApplet is a Swing class that extends Applet. then the init method would be where you check. this is the place to define them and add their listeners. /** * Called by the browser or applet viewer to inform * this JApplet that it should start its execution. That is. Yes. stop. the workaround that is shown appears to be unnecessary on my computer. an awt class. applets can contain buttons and textfields and … In fact. In particular. * It is always called before the first time that the * start method is called. These are init.The applet begins with two import statements. */ Many times the init method will do nothing. HelloWorld is a JApplet (as well as being an Applet. awt (Abstract Window Toolkit) and Swing. Java has two graphics libraries. init The documentation BlueJ creates states it all. paint. and the applet we are creating extends JApplet. /** * Called by the browser or applet viewer to inform * this JApplet that it has been loaded into the system. Just remember that an applet cannot save data to a file on your computer without asking your permission. much of what we saw in the previous three chapters can be applied to an applet.

files. 0). The documentation BlueJ creates does not let you know this. As such.Applets cannot open files on the machine on which they are running without asking your permission. As you see from the sample BlueJ provides. This method may do nothing. since it appears on a white background.setColor(Color. stop The documentation BlueJ creates gives the purpose of the stop method. and also * just before the JApplet is to be destroyed. the code to do it is placed in this method. change it to a different colour. Of course. When drawing something in an applet. g. it needs an area on which to draw. To see the rectangle. 0. Its upper corner is in the upper left corner of the window (and has co-ordinates 0.yellow. Should your applet do that. or other data. This creates a white rectangle. these commands allow you to specify colours. 200. It is hard to see the rectangle. and to write text (beginning at a specified position). but they can contact other websites to download images. this method may do nothing. The rectangle has a width of 200 pixels and a height of 100 pixels. * It is called when the Web page that contains this * JApplet has been replaced by another page. 318 . the process is to set its colours and other characteristics. called a graphics context (an object of type Graphics) is provided as a parameter and then you can issue whatever commands you need to produce the graphics output you wish. */ Perhaps the applet is playing some music and it should stop. this is the method in which you will write most (perhaps all) of your Java statements. paint This is the method which does all the heavy lifting in an applet.fillRect(0. Perhaps it is running an animation and it should stop. and then draw it. That is. 100). This area. perhaps Color.white). to draw filled rectangles (and other shapes as well). g. /** * Called by the browser or applet viewer to inform * this JApplet that it should stop its execution. An applet is a graphics program.

*/ Perhaps the applet has allocated some memory and it should be released. 20. g. You can see that it is similar to the toString methods we have written in all of the classes we have developed earlier.setColor(Color. /** * Returns information about this applet. and copyright of the JApplet.black). * * @return a String representation of information * about this JApplet */ 319 . 40). This changes the colour to black.g. The stop method will always be called * before destroy. and displays some text (in black). To see the other methods you can use to draw. Perhaps it has established a connection to another website somewhere and that connection should be severed.blue). this method may do nothing. look at the online documentation of the Graphics class. The lower left corner of the leftmost character is 20 pixels from the left edge and 20 down from the top. * An applet should override this method to return a * String containing information about the author. Of course. g. getAppletInfo The BlueJ documentation gives the purpose of the getAppletInfo method. a little further down in the graphics context.drawString("Sample Applet".setColor(Color. 20).drawString("created by BlueJ". g. You will have the opportunity to use some of the other methods in the exercises for this chapter. * version. destroy The documentation BlueJ creates gives the purpose of the destroy method. This changes the colour to blue and displays some more text. 20. /** * Called by the browser or applet viewer to inform * this JApplet that it is being reclaimed and that * it should destroy any resources that it has * allocated.

specify its name in the box provided. you can provide it with input. * Each element of the array should be a set of three * Strings containing the name. * * @return a String[] representation of parameter * information about this JApplet */ 320 . Repeat for as many parameters as you need. * Returns information about the parameters than are * understood by this JApplet. specify its value in the box provided. the type. The default value of null is not informative. and a * description.It is only politeness that you should provide meaningful information from this method. and then click Ok. The BlueJ documentation describes this in more detail. This information is provided through parameters. You can see this in the window which appears when we choose to run the applet. /** * Returns parameter information about this JApplet. An applet should override * this method to return an array of Strings describing * these parameters. getParameterInfo provides a way to find out which parameters an applet will process. If you wish to specify a parameter. getParameterInfo When you run an applet. and click Add.

You are definitely not a beginning programmer if you have covered the previous chapters. When you use AppletViewer to view the applet. containing three elements. "boolean". Hello world Since Kernighan and Ritchie published their book on C. 321 . "url". each of which is itself an array of three elements. "description of third parameter"}}. To complete those exercises. Thus paramInfo[1][2] is ―description of second parameter‖. When you run the applet from a web browser. in green text on a purple background. each of whose elements is an array whose three elements are the name of the parameter (element 0). you can specify those parameters. "1-10". the type of the parameter (element 1). but writing a Hello World program is something all programmers do. and a description of the parameter (element 2). beginning programmers have learned how to do this as well. {"images". and String paramInfo[][] = { {"firstParameter".This method returns a two-dimensional array (the documentation does not make this completely clear). "description of second parameter"}. {"status". But you can‘t specify the parameters unless you know what they are called. paramInfo[2][1] is ―url‖. Trying to access paramInfo[3][3] will cause an exception ( an ArrayIndexOutOfBoundsException) to be thrown. in 32 point text. all Strings. You can refer to individual elements of paramInfo by giving the individual row and column subscripts. Notice the way you can declare an array and give its elements at the same time. you will need to explore the getParameter method of the Applet class. "1-10". the elements of which are Strings. you can also specify those parameters. in which the first sample program was to display the words ―Hello World‖. To follow in the steps of those who have gone before. declares an array of three elements. Remember that both row and column subscripts start at 0. but you will have the opportunity to do so in the exercises. "description of first parameter"}. The applets we create in this chapter do not use parameters. The getParameterInfo method will tell you about the parameters. "description of first parameter"} represents an array. Thus {"firstParameter". Interpret this two-dimensional array as a one-dimensional array. modify the skeleton applet to display the message Hello World.

the contents disappear. and 255-255-255 is white. 100). g. 50). based on the default font. A problem When I resize the applet in AppletViewer. Why does it happen in AppletViewer and how can you fix it? Squares You can create an abstract painting by placing a series of filled rectangles on the graphics context. the contents remain.setColor(Color. g. isn‘t it? That is.green). Once we have the colour we want.setColor(purple). green. g.deriveFont(Font. green on purple is ugly.getFont(). we create a rectangle in which we can display the text. and blue. Make it so. The colours (the first number refers to the amount of red in the colour. not the Java code to create green text on a purple background. Before we display the text. Ugly.setFont(g. 32. g.fillRect(0. the second to the amount of green. 0. 200. This behaviour does not happen when I run the applet in my web browser. 322 . this time using a predefined value. Color purple = new Color(160.32)). Thus 0-0-0 is black. Google the words RGB purple and you will find many sites which tell you that purple is something like 160-32-240. 240). 20.PLAIN. 160-32-240 is interpreted by our brain as purple. we need to create the correct font.drawString("Hello World". Then we set the color of the text. purple is not one of the constants in the Color class! All colours can be constructed from a mixture of red. g.Oh. And we display the text. When I minimize AppletViewer and then restore it. and the third to the amount of blue) are measured on a scale from 0 (none) to 255 (all).

titled ―Select HTML page 323 . you could just rename the automaticallycreated page. choose Run Applet. Make it so. Generate web page only. flags. BlueJ allows us to do this very easily. I didn‘t notice the maple syrup and blueberry pie. When you run the applet. along with the maps. given the x and y co-ordinates of its corners. and flowers of the provinces. If I draw the flag as a rectangle. blueberry pie. Or you could right-click the applet in the class diagram. don‘t tell BlueJ to run it in AppletViewer or the web browser.ca/progs/cpsc-ccsp/etiquette/images/fig3. In my case. I found images of maple syrup. Compile the applet. Being Canadian. http://www. the bars and background are easy to draw. and Nanaimo bars.gc. Thus you need to create a webpage which contains the applet. The maple leaf is the challenge.html and is located in the same folder as the applet. I used a drawing program to identify the approximately 30 points I needed to define the vertices of the polygon adequately. hockey.gif provides an appropriate image. This is a newto-us method which allows us to draw a polygon. and a loon! Word 2007 appears to have lost some of the images. skating. what does the world think of Canada? While looking for this image in Microsoft® Office Word 2003‘s library. Creating HTML to run an applet While we have used AppletViewer to run our applet. A ―Save As‖ window appears. the webpage is called CanadianFlag. I‘ll create a Canadian flag.pch. for example. If you wished to create the webpage with another name.java.Canadian flag Or you can create your national flag. applets are more often viewed via a web browser. I‘ve chosen the Canadian Flag applet. As an aside. tell BlueJ to ―create webpage only‖. since the applet is called CanadianFlag. All you need to do is identify the points on the maple leaf where the line surrounding it changes direction and then provide that information to the drawPolygon method. tuques. and click Ok.

--> <head> <title>CanadianFlag Applet</title> </head> <body> <h1>CanadianFlag Applet</h1> <hr> <applet code="CanadianFlag.jar. Any manual changes made to file will be lost --> <!-. The simpler version of the HTML file is: <html> <head> <title>CanadianFlag Applet</title> </head> <body> <h1>CanadianFlag Applet</h1> <hr> <applet code="CanadianFlag.html was appended automatically.file:/F:/DATA/COSC111/java/ Fall2006/RelativeLayout/RelativeLayout." > Your browser is ignoring the &lt. It is regenerated automatically each time the --> <!-. Here are the contents of the html file.directory outside of the package directory if you want to --> <!-. I chose CanadianFlagTest and the extension .Environment.class" width=500 height=500 codebase="F:\DATA\COSC111\java\Fall2006\Applet" archive="file:/C:/BlueJ/lib/bluejcore.class" width=500 324 .APPLET&gt.jar. tag but isn't running the applet.file:/F:/DATA/COSC111/java/Fall2006/Applet/" alt="Your browser understands the &lt. tag! </applet> <hr> </body> </html> But much of this is unnecessary.jar. <html> <!-.‖ Double-click the Applet folder name.APPLET&gt. Save into a --> <!-. and then provide a name for the HTML page.applet is run.destination.when the applet is next run inside BlueJ. for some reason.file:/C:/BlueJ/lib/junit.This file automatically generated by BlueJ Java Development --> <!-.preserve this file.

surround each paragraph you wish to add with <p> and </p> tags. Within a webpage. These are called tags. The <h1> and </h1> tags mark the largest type of heading. Should you wish to add some text to the webpage (not shown here). capitalization doesn‘t matter. Should you omit the size. HTML (Hypertext Markup Language) is a language used to describe the way webpages will appear when viewed with a web browser. there are two sections. you can specify a title. The heading is surrounded by <head> and </head> tags. <h6> and </h6> (unused in this example) mark the smallest. Within the body of the webpage. comments begin with <!-. in my case.</p> Should you wish to add comments within your webpage (see the second line of the automatically-generated webpage). which appears as the title of the window in which the webpage is displayed. you may have headings.height=500 > </applet> </body> </html> A quick introduction to HTML Should you not be familiar with HTML. these control the appearance of lines which you use to separate parts of your webpage. the applet will run in a window of default size but. <hr> (without a matching </hr>) inserts a horizontal line across the screen. the default is too small to show the entire flag. Its national holiday is July 1. and the size of the window in which it is to appear. surrounded by <title> and </title> tags. here‘s the quick introduction. You have seen different tags when we used XML to serialize objects. These comments will not appear when you display the webpage. For example <p>This is the national flag of the great country of Canada. celebrating the day Canada became a nation in 1867. You may have seen a similar idea in the chapters using XML. and the body is surrounded by <body> and </body> tags.and end with -->. the heading and the body. The description of each webpage begins with <html> and ends with </html>. Within the heading. <applet> and </applet> mark the instructions which identify the applet to run (code=). 325 . and may extend over any lines if you wish.

In this chapter. Should you develop websites. If not. Enjoy them! In the next chapter.Summary Applets are graphics programs designed to run in a browser. We will look at patterns. we will step back from Java for a moment. you may not use them at all. and because they can be fun. 326 . I have included them here as many students enjoy creating visual artefacts. you find you use them extensively. and look at some of the underpinnings of good analysis and design. solutions which have worked for others and which you can adopt to make your own programs better. the exercises actually contain quite a bit of new material of applets.

The declarations are private int width.Exercises 1. private int height. When you use BlueJ to run the applet. Create a loadParameters method and call it from the init method. Modify the applet so it accepts parameters to specify the size of the frame. parameter = getParameter("height"). your applet should choose some reasonable value. if (parameter != null) width = new Integer(parameter). If you don‘t specify the size. First. begin by declaring instance variables for your applet. 327 . To accomplish all this. I would suggest length and width should be the names. Let‘s start with height and width. and the loadParameters method is private void loadParameters() { String parameter = getParameter("width"). specify those parameters and their values. else width = 300. decide on the names of your parameters. Create a simple applet which displays your name.

3.y + r. } Modify the applet so it doesn‘t display always your name. Rectangle r = g. recall that you are specifying the corners of the box surrounding it. 2.if (parameter != null) height = new Integer(parameter). int y = (r. Create an applet which generates a circle in the centre of its graphics context. It should display the name provided as a parameter. width. You should probably make sure the applet accepts both the name color (the American spelling) and colour (the Canadian and English spelling). with your name being the default value. 0. The Rectangle that ClipBounds returns has its top left corner. to determine the size of the box and then use the statement g.) You may draw squares and rectangles with the drawRect and fillRect methods. use something like the following statements. If the name you wish to enter contains one or more spaces.height)/2. To determine the centre. Assume for a moment that you use the height and width that BlueJ suggests. and execute its getParameterInfo method. Thus when you use the statements int width = r. as 0.getClipBounds(). (An oval is a circle drawn within a non-square rectangle. Other polygons are drawn using the drawPolygon and fillPolygon methods. Accomplish this by declaring an instance variable and then establish its value in loadParameters.height / 4. Modify the applet so it uses the colour provided as a parameter. The Rectangle‘s width and height are the values you (or BlueJ) specify when you run the applet. height).width)/2. else height = 400. When you draw a circle.x + r. You may draw circles and ovals using the drawOval and fillOval methods. ensure you enclose it in quotation marks. Modify the getParameterInfo method to explain the parameters the applet accepts. To test this method. represented by x and y.drawOval(x y. You will need to explore the Graphics class to use these methods. 328 .width / 4. create a new applet on the workbench. Ensure there is an appropriate default colour. int height = r. int x = (r. Create a simple applet to draw some geometric shapes.

we can‘t determine the lengths of the sides unless we also know the length of the hypotenuse. int deltaY = new Long(Math. y .to draw the circle.radius. Thinking again of the right-angled triangle. diameter.drawOval(x . out from its current centre. // distance to move radially int hypotenuse = diameter / 20. you need to use this statement.sin(doubleAngle) * hypotenuse)).radius. width. int radius = diameter / 2. or you could do it in two steps.min(height. in degrees. Think of a rightangled triangle.intValue(). the calculation of the centre of the frame is the same.round( Math. Both routes get you to the same destination. whose top left corner is at the centre of the graphics context.toRadians(angle). Make the circle move from the centre along a path whose angle you specify. g.drawOval(x . any direction. We have used a loadParameters method to provide a value for angle. g. but small enough that it will take a number of steps to move the circle a long distance. You will draw a circle in an invisible box.intValue(). This involves a little trigonometry. or you could follow a route along the other two sides. They just take different amounts of time. The first two lines decide the maximum distance the circle will move in a radial direction. int deltaX = new Long(Math. If you specify that the applet runs in a non-square frame. int diameter = Math. you will not draw a circle in the centre of the graphics context. We can calculate the distances in the x and y directions by using the cosine and sine functions. width). move a certain distance in one direction and move a certain distance in another direction. To actually draw a circle whose centre is in the centre of the graphics context. through a parameter. When you move in a direction.round( Math. What value should you use as the diameter of the circle if we really want to draw a circle? I would suggest the minimum of the height and width you have calculated. y – height / 2. Consider the statements below. double doubleAngle = Math. You could go directly to your destination. applied to the angle we specified. But the statement above will draw an oval. height). You could follow a route along the hypotenuse (the long side).width / 2. not a circle. I chose this distance since it is large enough to see. 329 .cos(doubleAngle) * hypotenuse)). diameter). there are at least two ways to do so.

diameter). // and redraw it somewhere else //in the original colour centreX = centreX + deltaX. Create an applet which generates a small circle in the graphics context.drawOval(centreX. } These statements determine the colours to use. i++) { // draw the oval in the background colour g. diameter. plus you will need to 330 . // default background g. How do you slow this action down? One solution is to use the Timer class defined in javax. centreY. repeating as many times as necessary. diameter). Color fg = g. g. diameter). Its centre is specified via parameters.setColor(fg). Explore that class.setColor(bg). which the trigonometric functions expect. and draw the first circle. but we have specified the angle in degrees. But that happens automatically! 4. calculate the new location of the circle and draw it there. you may not see the circle move. diameter. giving a double. g. Thus we convert the double to a Long and then extract the int equivalent. The distance the circle moves in the x direction is given by the hypotenuse times the cosine of the angle. centreY. centreY. unless you have a very slow computer. centreY = centreY + deltaY. The toRadians method converts degrees to radians. This exercise will use many of the ideas from the previous exercise. Make the circle move along a path whose angle you specify through a parameter.drawOval(centreX. Then they redraw it using the background colour (this makes it disappear). g. The distance the circle moves in the y direction is given by the hypotenuse times the sine of the angle.The trigonometric functions in the Math library expect the angle to be in radians.drawOval(centreX.white.Timer. The circle should appear to vanish as it reaches the edge of the frame.getColor(). When you run the applet. The circle should bounce off the edge of the frame and continue on its path. Color bg = Color. diameter. You may see it only at its last position. i < 25. Finally we are at a point where we can make the circle move. for (int i = 0. The conversions in the last few statements arise because drawOval expects ints while the sine and cosine produce doubles.swing.

Some flags are harder than others due to curved shapes. Rotate the triangle. See Australia and New Zealand.) If the edge of the frame is smooth (and it is) the angle at which the circle approaches the edge of the frame is the supplement of the angle at which it bounces off. we usually draw the flag of the United Kingdom and then use it as part of the flag of other nations in the Commonwealth. They need a star method too. Other easy-to-create flags are Aruba. 6.detect collisions between the circle (think of it as a ball) and the edge of the frame (think of it as a wall. This will use much of what you have seen in the previous two questions. 5.) Assume that you move the ball by deltaX and deltaY. for example the African Union. as in the previous exercise. and United Arab Emirates. Afghanistan and Albania are probably impossible to create using Java. at www. But the Olympic Movement flag would be easy to create. (Two angles are supplements if they total 180 degrees or π radians. Create a method that allows you to draw a star. for example. Bangladesh.net. Some international organizations. Then you can consider drawing the flags of the United States (easier) and Micronesia (harder. are also difficult to create.) When I ask my students to draw flags. Create an applet which creates the flag of your country. because the stars do not all point straight up. Create an applet which generates a triangle in the centre of the frame. If you look at the World Flag Database. Libya (probably the easiest of all). hitting a vertical wall means changing the sign of deltaX while leaving deltaY unchanged. 331 . For example. Ukraine. you‘ll quickly find some of these difficult-to-draw flags. Burkina Faso. Hitting a horizontal wall means changing the sign of deltaY while leaving deltaX unchanged. Then.flags.

332 .

or template. In any craft that is mature or that is starting to mature. you can find common. … The problem describes when to apply the pattern.com/2003/0423/patterns. popularised by Christopher Alexander. The authors are Erich Gamma. you can see nine additional architectural patterns at http://www. They have names like Inhabiting the Site. … The solution describes the 333 .Chapter 18 – Design Patterns Learning objectives By the end of this chapter you will be able to:    Define design pattern Use design patterns to help you design classes Use design patterns to help you understand the design of existing classes Introduction In his book on Design Patterns. An architectural example is the pattern called Capturing Light.html. Richard Helm. and woodworking. Steven John Metsker states that ―A pattern is a way of doing something. collectively they are known as the ―Gang of Four‖ or simply ―GoF‖. This idea applies to cooking.architectureweek. and to any other craft. developing software. Ralph Johnson and the late John Vlissides. The idea of patterns in computer science comes from the world of architecture. ―The pattern name is a handle we can use to describe a design problem. or blueprint. The name may be pattern. making fireworks. The word pattern became known in computing with the publication of Design Patterns: Elements of Reusable Object-Oriented Software in 1995. and Parts in Proportion.com/topics/patterns. or a way of pursuing an intent. helping to standardize the jargon. effective methods for achieving aims and solving problems in various contexts. Writers document these patterns. This jargon often refers to patterns. Often they prefer to sit in the sunlight. Sheltering Roof.‖ Among the crafts in which patterns are used are sewing. or jig. You can see this in the house described at http://www. since the sun rises in the east. or standardized ways of achieving certain aims.architectureweek. or recipe.html and. so the quiet place should be on the east side of the building. Writers also ensure that the accumulated wisdom of a craft is available to future generations of practitioners. and consequences in a word or two. Many people like to have a quiet place to have their morning coffee.) They define a pattern as having four essential elements. knitting. The community of people who practice a craft usually invent jargon that helps them talk about their craft. its solutions.

Metsker‘s paragraph which I quoted appears near the beginning of his book. Throughout this book we have been using patterns without naming them. This is clearly shown in a pattern map from the GoF book. illustrating the connections between the GoF patterns.wikipedia. responsibilities. without specifying the final application classes or objects that are involved. and lists many of the patterns that have been published.‖ A few of these patterns are independent of the others.elements that make up the design. The article begins with the words ―In software engineering. we have Capturing Light. Object-oriented design patterns typically show relationships and interactions between classes or objects. 334 . a pattern is a named solution to a problem in design. Design Patterns Java Workbook. in software engineering we have Singleton and Creator. their relationships. one which has been used by many people to solve a problem.‖ We will see some of the GoF patterns below. Regardless of the field. at http://en. The GoF book describes many patterns.org/wiki/Design_pattern. … The consequences are the results and trade-offs of applying the pattern. but many work with other patterns. In software engineering a pattern is not a piece of Java code. In architecture. that would be an implementation artefact. and collaborations. a design pattern is a general repeatable solution to a commonly occurring problem in software design. but we will also see patterns from other sources. It‘s now time to do so. A design pattern is not a finished design that can be transformed directly into code. In this book he shows how to apply the design patterns first publicised in the GoF book. Metsker‘s book shows how to implement the patterns in Java. It is a description or template for how to solve a problem that can be used in many different situations. Wikipedia provides details on the history of patterns within computer science.

This pattern is not directly named in the GoF book since the authors were not using Java examples. for some reason. The Student class implements Serializable. The basic idea behind this pattern is to describe some capabilities a class may have. For the Serializable interface. requires a Serializable object to be used as argument. we saw that the capabilities it specifies are the ability to write objects of a class into a format that may be read back easily. a Student object is also a Serializable object. Thus. The details of how that is accomplished depend on the specific class.Interface pattern Here is a pattern that underlies much of the philosophy behind Java. Set and Map. including Serializable and Comparable. If we have a method which. capabilities which many classes may be expected to have. they used Smalltalk and C++ and those languages don‘t support interfaces as Java does. 335 . We have used many Java interfaces in our coding. and then leave the classes to provide the details of how those capabilities are implemented.

A few more details on this pattern are available at http://en. More details on this pattern are at http://en.org/wiki/Interface. Serializable (where we may not implement code) and Cloneable (where we will implement code) are both marker interfaces we have used which involve this pattern. since a Mark object is also a Serializable object.wikipedia. but the course continues to be available after the professor has left the college. If a class implements several interfaces. College should create new Student objects.a Student object may be used. and gives a name to a practice used for a long time. A design principle is ―less important‖ than a pattern. Thus. It helps you answer the question ―Which class should create new objects?‖ As such it is a pattern that you use while designing your system. It is not a pattern you use in solving problems that arise while implementing the system. 336 . Sometimes this capability will require us to write code.wikipedia. GRASP. sometimes it will not. With this pattern. College should create Course objects. an object which implements a marker interface indicates that it will support the capabilities of the interface. Marker interface pattern A specialisation of the Interface pattern is the marker interface pattern. But so too may be a Mark object. The problem it is solving is how to write high quality code. a course is taught by a professor. in our college model. Which class should create a new Student object? Which should create a new Course object? Since students are registered at the college. Courses are taught by professors. High Cohesion This is another of Larman‘s patterns.org/wiki/Marker_interface Creator pattern This pattern is a simple one. Many would note that this is a design principle and not a pattern. Does that mean Professor objects should create Course objects? No. code which can be understood by a single programmer. then an object of that class has several types. The Creator pattern was publicised by Larman as part of his General Responsibility Assignment Software Patterns. we have students and courses. For example.

particularly in the ActionListeners we used while building our data entry screens. objects appear to possess behaviours but delegate those behaviours to other objects.‖ This is another pattern which is clearly reflected in the philosophy of Java. This pattern (or design principle) states that a class should do a limited number of things and it should do them well. An object listens for events and acts on them. so that a change in one class has minimal effects on another.Something which gets in the way of understanding is complicated code. code which attempts to do too much. messages about events. One object publishes. all its dependents are notified and updated automatically. We saw this most clearly while using the XMLEncoder. To do this. More details on this pattern are at http://en. it must identify itself to some other object which also listens.org/wiki/Event_listener Delegation This is another pattern which is clearly reflected in the philosophy of Java. and gives a name to a practice used for a long time. while others (the listeners) subscribe to receive those messages. but lets other objects know of the events. Low Coupling This too is another of Larman‘s patterns. 337 . we replaced the DefaultPersistenceDelegate with one which knew about the collections our object contained. Observer or Event listener The GoF defines the problem this pattern solves as ―Define a one-to-many dependency between objects so that when one object changes state. This has also been called a ―publish and subscribe‖ pattern.wikipedia. This pattern (or design principle) states there should be no more connection between classes than is necessary. The problem it is solving is how to minimise the connections between classes. Note that the Checkstyle extension interprets this to mean that a method should have no more than seven parameters. This pattern is related to the GoF Mediator pattern. Many would note that this is a design principle and not a pattern. and that those connections be as simple as possible. or sends.

More details on this pattern are at http://en. slowing down the program. We have seen this with the BigInteger. Lazy initialization pattern Perhaps this is a design principle rather than a pattern but it deserves mention.) Some programs would create the index while you are typing the document. the methods are factories. More details on this pattern are at http://en. and with BindingFactory.create methods. which build objects. Dynamic programming. More correctly. complicated data structure.wikipedia. In some cases they have methods which act as constructors. perhaps you could use the factory pattern to decide how it is created. For our college. Both of these could be improved by paying attention to the lazy initialization pattern. is another use of the lazy initialization pattern.wikipedia.org/wiki/Lazy_initialization_pattern Singleton pattern The GoF book defines the problem this pattern solves as ―Ensure a class only has one instance.wikipedia. That could involve a lengthy wait as the program loads.valueOf method. this is a pattern which is clearly reflected in the philosophy of Java. Factory Like delegation. Or suppose you have a program that takes some time to create an index for a document (or some other large. the various BorderFactory.org/wiki/Delegation_%28programming%29. Suppose you have a program which involves many data entry screens. a class which ensures there is only one set of rules which applies to all students. which we will use with some of the mathematical functions in the next chapter. Other programs would create the index only when requested. Simply display a splash screen and an hourglass icon until all the screens are ready to use. When it is needed. and provide a global point of access to it. One school of thought says you should create all the screens before the program displays its main menu. Not all classes have the constructors you would expect.org/wiki/Factory. Note that this is also one of the principles behind extreme programming.More details on this pattern are at http://en. the marks for a student in a course are 338 . This pattern says don‘t create something until it‘s needed.‖ We used this pattern when we created the College class.

the course. But we wish only one such method. was new. For example. Of course. The model represents the data and how it is stored. the term ―pattern‖ was not used then. There would be only one rule to determine the interest paid on a bank account. By using controllers.org/wiki/Singleton Model-view-controller (MVC) This is quite an old pattern. As an aside. the model could have a writeData method which the controller could invoke. We would need a class which creates a method to translate these percentages into letter grades. the interface is isolated from the details of the model implementation. many older programming languages used global variables. We have also mentioned the use of databases. The view represents the interface we have created to manipulate and present the data. it is a more powerful technique than using global variables. The controllers are the glue that connects the model and the view. without recompiling the system. That method would know whether XML or a database is being used. but it can limit the changing of those values. by reading something in from a resource bundle. we would find that the Singleton pattern helps us keep the interest rates paid in only one place. you want to display them as a letter grade.wikipedia. The college needs to have one set of rules for translating percentages to letter grades. Similarly. Controllers respond to user events and modify the model.stored as a percentage. dating back to the days when Smalltalk. It also allows changing values on the fly. they too are ignorant of the model implementation. But sometimes. This is also an example of the application of the Low Coupling pattern. If we write the controllers correctly. or the department. independent of the student. More details on this pattern are at http://en. Thus the constructor would need to see it there already was such a method created. Note that we have looked at several candidates for the model. one of the first objectoriented languages. As such. were we to examine bank accounts as an example of objects. including serialization and XML. The Singleton pattern allows the retrieval of global values. This allowed for all sorts of problems when values were accidentally changed. variables which were known and changeable in all parts of a system. 339 . MVC is the pattern we have tried to use in creating the GUI for the College.

I wish I could find it! More details on this pattern are at http://en. it is displayed as a pie chart.org/wiki/Design_Patterns and http://c2. 340 .wikipedia. while it touches on design.org/wiki/Model Summary Patterns are a very important part of design. good places to start online are http://en. In the fourth it is displayed as a table of data.com/cgi/wiki?DesignPatternsBook. that data is displayed as a histogram. In the second. and the exercises on the next page. If you wish to look into patterns in more detail (and you may do so in further courses). We are not able to go into them further as this book. In the third. This chapter has provided a very brief introduction to patterns. is mainly dealing with implementation.wikipedia. In the first you enter data into the model.A famous example of MVC divides the screen into four quadrants.

Indirection. Template Method. Their catalogue contains 23 patterns with which you should become familiar. For learning the patterns. Look in the GoF book and explore the patterns they discuss. 4. Command. Chain of Responsibility. Note that the GoF book is available on CD as well as in printed format. Flyweight. Decorator. Adapter. Prototype. Strategy. Look in Metsker‘s book and see how the GoF pattern may be implemented in Java. High Cohesion. 341 . Pure Fabrication. Singleton. Memento. Explore the links they provide. http://www. One provides the theoretical underpinnings for the pattern. You will become a better designer and programmer when you gain familiarity with these patterns. Builder. Façade. Composite. 2.net/.hillside. Controller. the CD is perhaps better. These include Abstract Factory. Proxy.hillside. and the other provides a Java implementation. Interpreter. Creator.Exercises 1.net/patterns/. Observer. These include Information Expert. Bridge. I suggest you use Metsker‘s book in combination with the GoF book. 3. particularly the patterns section of the website. Visit http://www. Factory Method. and Visitor. Look in Larman‘s book and explore the patterns he discusses. Iterator. Mediator. Low Coupling. Don‘t attempt to become familiar with all the patterns at once. and Protected Variations. Polymorphism. State.

342 .

Public key encryption using the RSA algorithm involves factoring large numbers. It took several supercomputers about 11 months to accomplish this feat. Certainly the gross national product for many companies will exceed even the limit for a long. (If there were. Sometimes a class can represent mathematical concepts instead.Mathematical examples Learning objectives By the end of this chapter you will be able to:    Define rational number Define complex number Use Java to create classes which were omitted from the Java libraries Introduction The classes we have created in earlier chapters were all related to computer representations of things in real life.Chapter 19 . I‘d like to look at some mathematical examples now. BigInteger What is the largest integer? Since the time of the Greeks it has been known there is no largest integer. In early 2007. one an 80-digit number. We have already seen the limits Java imposes on the size of integers. For numbers. The national debt for a large country may exceed even the limit for a long. the other a 227-digit number. Suppose you need numbers larger than that. a byte contains 8 bits (representing integers from -128 to 127). an int contains 32 bits (representing integers from -2147483648 to 2147483647). a short contain 16 bits (representing integers from -32768 to 32767). researchers reporting factoring a 307-digit number into its two prime-factors. 343 . one of which is available as part of a Java package. what would that integer plus one be?) Unfortunately computers don‘t work well with large numbers. and a long contains 64 bits (representing integers from -263 to 263 – 1). and two of which we can create ourselves.

GCD calculation. Of course.E) and π (Math. Finally.Math. square root. The java. and vice versa. Additionally. The applet exercises used trigonometric functions. please consult any statistics textbook. the Math class provides a way to generate pseudo-random numbers.‖ To understand that statement. in many cases. converting negative numbers to positive ones.lang. The absolute value method (abs) strips the signs from numbers.‖ Method is the term we use in Java. while function is the term we use in mathematics.Math package The online Java documentation says ―The class Math contains methods for performing basic numeric operations such as the elementary exponential. Maximum and minimum functions are available. A square root function is available.Math first. The online Java documentation says ―BigInteger provides analogues to all of Java's primitive integer operators. and all relevant methods from java. and trigonometric functions. and a few other miscellaneous operations. we should look at java. ints and longs. All of these functions are available for floats and doubles. you may convert degrees (a circle represents 360 degrees) to radians (a circle may also be measured as 2π radians). BigInteger provides operations for modular arithmetic. ones which meet tests of randomness but are actually created non-randomly. Logarithm and exponential functions are available. bit manipulation. The Math class also provides values for the mathematical constants e (Math. so many people do need these mathematical functions.lang. logarithm. shorts and bytes are generally not welcome. For details of how this is done. We haven‘t needed many of these mathematical functions in our calculations so far. 344 . a nice recursive method which we examine in more detail in the next chapter. and.So how do we represent even larger numbers? The BigInteger class comes to the rescue. continued The GCD calculation referred to above is the greatest common divisor calculation.PI). primality testing. So are trigonometric and inverse trigonometric functions.lang. But Java is used in the world of science and engineering. BigInteger. prime generation.

Instead. you will find there is no constructor which accepts an int or a long. g. the USA national debt it was $12.000. Between writing this chapter and editing it three years later. on the other hand.000.668. you must use the valueOf method. g. You would need a BigDecimal to represent this exactly.668. 20. valueOf is a static method within the BigInteger class. To test BigInteger.shtml on the same date) was approximately $702. it has a constructor which accepts a double as its argument. int n = 40. The Canadian national debt (as reported via a Java applet at http://www. has the constructors you would expect. that means we use the name of the class.brillig. private BigInteger usDebt = newBigInteger("$12982626754668"). a recession happened during the last of those three years.lang.000.564. the American debt rose by approximately $3. Then we‘ll look at complex numbers. 40). First we‘ll look at the rational numbers. and municipal debt.000. BigInteger b = BigInteger. This is an example of the Factory pattern. In both cases.toString().drawString("US debt " + usDebt. I created an applet. While this is a large number.000. Of course. In it I placed the following statements. via http://www. The BigDecimal class.754. provincial.02.982. Note that the constructor for a BigInteger expects the number to be passed to it as a String.com/debt).754.626.valueOf(n). the same way abs is a static method within the Math class.BigInteger. one without any commas or any other punctuation signs. If you wish to create a BigInteger from a value already stored in an int or a long.000.000. it is not quite comparable to the American figure as the Canadian number includes federal.red). but we can round it to the BigInteger value of $12.Math does not support.626. For example.ndir. import java.000 while the Canadian dropped by approximately $35. followed by a period and the method. What is a rational number? 345 .setColor(Color.000.com/SI/education/debt.When you look through the methods available in the BigInteger class you see all the variety. while the American number includes only the federal debt. When I checked (2010-05-21.982. Rational numbers There are two types of numbers which java.math.

those two rational numbers are the same. if (denom < 0) { 346 . * * @author rick gee * @version may 2006 */ public class RationalNumber { // instance variables private int n. you are left with ¾.It is any number which can be expressed as the ratio of two integers. Some rules we will adopt for our rational numbers. if (d == 0) throw new NumberFormatException( "RationalNumber: denominator may not be zero").  Zero is represented as 0/1. ¾ is a rational number. In fact. denom = d. Following my usual practice.  A zero denominator is not allowed. I know that you can find many examples of a RationalNumber class on the Internet. int d) throws NumberFormatException { int num. After you remove the common factor (12) from the numerator and denominator. num = n. as is 36/48. int denom. The denominator (48) may be represented as 12 * 4.  A negative rational number will have its numerator negative and denominator positive. Yes. /** * class RationalNumber. // the denominator /** * Constructor for objects of class RationalNumber. The numerator (36) may be written as 12 * 3. we begin with a constructor and the toString method. Perhaps the simplest irrational number is the square root of 2.  A rational number with both numerator and denominator negative will be replaced by one with both denominator and numerator positive. // the numerator private int d. These are called irrational numbers. Note that there are some numbers which are not rational numbers. So let‘s create a rational number class.  Common factors will be removed from the numerator and the denominator. This is a standard programming example in many introductory programming courses. */ public RationalNumber(int n.

To test this class. this.// handles both -5/-4 and 5/-7 num = . Math. else num2 = num2 . } /** * @return a String representation of a rational number */ public String toString() { return n + "/" + d. */ private int gcd (int num1. else { int divisor. the constructor should work properly for each.abs(denom)). Uses Euclid's algorithm.num2.    0 and 5 (result should be 0 and 1) 0 and 0 (result should be an exception) 0 and -3 (result should be 0 and 1) 347 . write unit tests. } // initialise instance variables this.abs(num). Consider the following values for the numerator and denominator. int num2) { while (num1 != num2) { if (num1 > num2) num1 = num1 .d = denom. } /** * compute the greatest common divisor of the two * positive parameters.n = num. denom = denom / divisor. denom = . trust me that it works. } return num1. divisor = gcd(Math.num.num1.denom. } } We‘ll look at the gcd method in more detail later. num = num / divisor. } if (num == 0) denom = 1. For now. You‘ll need quite a few since the constructor makes many decisions.

} Notice that we need two getter methods. * @param r The second rational number * @return this + r */ public RationalNumber add(RationalNumber r) { RationalNumber result = new RationalNumber( this. one for the numerator and one for the denominator.d * r. Notice also that by using the constructor.d * r.n * r. return result.getDenominator() + this. and dividing rational numbers We leave it as an exercise to implement subtraction 𝑎 𝑐 𝑎 ∗ 𝑑 − 𝑏 ∗ 𝑐 − = 𝑏 𝑑 𝑏 ∗ 𝑑 multiplication 𝑎 𝑐 𝑎 ∗ 𝑐 ∗ = 𝑏 𝑑 𝑏 ∗ 𝑑 348 . multiplying.getNumerator(). this. this method does not need to concern itself with removing common factors at the end.    1 and 7 (result should be 1 and 7) -1 and -8 (result should be 1 and 8) 2 and -9 (result should be -2 and 9) 2 and 8 (result should be 1 and 4). Subtracting.getDenominator()). nor does it need to concern itself with negative signs. Have we missed any combinations? Adding rational numbers How do you add together two rational numbers? The mathematical definition of 𝑎 𝑐 𝑎 ∗ 𝑑 𝑏 ∗ 𝑐 + = 𝑏 𝑑 𝑏 ∗ 𝑑 translates into /** * Add two rational numbers.

0 + 0i.and division. 349 . the absolute value of the imaginary part. as are -5 + 5i. (0. we have assumed the numerator and denominator are both ints. The letter i represents the square root of -1. 5). -7). while at the same time inconveniencing users of this class as little as possible? Complex numbers Another type of numbers that java. 4). (-5. That is. 6 + 4i is a complex number. the real part and the imaginary part. If necessary. and (2. a number which does not exist. What if ints are not big enough? In the RationalNumber class. It is also due to the use of the design pattern Loose Coupling. What changes would you need to make to the RationalNumber class to use BigIntegers. if you have a rational number a/b.Math does not handle is complex numbers. Complex numbers are usually displayed as a String containing the real part. But in some mathematics an imaginary number can be very useful. Thus we have two choices for the implementation of the toString method. Complex numbers sometimes are represented as (6. hence is called an imaginary number. the reciprocal is b/a. 𝑎 𝑏 𝑎 ∗ 𝑑 𝑐 = 𝑏 ∗ 𝑐 𝑑 What should happen when you attempt to divide by the rational number 0/1? Does it? Inverting a rational number Implement a method to invert (or calculate the reciprocal of) a RationalNumber. What should happen if you try to invert 0/1? Does it? Converting a rational number to a double Implement a method to convert a RationalNumber to its equivalent double value. and 2 – 7i. For example. and the letter i. we could always change them to longs. 0). Recall that a complex number has two parts. the sign of the imaginary part.lang. without disturbing the code of anyone who uses this class. Being able to make changes like this without disturbing code which uses our code is a result of a design principle called information hiding.

thus extending the areas in which it is applicable. they should actually be doubles. Summary Java is useful for many types of applications. One of its strengths is the ease with which you may add libraries.(c + di) = (a . Note that while my first examples show integer values for both the real and imaginary parts. The real part of (a + bi) / (c + di) is (a * c + b * d) / (c2 + d2) and the imaginary part is (b * c – a * d) / (c2 + d2) Implementing ComplexNumber Make it so.c) + (b . 350 . We have seen this by creating RationalNumber and ComplexNumber classes.d)i (a + bi) * (c + di) = (a * c – b * d) + (b * c + a * d)i Division is a little more complicated. (a + bi) + (c + di) = (a + c) + (b + d)i (a + bi) .Arithmetic operations and complex numbers Various operations are defined on complex numbers.

3. Learn something about octonions and implement an Octonion class. 5. 351 . Complete the ComplexNumber class. You cannot write a ComplexNumber class that has two constructors. Change the datatype to BigInteger. Why not? 4. and the radius is the square root of x squared plus y squared. Learn something about quaternions and implement a Quaternion class.Exercises 1. The angle may be calculated as the inverse tangent of y over x. Just as complex numbers are the extension of real numbers from 1-space into 2-space. Describe the effects. Change the datatype for its instance variables to long. but they may also be represented as an angle and a radius. octonions are their extension into 8-space. Supplement the ComplexNumber class to include accessors for the angle and the radius. one which accepts x and y and one which accepts the angle and the radius. quaternions are their extension into 4-space. add two new getters. 2. one for radius and one for angle. That is. Just as complex numbers are the extension of real numbers from 1-space into 2-space and quaternions are their extension into 4-space. Describe the effects. Complex numbers may be represented by x and y as we have done. Complete the RationalNumber class.

352 .

Frequently there are several algorithms which solve the same problem. An algorithm will solve the problem in a finite number of steps and it will solve the problem in a finite amount of time. (Yes. I know that once upon a time I said the name of a class should be a singular noun. If that really bothers you. But I‘d like to look at a collection of simple algorithms and the methods which implement those algorithms. Define recursion Write iterative methods Write recursive methods Write methods that use formulas. Let‘s create a class called Algorithms. Imagine a class that contained the various constants used in physics and chemistry.Chapter 20 . use the name AlgorithmCollection.) What is an algorithm? An algorithm is a set of rules that you can follow to solve a problem. etc. Avogadro‘s number. you will be able to:         Define algorithm Write methods to implement mathematical algorithms Define iteration.Mathematical methods Learning objectives By the end of this chapter. It is often a course taken in the second half of your postsecondary (tertiary) study. Use dynamic programming Introduction Sometimes a class can be a collection of useful constants or methods. This is similar to the way we have seen different Java statements to accomplish the same result. ―Analysis of Algorithms‖ is the study of algorithms (understanding which are better and when) and the development of new algorithms. the speed of light. Planck‘s constant. 353 . Imagine a class that contained information on all the chemical elements.

In a recursive solution. */ private int gcdIterative (int num1.num2. under the control of a loop of some kind. } This algorithm is the Euclidean (or Euclid‘s) algorithm. to reverse a String. there is also a recursive solution as well. in this case a while loop. we needed a method to find the greatest common divisor of two numbers.num1. A recursive greatest common divisor method However. public static int gcdRecursive(int num1. 354 . int num2) { while (num1 != num2) { if (num1 > num2) num1 = num1 . num1 % num2). The code we used is repeated below (but I have changed the name of the method. You‘ll see why in a moment. int num2) { if (num2 == 0) return num1. We saw a recursive method in an earlier chapter. Euclid was a Greek mathematician and the algorithm dates back to around 300 BCE and is described in http://en. Uses Euclid's algorithm.) /** * compute the greatest common divisor of the two * positive parameters. An iterative solution is one in which you perform one step after another. return gcdRecursive(num2. until you reach your solution.org/wiki/Euclidean_algorithm This method implements an iterative solution to the problem. Here is a recursive solution to the gcd problem. else num2 = num2 .wikipedia.Greatest common divisor (gcd) While creating the RationalNumber class. a method develops the solution by making a smaller case of the problem and calling itself again to solve the smaller case. All recursive methods have these two parts:   One or more stopping case(s) for which we know the answer. and A statement that calculates an answer by calling the method with a smaller argument. This continues until a smallest case is reached in which you know the solution. } return num1.

Before we can return an answer. The numbers are not the same. num1 and num2 are not the same. or 42. Hence the name. num1 and num2 are not the same. and num2 is the larger. removing 42 from num2 each time. with a remainder of 1. Both forms of the algorithm produce the same answer (That‘s good!) but the second requires more memory. The second number is not zero. The first may require more time. and num2 is larger. The second number is not zero. For the iterative solution. so it becomes 1029 – 42 or 987 while num1 remains 42. and so num1 becomes the difference. Now num1 is larger than num2. 42). For example. but now num2 is the larger. we need to calculate gcdRecursive(42. methods can return 21. so becomes 42 – 21 or 21. Before we can return an answer. Wikipedia uses 1071 and 1029 as the two numbers for which we wish to find the greatest common divisor. Now both num1 and num2 are 21 so the algorithm terminates and the greatest common divisor is 21. so it becomes 987 – 42 or 945 while num1 remains 42. 21.       We start with num1 = 1071 and num2 = 1029. Now all the waiting.        We start with num1 = 1071 and num2 = 1029. so num2 becomes 63 – 42 or 21 while num1 remains 42. since it requires more steps. and 1029 % 42 is 21. num1 and num2 are not the same. 21). while num2 remains 1029. The second number is not zero. until it becomes 63. Before we can return an answer. so we return the first number. This continues. The second number is zero. 1071 = 3 * 17 * 21 and 1029 = 7 * 7 * 21 so 21 is the largest integer which divides both. For the recursive solution. since it has a number of unterminated methods in memory at one time. unterminated. Sample greatest common divisor calculations Perhaps we should work out an example to see how the iterative and recursive methods work. we need to calculate gcdRecursive(1029. 0). we need to calculate gcdRecursive(21. In fact. num1 is the larger. 355 . and 1071 % 1029 is the remainder when we divide 1071 by 1029. since 2 goes into 11 five times.} Remember that the modulus operator (%) calculates the remainder when you divide the first integer argument by the second. greatest common divisor. and 42 % 21 is zero. 11 % 2 is 1. 42.

That is. Wikipedia has some interesting examples at http://en. int). it will need to become a public static method also. Declaring a method static says that this method is a method belonging to the class. This series of numbers occurs in many places in the world. Fibonacci numbers If you read or saw The da Vinci Code. 21. Of course. you have seen Fibonacci numbers. Fibonacci wanted to know how many pairs you would have. other classes may call the method using the Algorithms. This is because Fibonacci was dealing with questions about the breeding behaviour of pairs of rabbits and it is difficult to breed more rabbits if you have no pairs. F(n) = F(n . 8. The series derives its name from Leonardo of Pisa. 2. if you have one pair. where the first number (F0) is zero. 3. It is not a method which belongs to instances of the class. Mathematicians tell us that the worst performance for the gcd function occurs when the numbers are consecutive Fibonacci numbers. in functional notation: F(0) = 0. which are described below. meaning son of Bonaccio)..wikipedia. the series starts at 1. you will soon have many. In combination with declaring the method public. F(1) = 1. 1. dating back to 200 BCE. etc. Leonardo was posthumously given the nickname Fibonacci (derived from the Latin words filius Bonacci.2) when n > 1 Sometimes. and every subsequent Fibonacci number is the sum of the previous two. The values in the series are 0. 55. it seems like magic the way the method works.gcdRecursive(int. 1. both natural and mathematical. 2. If we are going to use it in outside our class.1) + F(n . 5.org/wiki/Fibonacci. It is a singleton. the second (F1) is one. They were the first line of numbers written on the floor of the Louvre. 34. 13. Note that the iterative method was a private method.Once you have the algorithm explained in a recursive form. functioning as the answer to the secret question if you forget your account number. 1. His father was nicknamed Bonaccio (―good natured‖ or ―simple‖). 356 .

i < n. int f1 = 1. 357 . int t. return rFib(n-1) + rFib(n-2). for (int i = 0. How can two positive numbers added together become negative? It has to do with the way numbers are stored as bits. } We know that there is a limit to the size of ints so we would expect there is a limit to which Fibonacci numbers we can calculate. } return f0. it may change from a positive number to a negative one. } Recall that recursive method work by trying to solve successively smaller problems using the same method. How long does it delay the problem? Recursive Fibonacci method Here is a recursive method to find the nth Fibonacci number. if (n == 1) return 1. public static int iFib(int n) { int f0 = 0. The definition of Fibonacci numbers provides a blueprint for a recursive implementation. Changing from int to long only delays the problem. and there are one or more ―smallest‖ problems for which we know the answer. i++) { t = f0 + f1. f1 = t. /** * recursive Fibonacci.Iterative Fibonacci method Here is an iterative method to find the nth Fibonacci number. but iFib(47) is negative. One of the bits is the sign bit. f0= f1. * @param n The position of the number we wish * @return the nth Fibonacci number */ public static int rFib(int n) { if (n == 0) return 0. That‘s what happens here. iFib(46) looks okay. The result is obviously wrong. When the calculations in the other bits result into a carry into the sign bit.

One that I find particularly interesting was explored by Divakar Viswanath. for convenience. as 1. pronounce ―feye‖ or ―fee‖) or approximately 1. you will find that this ratio comes closer and closer to the golden ratio (φ. The factorial function How many ways are there of arranging 10 people in a line? The answer is 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 or 3628800. In addition. F(n) is the largest integer less than (φn/√5) + 0. 358 . but different.5.ams.  For any other positive value n. The recursive definition of factorial is:  Zero factorial is defined. but he proves that they have an interesting behaviour. I never did see what it would calculate for rFib(46). T(n) = ± T(n . This is an example of the factorial function. we will need to go to BigIntegers. I was too frustrated waiting for it to finish.html) points out that it is not clear what will happen to the numbers in this series. We‘ll see how to do that later. The iterative definition of factorial is:  Zero factorial is defined. T(1) = 1.1) ± T(n . perhaps using a cointoss. and we will have to do something about the speed of the recursive method. The Wikipedia article mentioned at the beginning of this section also has some interesting generalizations of the Fibonacci series. Perhaps your machine is faster than mine.org/mcom/2000-69-231/S0025-5718-99-01145X/home.If you run this method. When you calculate the ratio F(n + 1) / F(n) for a number of values of n.2) The plus or minus signs are equally likely and are chosen independently. Note that the Fibonacci numbers we discussed have an interesting. n factorial is defined as the product of all integers from 1 up to and including n. you‘ll find that it works. it is possible to calculate F(n) via a formula. as 1.618034. but it gets very slow for larger values of n. written in mathematics as n!. The random Fibonacci sequences are defined by: T(0) = 1. for convenience.  For any other positive value n. n factorial is defined as n times n . If we are going to use these Fibonacci methods for large values of n. behaviour themselves. His article (available at http://www.1 factorial.

int result = 1. 15 . * @param n The value whose factorial * @return n factorial */ public static int rFactorial(int n) { if (n == 0) return 1. return n * rFactorial(n-1). The answer is 15 choose five. If we used long instead of int. i <= n. /** * recursive factorial. i++) result = result * i. /** * iterative factorial.The first of these definitions leads to this implementation of the iterative factorial function. written 5!). return result. for (int i = 1. * @param n The value whose factorial * we wish to calculate * @return n factorial */ public static int iFactorial (int n) { if (n == 0) return 1. } Both of these calculate 16! successfully and then overflow when you attempt to calculate 17!. This unusual expression is evaluated as 15! / (10! * 5 359 . } The second definition leads to this implementation of the recursive factorial function. how much further could we go? The choose function How many ways can you choose five volunteers from a group of 15 people? Assume that the order of the volunteers doesn‘t matter.

It is neither iterative nor recursive. which gives rise to this recursive method.org/wiki/Choose for a discussion on this form of the algorithm. Recursive choose method One such more-intelligent algorithm is a recursive one.the number of ways to * choose k items from n.wikipedia. /** * the number of ways to choose n items from m. k . if (n == k) return 1. } 360 . /** * recursive choose . int n) { return iFactorial(m) / (iFactorial(n) * iFactorial(m . or n = 0. return rChoose(n .A Formula! In Java.1. int k) { if (k == 0) return 1.n)). and 𝑛 𝑘 𝑛 𝑘 is also defined as: = 𝑛−1 𝑘−1 + 𝑛−1 𝑘 otherwise. } Unfortunately it does not give correct answers in many cases. k). * @param m the size of the pool * @param n the number to be chosen from the pool * @return m choose n */ public static int choose(int m. It is simply a formula. or n = k. We‘ll use a more-intelligent algorithm. but a formula that uses one of the factorial methods. Note that 1 if k = 0. or we could use a more-intelligent algorithm. See http://en. * @param n the size of the pool * @param k the number to be chosen from the pool * @return n choose k */ public static int rChoose(int n. if (n == 0) return 1.1. How could we modify it to work properly? I suppose we could use longs or BigIntegers. due to the overflow problems we have noticed earlier.1) + rChoose(n . this method is very simple to write.

wikipedia. Secondly. n) */ public static int A(int m.1. unless you have some time to wait. The function is fully-described at http://en.1. n-1)). } But the table referred to above does offer some ideas on how to calculate this function more efficiently.org/wiki/Ackermann. It has its origin in the design of operating systems and was designed specifically to produce problems while running programs. that is. A(4. it has been done. First. n) = n +1 A(m. The definition of the Ackermann function tells us that A(0. Warning . The Ackermann function This is a truly fascinating function. 361 . the numbers become very large very quickly. n . 1) A(m.Do not try to calculate the Ackermann function for large values of m and n. there is a formula which gives you an answer immediately. /** * Ackermann function. return A(m-1.This method gives valid answers in many of the cases for which the previous version did not. Look at the table on that page to see why you should not calculate this function for large values of m and n. * @param m The first parameter * @param n The second parameter * @return A(m. Definition of the Ackermann function The Ackermann function A(m. n) is defined for non-negative m and n as follows:    A(0.1)) Recursive implementation of the Ackermann function This leads to the obvious recursive implementation. A(m. 1). Sometimes there are closed forms for the function. n) = A(m . 0) = A(m . n) is n + 1 for any non-negative n.1) is too large. if (n == 0) return A(m-1. int n) { if (m == 0) return n + 1. A(m. Addition is less likely to overflow than multiplication since the numbers involved are smaller.

pow method expects both the base (in this case 2. n + 3) to be doubles. A(2.The table gives us closed forms for A(1. how do we save it? Storing the data . That idea of calculating and saving values is the idea behind dynamic programming. although there are a few values calculated which we could use. Dynamic programming Dynamic programming. however. the Algorithms class needs the following statement. Here‘s the new version of the recursive Fibonacci method. rFib. We can. One such data structure is the ArrayList. 362 . What type of data structure do we use for the table? When do we create it? Do we want to save it and if so. a technique which remembers the results of previous calculations. there are no simple formulas.Fibonacci We want a data structure that allows us to store two ints (n. a description which even mentions the Fibonacci numbers we have examined already. create an ArrayList<Integer>. and A(3. 2.org/wiki/Dynamic_programming. We want a data structure that is efficient in returning values. So if you follow up the calculation of Fib(100) with a request for Fib(50). n). n) = 2(n+3) – 3 This last equation would be implemented as Math. private static ArrayList<Integer> fibData = new ArrayList<Integer>(). We want a data structure that will grow without any special effort on our part. n + 3 is not. For other values of m and n.0 is a double. We will use n as the index and Fib(n) will be the value in the element. n) = 2 * n + 3 A(3.0 instead of 3. a data structure we have used earlier. As we have seen. n) = n + 2 A(2.pow(2. it would be much more efficient to simply look up the value in a table rather than to recalculate it.0 Note that the Math.wikipedia. so we must cast it to a double. and Fib(n)). A(1. We could have the same effect by using 3. This statement conceals several questions. Dynamic programming involves calculating and keeping the table. n) as well.0) and the exponent (in this case. Why does it mention them? Obviously because to calculate Fib(100) you need all the Fibonacci numbers less than Fib(100). Integer is a wrapper class for the primitive datatype int. But we can‘t create an ArrayList<int>. Thus. (double(n + 3)) – 3. n). is described at http://en.0.

and choose new Algorithms(). and inspect it. and choose rFib to calculate some Fibonacci number. new Integer(1)). return x. Finally./** * recursive Fibonacci * @param n The position of the number we wish * @return the nth Fibonacci number */ public static int rFib(int n) { int result. But what if we wish to serialize the data so that we can use it again next week or next month? 363 . it grows. new Integer(result)). follow these slightly-strange instructions. Then right-click the Algorithms class in the class diagram. right-click the object on the Object Bench. fibData.isEmpty()) { // Contains no values so load a few fibData. you will sometimes find a number of null elements at the end of the ArrayList. return result. As a result of this growth. not on the Object Bench. calculate it and put it there try { Integer x = fibData. the values specified in the definition of the function. we will add it to the ArrayList. new Integer(0)). if (fibData. particularly its static fields.add(1. but the details of how it grows are not described in the documentation. Right-click the Algorithms class in the class diagram. When it needs more elements. this places an instance of the class on the Object Bench. } } We have loaded the ArrayList with the smallest set of values. Any time we calculate another value. } // is the answer in the arrayList? // if not.get(n). To see that this actually works.add(0.add(n. What is the size of the ArrayList and what are its contents? The answer depends on which Fibonacci number you calculated and which numbers you have calculated in the past. The constructor I used above creates an ArrayList of 10 elements. fibData.intValue(). } catch (Exception e) { result = rFib(n-1) + rFib(n-2).

get(i)). so remove any extra elements // and then try to serialize it fibData.writeObject(i). it will work well as we deal with functions of more than one variable. // fibdata exists. We declare the table of data values. import java. and for the XMLEncoder. When we restore the file. maybe in an applet } // end catch } This will create the file. But this does not work with static methods. try { XMLEncoder e = new XMLEncoder( new BufferedOutputStream( new FileOutputStream("fibonacci. We need to have three import statements.close().util. Recall that we are using a static method. in fact. When we create the file.xml"))). we could use the finalize method which is invoked by the garbage collector.bean.util.ArrayList.List.size(). i++) { e. 364 .trimToSize(). e. This section uses XML serialization. // private instance variables private static List<Integer> fibData = new ArrayList<Integer>(). it must read and write its own files. If the method were associated with an object. we will restore the value to the correct place. Thus we need to add the following statements to our static method. previous chapters contained two ways to serialize data. As such. While this may seem overly complicated for a couple of integers (and it is).writeObject(fibData. the ArrayList. import java. when we serialized various classes in our college model.xml. } e. i < fibData.Fibonacci We have seen how to serialize data before. for (int i = 0.Serializing the data . for the List. we will store the index and the value. } catch (IOException e) { // can't write. import java. fibonacci.XMLEncoder.

add(0. new Integer(0)).xml"))). If not. value).isEmpty()) { try { // does the file exist and is it readable? XMLDecoder d = new XMLDecoder( new BufferedInputStream( new FileInputStream("fibonacci. if (fibData. } } d. fibData.add(1. // read as much data from the file as possible boolean more = true. 365 . } catch (Exception e) { more = false. Integer value. it checks if there already is data in the table. value = (Integer) d. we need the following statements.close().readObject(). we load the data from it into the table. } // end try catch (FileNotFoundException fnfe) { // cannot find file. we create the table ourselves by adding the two values we need. so start with // minimal set of values fibData. and the value of the function is the element for the ArrayList.Run a unit test and see what is stored in the file. while (more) { try { int i = (Integer) d.add(i. of courses. it checks if the file the method wrote earlier exists. Deserializing the data . If not. Storing the data – Ackermann function The Fibonacci method implements a function of one variable. fibData.readObject(). } catch (IOException e) { } // end catch } When we use the method. if so. at the beginning of the method.Fibonacci To retrieve the data stored in the file. so we can use that one variable as the index for an ArrayList. new Integer(1)).

import java. n). new Integer(result)).util. n). 1). so we can‘t use an ArrayList.put(new Point(m. 366 . Instead. we add it to the table of remembered data. Integer> ackData = new HashMap<Point.HashMap. if (m == 0) { result = n + 1.But the Ackermann method implements a function of two variables.put(new Point(m. n). new Integer(result)). we serialize three. Recall that a HashMap provides a key (the two parameters to the function) and a value to which the key maps (the value of the function. ackData.put(new Point(m. n-1)). (Note that we could have used a HashMap with the Fibonacci function. } else { if (n == 0) { result = A(m-1. Integer>(). we need a HashMap. } else { result = A(m-1. although designed for graphics. a result. the key would be one integer and the value would be the other. But instead of serializing two Integers.) import java. import java. new Integer(result)). will serve as our key.awt. } } Serializing the data – Ackermann function We can use the serialization technique we used in the Fibonacci function to serialize the Ackermann function. Whenever we calculate.util. as the Ackermann function is a function of two variables. ackData.) The datatype Point. ackData. A(m.Point.Map. Deserializing the data – Ackermann function We can use the deserialization technique we used in the Fibonacci function to serialize the Ackermann function. We declare the variable private static Map<Point.

Summary We have seen how to write several mathematical functions. it is always possible to create a number so large that the memory of the computer is not large enough to hold it. We can address that with the BigInteger class. That‘s the fun of working with numbers. and using (for the Fibonacci and Ackermann functions) dynamic programming techniques. there is always one bigger. Of course. The main problem some of these methods have is that the results become large very quickly. 367 . The other methods in this class don‘t need. but could use. should we wish. dynamic programming. using iteration and recursion.

until the last child gets all the items (if any) after the last item removed. Use this formula to allow you to calculate the expansion of (x + y) raised to the power n. Implement a class that contains some of the physical or chemical constants. 2. How does this formula arise? Imagine m + n . 5. Explore the Koch snowflake. 3. 368 . Explore Pascal‘s triangle and the functions associated with its elements.1 items lined up. The first child gets all the items (if any) up to the first item removed. And so on. the number of ways to do it is +𝑛−1 calculated as 𝑚𝑛−1 . in either its iterative or recursive form. 6.Exercises 1. Create a method which will draw the triangle. If you wish to divide m presents among n children. Write a class that contains some of the chemical elements and their properties. Modify your Fibonacci function to use at least longs if not BigIntegers. 4. Create a method which will draw the snowflake. Use your Fibonacci functions to explore the ratio F(n + 1) / F(n) as n increases. Recursion appears in many graphics situations. The second child gets all the items (if any) up to the second item removed. Remove n – 1 of them. Write a method to calculate this function. Explore the Sierpinski triangle. One such function is the choose function.

org/wiki/Thread) defines a thread as ―a way for a program to split itself into two or more simultaneously (or pseudo-simultaneously) running tasks. there are some issues relating to threads which we should discuss. and input using the Scanner class Introduction We have looked at many aspects of creating solutions using Java. 369 .) The Java interpreter uses a garbage collection thread to identify objects for which there are no references.Chapter 21 .) and both are running at the same time as the thread that allows me to type the document. Threads . It then reuses the memory for new variables. we need to consider how threads work in Java. For now. In particular. Simultaneously. and other topics Learning objectives By the end of this chapter you will be able to:      Define and use threads Define and use inner classes Define refactoring Explain public static void main(String[] args) Perform output using the System class.‖ Have you ever been working in your word processor and made a spelling or grammar mistake? A word appears underlined (in my case in red) to indicate a spelling mistake. which itself may have threads (checking for appointments and incoming mail. other processes are running on my computer. and all the code we have seen works. You‘ll see how threads and processes interact in an operating systems course.definition Wikipedia (http://en.Threads. for example. A phrase appears underlined (in my case in green) to indicate a grammar concern. I don‘t know for sure. But it is not all well-written Java. but these processes are part of another program.wikipedia. A spell-check thread is running at the same time as a grammar-check thread (or maybe one thread is doing both checks.

setVisible(true). box. Thus. These create a Runnable object and then place that object on the event queue. I have used the GUI for entering MyDate values. an event-dispatch thread is listening for events and the notifying the appropriate handlers. In the background. } }. first-out) and the event-dispatch thread removes them as appropriate. the queue itself will keep the screen displayed until it is ended. Now that the data entry form is on the event queue.invokeLater(runner). 100).setPreferredSize(500. For these components. events may not be handled immediately if a previous event is being handled slowly or if many events are happening at the same time. We wrote data entry screens for MyDate and for Section. 300). Pay particular attention to the lines with shading and the commented lines. // // while (box. public static void showDataEntryFrame() { Runnable runner = new Runnable() { public void run() { JFrame box = buildDataEntryFrame(). 370 . These have the potential to fail at some point because we did not consider threads. } Note that we have made only a few changes. We wrote a number of data entry screen and menus. it may be called from different threads without unwanted interaction between the threads. we have added a few statements. EventQueue. That is. First. and applets. we responded to events which occurred to these components.exit(0). box.Threads and Swing Threads are most relevant for our data entry screens. Then we have deleted a couple of statements. box.setLocation(100. using Swing components. as indicated by the shading. Events are placed in a queue (first in. menus. Here is the code to create a thread-safe GUI or applet. The deleted statements made sure the data entry form remained on the screen.isVisible()) {} System.

getText(). public void actionPerformed(ActionEvent e) { JMenuItem source = (JMenuItem)(e.org/wiki/Inner_class) as ―a class defined entirely within another class. Let‘s see how to do that. we needed to indicate that the CollegeMenu class was responsible for handling events associated with that menu item.wikipedia. if (source. the one we have used the most is the anonymous class. }. } if (source.showMessageDialog(null. The actionPerformed method then is a series of if statements. The first event handler we created in the GUI should have been a series of event handlers. "About". The InputVerifiers we used are anonymous classes. implemented as anonymous classes. For each item on the menu. As a consequence.exit(0). An inner class is defined in Wikipedia (http://en.) are anonymous classes.addActionListener(this). "CollegeMenu .demo program for COSC 111/121". the class is required to implement an ActionPerformed method.INFORMATION_MESSAGE). and doing an appropriate action. Recall that we created a CollegeMenu class which implemented the ActionListener interface.‖ There are several types of inner classes. but it is one we have been using occasionally from near the beginning of this book.getText(). JOptionPane. Note that we have seen this trick. indicating they would not be changed by the actions in the inner class. menuItem. 371 . } // do something for each menuItem return.equals("About")) { // display message box JOptionPane.Inner classes This topic is often considered to be an advanced topic.equals("Exit")) { System. identifying the source of the item. It was our use of inner classes that made it necessary to declare come components of the GUI as final.getSource()). when we created the Section data entry screen. The Comparators we have used while creating collections (and specifying the order of elements within the classes.

but not always great code. When we create that menu item. Refactoring Throughout this document. menuItem. this actionPerformed method becomes longer and longer. we need to add a comment to it. /** * handle events for which there is no separate listener */ If you wish to have very complicated Java code. we need menuItem. we have seen good code.exit(0).addActionListener(exitListener). } } But this is not something I‘d like to see. it would be better to simply assign the same ActionListener. /** *action listener for exit menu item */ ActionListener exitListener = new ActionListener() { public void actionPerformed(ActionEvent e) { System. After all. It becomes less and less cohesive since it is making more and more decisions.As the number of items causing events increases. we need to ensure the exit menu knows about this listener.exit(0). We have seen code that a programmer would write if he or she was unaware of some of the latest advances in software engineering. what if there were several ways to cause the same event to happen? You‘d need to repeat this code several times.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { System. } }. 372 . Here is the listener for the exit menu. Of course. As we move listeners out of the original actionPerformed method. We should specify a separate listener for each item on the menu. and more and more complicated. and we do this with anonymous classes. you can use inner classes and create the actionListener as follows.

Depending on the testing you wish to do.In particular. But not everyone uses BlueJ. 373 . We will surely use these in other places. too. the toString method. example of InputVerifiers. We have developed them for year. and the getters and setters. That is. Recall that we created unit tests for Student and Professor. Thus. and time. We have been fortunate that they were only used in that one class. month. How do you run programs when you don‘t have BlueJ to help? You create a main method in your class. you create a method whose name is main and whose signature is the heading for this section. Can you find other places in the code we have seen which would benefit from some refactoring? public static void main(String[] args) Now we can look at the statement with which most Java books begin. one thing that we have done is to create Comparators within the class that needs them. Wikipedia (http://en. If we didn‘t have BlueJ we would have needed a main method. and use them as necessary. This idea of improving the structure of your design and its resulting program is the foundation of refactoring. and BlueJ has its limitations. possibly better. declare them static. as the College application expands.wikipedia. So we should move them to another class. while explicitly preserving its meaning or behavior. You will create a class which generates and displays the GUI. Suppose you are testing. we should move the Comparators to another class. We have used BlueJ to allow access to the methods of our classes and objects. Suppose you wish to create a GUI for an application. In it we would have constructed one or more objects and then invoked the methods we wished to test. there may be a main method for each class you wish to test. ―Refactoring is the process of rewriting a computer program or other material to improve its structure or readability. and then use them as necessary. However. we may find that we need those Comparators in other classes as well. In each. you may be running from the command line. Without an integrated development environment like BlueJ. declare them static. day.‖ That definition would even include using constants like MAX_MEETINGS in place of the number 5. That class will contain a main method.org/wiki/Refactoring) gives this definition. Similarly we have the. we tested the constructors. We started to develop one for rooms.

println as a way to display output. But Scanner is occasionally useful in the BlueJ IDE. How do we input from the command line? The Scanner class is used for input. String[] args tells us that we can provide arguments to the main method. the arguments are placed on the command line after java SomeClass. The Java interpreter expects to find a main method. it just completes. this will be the tool you use for input. If you are using the command line.java to compile the class. Yes. The arguments are provided as elements of the array of String called args. BlueJ created this for us in the background. the first one is placed in args[0]. Input and output We have seen System. it doesn‘t return any special value to the operating system. which is accessible within the main method. similar to the way we provide arguments to applets. To execute the main method of SomeClass. public static void main(String[] args) public tells us that this method is available outside the class. It has to be so that others can invoke it. main tells us the name of the method. you‘ll need to use the command java SomeClass and the Java interpreter will look for a method named main. the second in args[1]. Let‘s examine the parts of the header for this main method. look it up in the Java online documentation for more details.out. We have not needed it since we are using the BlueJ IDE. To see how to use it. 374 . void tells us that when the method completes its processing.You‘ll need to use the command javac SomeClass. static tells us that there is only one copy of this method in this class. If you will be using your program in a command line environment.

Now you have a good basis for going forward and using Java.Summary This chapter completes our discussion of the Java language. since this is only an introduction to Java. 375 . and for learning more about Java.

4. Modify the CollegeMenu so that it uses inner classes. Modify the data entry screen for the Section class so that it uses inner classes. 2. 3.Exercises 1. 376 . Modify the data entry screen for the MyDate class so that it uses inner classes. Modify the data entry screen for the Section class so that it is thread-safe.

Go forth and expand your knowledge. Include subjects taught and when as a separate class. Customisation – How do you allow people to change the colours of your interface? How do you allow them to change the way courses and rooms are numbered? Program standard OO examples. Sports players and their teams. A related example of inheritance. 377 . phone number. The most common one is different types of bank accounts.In Conclusion Now we have seen how the basic (and some not-so-basic) techniques of Java allow us to implement our ideas. degrees (where. This environment will use inheritance and the Singleton pattern to provide interest rates. subject. Here are some possible areas you may wish to explore to build upon the knowledge you have gained here. See the appendix for the labs I used while teaching a course using this textbook for the first time. when). How to normalize them and how to use them with Java programs.      Professor class – office number. Databases.

378 .

Richard Helm. Michael Nairn. Prentice-Hall 1988 Larman. Testing First: Emphasizing Testing in Early Programming Classes. Craig. John Vlissides. No Starch Press.. The C Programming Language 2nd ed. John Haddow. Erich. O‘Reilly. and Dennis Ritchie. Timothy Java phrasebook. Just Say ―A Class Defines a Data Type‖. Rudolf. Ralph Johnson. Communications of the ACM. 2007 Hu. James H. ACM SIGCSE Bulletin. number 3. ACM SIGCSE Bulletin. 280-4 Pecinovský. John The Definitive Guide to Java Swing. Chenglie. and Greg Wilson. volume 38 number 3. Sams Publishing. A Design Patterns Extension for the BlueJ IDE. Pete. 2002 Oram. Brian. 19-21 Kernighan. 4-8 Metsker. Prentice Hall Ptr 2004 Marrero. Code Craft. 2007 Gamma. 188-92 Zukowski. Let’s Modify the Objects-First Approach into Design-Patterns-First. volume 38 number 3. Luboš Pavliček. Beautiful Code: Leading Programmers Explain How They Think. 1995 Goodliffe. 3rd ed. volume 37. Addison-Wesley. Addison-Wesley. Andy. number 3. Steven John. Design Patterns: Elements of Reusable Object-Oriented Software. 2007 Paterson. Jarmila Pavlíčková. ACM SIGCSE Bulletin.References Printed Reference materials Fisher. Design Patterns Java Workbook. Will. APress 2005 379 . Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development. 3rd ed. volume 51. and Amber Settle.

html.html Unicode.onjava.com/p/relativelayout/ (viewed 2010-05-21).com/newsletter/July2002/setinterface.org 380 .horstmann.G.com/javapro/2004_04/online/rule5_04_07_04/ Liu. http://code. Ganesh. http://www.unicode. http://www. Rachael Bennett. http://www.F.bluej.javaranch. S. John. Java tutorial.org Wikipedia. James. teachers. http://en. Part 2 – The Set Interface http://www.ftponline.com/pub/a/onjava/2002/11/27/layout2. James. a Constraint-Based Layout Manager.org Kolawa. Thomas.junit.org. Adam. http://www.html O‘Hanley. RelativeLayout.sys-con.onjava. Elliott. Cay. Brian. http://java.Online references BlueJ – the interactive Java environment.org/mhonarc/lists/gef-dev/msg00469. http://java. and Anastassia Drofa. Collections in Java.javapractices.com/docs/books/tutorial/index. http://www.html (viewed 2006-05-20) Elliott. Rule 5: Make your clone() method final http://www.wikipedia. Gina Assaf.com Paul. Inside RelativeLayout.com/read/564291.org. http://java. and Roberto Scaramuzzi.html (viewed 2006-05-20) Ellis.eclipse.com/javase/6/docs/api/index. RelativeLayout.sun. J. Java online documentation. and authors who need to produce simple UML diagrams quickly.html JUnit.org http://www.com/pub/a/onjava/2002/09/18/relativelayout.sun.htm (viewed 2008-05-27) Horstmann. Uncommon Java Bugs.google. http://www.com/violet Violet is intended for students. http://dev.

I needed some assignments which were similar to. You may find the assignments useful. I provide the assignments I used. but not identical too. In this appendix.Appendix 1 – Sample lab assignments Introduction The first time I taught a course (The course extended over two 13-week semesters.‖ Details on lacrosse and links to teams and leagues will be given in lab assignment 1. supplemented with additional information I had to provide to the students as they were not familiar with much of the material discussed. A lacrosse league provided the first few assignments. The slogan on the T-shirts was ―Real athletes play sports. Modelling a lacrosse league presents many interesting problems in object-oriented analysis and design and lots of opportunities for student learning. great athletes play lacrosse. 381 . the examples used in the textbook. My son used to play box lacrosse.) based on this book. In particular. The subsequent assignments followed the topics in the textbook. a sport popular in Canada and parts of the United States. I needed a series of lab assignments.

in YYMMDD format. At the moment. This account has your student number as the username.bluej. Microsoft Office is available for your word processing. Do not submit a repeat request until you are sure that your job has disappeared.) I encourage you to install this software on your home computer. One reason for disappearing jobs is that your name is not visible on the job.Lab Assignment 0 . that page also provides a link to download the Java software (you want the latest version). Procedure: Computer labs at the College are available during scheduled lab times and at other times. The parts of the Java language are available from java. print only what you need to print.0 Documentation as well.Getting to know you Objectives: The purpose of this lab assignment is to see and become comfortable with the computing environment you will be using in this course. but it will not remain that way if you abuse the privilege. So. you also need to have an account. Hint. When is this lab available? The answers for our labs are available online. hint! The programs mentioned above may be used in many courses. Note that your print requests are put into a queue. There may be other jobs in the queue which arrive before yours. So let‘s look at how we use BlueJ. printing is free. You may print from these programs to a shared printer. In particular. The BlueJ environment is available at www.sun. Both Internet Explorer and Firefox are provided for your web browsing. you need to become comfortable with a programming environment named BlueJ. when lab monitors are available. a list of print requests. spreadsheet. To use a computer lab. your job may not start printing immediately. As a result.com. and database needs. 382 . Make sure that you download the J2SE 5. I mention this as you may find it difficult to gain the access you need to the computer lab and you will be using the software a lot. and your date of birth as the password.org/download/download. Ensure that you can log in to your account. J2SE 6 became available. Maple is available for your calculus course.html. and do not print multiple copies unless absolutely necessary. Note that the two major programs we will be using in this course (and the following course) are available for free on the web. and there may be others with a higher priority. What programs can you use once you have logged in? The College provides many programs. (During the course.

generally found in the eastern part of North America. are a number of disabled buttons. on the left. You will see something like the screen below. and close the program. On occasion. it wanders as far west as British Columbia. 383 . Blue is … Anyways. at www. a collection of classes. click the icon. In western Canada we have the Steller‘s Jay. You can see that the two species are related from the common family name Cyanocitta. Why is the Blue Jay on the icon? I guess it‘s a play on words. Below the menu. A menu appears below the title bar. these buttons will become enabled.org. Once we begin to work with a project. Cyanocitta cristata. show a bird called the Blue Jay. Cyanocitta steller. BlueJ appears as a typical Windows application.bluej. The Steller‘s Jay is the official bird of British Columbia. maximise.The icon and the BlueJ website. BlueJ is a programming environment for programming in the language Java and J is an abbreviation for Java and. The title bar contains the name of the program plus buttons to minimise.

This option allows you to create and remove classes. Testing is also very important when writing code. currently saying ―Package saved‖. The second option is ―Edit‖. translating them into the bytecode the Java interpreter processes. we need to compile them. There are options for all these. collections of classes. in some cases a project will represent your work over several weeks. The ―Project‖ menu also allows you to quit BlueJ (―Quit‖). the ―Documentation‖ option analyzes the documentation we have created and formats it nicely. empty project (―New Project‖). Now we consider the Help menu. If a project has several classes. let‘s look at the menu. To run and test the Java classes we write. You will get to know all of these intimately by the end of the course. The first option is ―Project‖. This documentation is created from simple statements we insert in the code. BlueJ displays a diagram representing the classes we use in our project. We will be creating projects. The ―Testing‖ option allows us to run some or all of the tests we create. For example. You can also print a project. a project will represent your work for a one-week period. Perhaps we need to compile them all. The ―View‖ option allows us to customise the appearance still further. including the class diagram and/or the source code. For now. I have old eyes so I have modified the font size to 20. as well as to close and save projects. on the right is the class diagram. There are several categories on this menu. The ―Preferences‖ menu includes things you change less-frequently. Below the column of buttons and the class diagram is another window or two. 384 . The Project menu allows you to create a new. Below that is a message area. as well as create new arrows on the class diagrams. The third option is ―Tools‖.Below the menu. In some cases. ―Preferences‖ allows us to set many preferences in the appearance and working of BlueJ. to open an existing project (―Open Project‖). we may need to compile only one or we may need to compile many. to open a project on which you have worked recently (―Open Recent Project‖). Documentation is very important when writing code and Java supports a very nice type of documentation. In this area. beginning with its ―About BlueJ‖ option. The choices on this menu are things which you may wish to change frequently.

385 .bluej. Deakin University (www. in Melbourne and other parts of Australia. The BlueJ project started at Monash University. At Okanagan College. and the University of Kent (www. Use this to decide if there is a newer version of BlueJ than the one you are using. check http://www.edu. so the information from this choice is for information only. you do not have the authority to install software. It may be better to keep the same version at home and school. including the BlueJ website. To dismiss the About box. The About box shows the version of BlueJ you are using and the version of Java you are using. The next Help menu option is ―Copyright‖. The next Help menu option is ―Check Version‖. For more about extensions. The next Help menu option is ―Installed Extensions‖.uk/). At home. click Ok or press .deakin.au/).We see that BlueJ is a product of teams at two universities. you can keep it up to date if you wish. Notice that there are only a small number of people involved in the BlueJ project.org/extensions/extensions.kent. It then shows a few other pieces of information.ac. in Canterbury and other parts of England.html. newer versions of both are probably available. in Australia and migrated to Deakin and Kent.

0. Now that you have quickly seen the menu.com/j2se/1. displaying the site in your default browser. neatly-formatted. Read and follow the steps in that tutorial. a site which describes everything you would like to know about the Java language. We will be visiting this site regularly. Complete the first three sections of the tutorial.1. The main task of this lab assignment is to complete the tutorial.bluej.X and we are using 2. Rather than create my own tutorial. Yes. Due date: Two weeks 386 . This is a very important link. it‘s time to use BlueJ. the tutorial is for BlueJ 2. Note that I will not be repeating material from the tutorial in subsequent labs. This is a very complete tutorial on how to use BlueJ. Make sure that the note is word-processed. This could be handy should you be using BlueJ while you are not connected to the Internet.0/docs/api/index.sun. The next Help menu option is ―BlueJ Tutorial‖.org. The final Help menu option is ―Java Class Libraries‖. and free of grammar mistakes.5. Hand-in:  A note to me stating that you have completed the first three sections of the tutorial. It leads us to http://java. I will direct you to the ―BlueJ Tutorial‖ option on the Help menu. This provides a direct link to www.The next Help menu option is ―BlueJ Web Site‖. perfectly-speled. so you should complete the rest of the tutorial when it is appropriate.X but I haven‘t found any differences. Note that you can download the documentation to your own computer and have this menu option link to your local copy.

craigmarlatt. you will use Java classes to model a box lacrosse league.  The Western Lacrosse Association (www. Many players play both summer and winter. Goalies have one type of statistics. Look at the statistics for the New Westminster Salmonbellies to see the type of statistics kept for goalies. When you looked at the league websites. Create and test a class called Player. when there is no ice in place. In the next series of lab assignments. and box lacrosse is a variant played in hockey arenas during the summer. Procedure: Lacrosse players all have first and family names.Lab Assignment 1 .theboxrocks. and the number of goals allowed. the number of shots faced.com/canada/symbols_facts&lists/symbols.html Lacrosse comes in two varieties.com). create. and many players switch summer leagues from time to time. Background: Lacrosse is the official Canadian summer game (as ice hockey is the official Canadian winter game. To see what modelling a box lacrosse league involves.Players Objectives: To design.com) has teams in Canada and the United States which play their season during the winter.nll.majorserieslacrosse. The 2006 Mann Cup playoffs were scheduled for September 8 through 16.  The National Lacrosse League (www. has teams in British Columbia which play their season during the summer. or MSL. you may have noticed two types of player statistics.com) has teams in Ontario which also play their season during the summer. you should investigate the websites for the three professional box lacrosse leagues with Canadian teams. reflecting the two different types of players. field lacrosse is more similar to the original sport played by First Nations in Eastern Canada. formerly the Ontario Lacrosse Association. The champions of the WLA and MSL play off for the Mann Cup.  Major Series Lacrosse. 387 . The numbers shown for the Salmonbellies goalies are the sum of a number of single-game statistics. and test classes using the BlueJ environment. or WLA. (www. So that they can be paid. including the number of games played. they also provide their Social Insurance Number.) A website which describes how this came to be is http://www. Feel free to use any classes from the textbook if they are useful.

While the second is easier. The second is to record the number of events in each game. A GoalieStatistic object contains details for a single game. Since a goalie is a player. including goalies. Assist. and for a Goalie object to contain a collection of GoalieStatistic objects. we can see that the WLA is using the first way of recording these statistics. In August 2006. so we will not pursue it further except that we will need a Goalie object. Create and test a class called GoalieStatistic. For example. Create and test a class called Goalie. penalty) separately. and Penalty classes from PlayerStatistic. But we don‘t have a league object yet. the first is more flexible. can receive penalties. one assist. if you derive Goal. GoalieStatistic. two-minute penalty at 11:23 of second period. For example. this is best accomplished by deriving a Goalie class from the Player class. one goal. the number of shots faced. and score and assist on goals. One of the observations that came up from this was the length of time between the first and the last goals. The alternative is for a Player object to contain a collection of PlayerStatistic objects. the numbers shown on the websites represent the sum of separate statistics. Which is the class which contains these collections? Following the model in the textbook. assist. Hand-in: Provide me with the Player. The find is to record each event (goal. assist at 1:53 of second period. Assist. Goal.Scoring and penalty statistics are the second kind of player statistics. This design may possibly cause difficulties later. As for the goalies. All players on a lacrosse team.Teams and Leagues 388 . goal at 12:45 of first period. Due date: TBA Lab Assignment 2 . and PlayerStatistic classes. you might suggest a League object. You may find you have a better design. Thus. Goalie. the number of minutes played. seven minutes of penalties. Also provide any other classes you have developed to support these classes. and the number of goals allowed. Kerry Susheski scored nine goals in a playoff game. These details should include at least the date of the game. There are two different ways to do this. We will create one in the next assignment. Create and test a class called PlayerStatistic. five-minute penalty at 7:25 of third period. You will need collections of GoalieStatistic objects and PlayerStatistic objects. Penalty.

The type of information necessary for a Team class is shown at http://majorserieslacrosse. fired) or placed on/removed from an ―injured-players‖ list at any time. In this assignment. there are three professional lacrosse leagues with Canadian teams. A Team may change its name from time to time. Note that a League contains a collection of Team objects. often like the number 0. we will create Team and League classes. and test classes using the BlueJ environment. They moved back to the Lower Mainland and changed their name to the Langley Thunder. You may find it easier to just model one season. Thus a League object needs to know the teams it contains in each year. Each team needs to know the players it has on the team. Occasionally a goalie will prefer 00. What are appropriate structures for these collections? Each team needs to know its schedule against all the other teams in its league. For example.ArrayList<Team>> to store this collection. create. and then stored a team‘s schedule in an ArrayList<ScheduleEntry>. 389 .com/teams/brampton.html. Procedure: Create and test a Team class. being unusual people. and it may or may not participate in a league in any particular year. Goalies. In that case. the profile for the Brampton Excelsiors of the MSL.Objectives: To design. I created a ScheduleEntry class. The type of information necessary for a League class is shown on any of the three league websites mentioned in the previous assignment. the North Shore Indians were a team in the WLA. The two numbers 0 and 00 are different. They moved to the Okanagan and changed their name to the Okanagan Thunder. When a player joins a team he/she is assigned a jersey number. Jersey number is the key to use when setting up a HashMap<String. The Integer refers to the year and the ArrayList is the list of teams. Assume that players may be traded (to another team) or released (essentially. Background: As we mentioned in the previous lab assignment. despite what mathematicians say. you simply need to use an ArrayList<Team>. I used a HashMap<Integer. Create and test a League class. Player> of players on a team. Recall that the League also contains collections of PlayerStatistic objects and GoalieStatistic objects.

Include persistence for the goals. If you would like a challenge: Each league has its own rules about the number of active (that is. not the teams. we would require some form of persistence to remember data from one run of the program to another. Implement persistence. Ensure your Team and League classes support all the above information. Hand-in: Provide me with the Team and League classes and their unit tests. If this were a real application. and penalties. active players. or is it better for the League to construct a schedule by asking all the Teams for their own schedule? Patterns say that the League should own the schedule. You will need static variables. and injured players) and leagues. Each league has its own rules about the number of active players (including goalies) a team has. We can use unit tests to populate teams (including their schedules.Consideration: Is it better for the League to know the schedule for all games in the season. Due date: TBA 390 . assists. Implement these rules as part of League. You may wish to use exceptions to detect a violation of the rules. not including those on the injured-players list) goalies a team has.

Which goalie has the best save percentage? Which goalie allows the fewest goals? Which players win their team scoring championships? Which player wins the league scoring championship? Which team wins the league championship? To answer these questions we need to ask the right questions to the right objects. although this would be unusual. on a team or in a league. PlayerStatistic. this could be quite common. Which players win their team scoring championships? Which player wins the league scoring championship? The league knows the teams it contains and it can ask each of those teams about its own scoring. The league can then combine those answers and produce its own answers. In fact. Modify League to include a method to use these new Team methods. on a team or in a league. modify Team to include a method that will determine which of its goalies has the best save percentage. Note that several goalies may be tied. GoalieStatistic. you probably have the number of shots the goalie has faced and the number of goals he/she has allowed. Make it so. Sometimes an object will have to ask other objects for help in answering the questions.Lab Assignment 3 . Note that two or more goalies may have the same save percentage. Procedure: Which goalie has the best save percentage? In your GoalieStatistic class. with each goalie playing half the season. Which goalie allows the fewest goals? The league knows the teams it contains and it can ask each of those teams about its own goalies. Team. and League classes. we can use them to produce a few reports. Modify Team to include a method that will determine which of its goalies allows the fewest goals. Goalie. and test classes using the BlueJ environment. Assist. The league can then combine those answers and produce its own answers.Reporting Objectives: To design. 391 . Background: Now that we have created Player. Note that two or more goalies may have the same number of goals allowed. as some teams alternate their goalies. Note that several players may be tied. Goal. The save percentage is (shots faced – goals allowed) / shots faced. Penalty. That is. create.

Hand-in: Provide me with the revised Team and League classes.and fourth-place teams play a single-elimination game and the second. again with two points for a win. (See http://www. and modify League to determine the player(s) with the highest points total.nll. In each. and zero for a loss. second-. The division champions then play a single-elimination game for the league championship. modify Player to include a method to calculate the number of points (two for a goal.theboxrocks. That is.) In the NLL. the second. Add playoff data to the League class so that the League can identify the champion teams and produce a report showing the results of all playoff games.Make it so.com/playoffs.and third-place teams play a best-of-seven series. Then use WLA/MSL rules to determine which teams are in first-. In the WLA and MSL (both of which have only a few teams) the first. If the teams are still tied. (See http://www. and zero for a loss. consider only the games they have played against each other. with the winners playing a single-elimination game for the division championship.and third-place teams play a single-elimination game. assuming two points for a win. Modify and test the Team class so that the results of games are known. one for an assist) each player earns. If two teams are tied. third-.com/l_play_offs. use a random number to simulate a coin toss. one for a tie.) But we don‘t know the placing of the teams since we have not recorded the winners and losers of the games played. modify Team to determine the players(s) with the highest points total. there are two divisions. one for a tie.and fourth-place teams play a best-of-seven series.shtml for the winter 2006 results. Which team wins the league championship? This is harder since the rules in the leagues are slightly different. and the winners of those two series play a best-of-seven series for the championship. each approximately the size of the WLA or MSL. the first. and fourth-places.asp for the summer 2006 results in the WLA. Due date: TBA 392 .

) Imagine a Trade class which contains two collections of Players objects. That data includes:  Player demographics (This will include name.)  Scoring statistics (These have been described in an earlier assignment. contact info.Data Entry Screens Objectives: To design. along with player and goalie statistics. etc. Due date: TBA 393 . There should also be a comments field.  Player placed on or removed from injured list (This will include type of injury and expected return date. Background: How do we enter much of that data we have been manipulating? We can create test cases using setters. date of birth .Lab Assignment 4 . Assume there are no ―future considerations‖ trades. but that is not suitable for real world use. Hand-in: Provide me with all the code necessary to create and test your data entry screen(s). and test classes using the BlueJ environment. and Social Insurance Number)  Player trade information (A player may be traded for several players. Create one or more of the screens identified above.)  Results of games (This will include who won and who lost. address. one for the Player(s) the teams gives up. or create another screen which is appropriate.)  Team name. create. we should create a data entry screen. and the other for the Player(s) the team receives. Instead.)  Goalie statistics (These have been described in an earlier assignment. A player may be part of a trade for several other players. Procedure: Create a data entry screen to allow for entry of some of the data we have identified.

Now we will examine an area where Java shines. For a larger challenge. 394 . Create a web page to use the applet. we have been developing an application which could have been developed in many languages. Japanese. you will explore several applets. which require Unicode characters. create and run the HelloWorld applet as it is given in the textbook. Procedure: Chapter 7 of the textbook discusses applets and how to create them. Australia ( ). Korean. embedding programs into web pages. In this assignment. have the applet display in only one language.altavista. Have the applet display the message in several different languages. While following that example.Lab Assignment 5 . and test classes using the BlueJ environment. More challenging are the flags of the Seychelles ( ( ). and New Zealand ( ) and use it to create the flags of Niue ( ). We‘ll create some applets. You could ask around for different translations. The centre bar on both is white and the bar on the right is red. or you could look at http://world. The difference doesn‘t show up in black and white. create. For the second applet. but have that language change (among a few different languages) as you run the applet again and again. ). choose one or more of the languages from those such as Chinese.com/tr For an extra challenge. while the bar on the left of the Italian flag is green. but the bar on the left of the French flag is blue.And now for something completely different Objectives: To design. Background: We have finished with the lacrosse league example. For the first applet. Hebrew. create a flag applet that displays either the French ( ) or the Italian ( ) flags. or Arabic. Macedonia ( ) and Nepal Then create the flag of the United Kingdom ( ).

html (loading more slowly since all flags appear on one page). Illustrations of these and other flags are at many places on the Internet. Pay particular attention to the stars on the last two flags.flags.This illustrates the important topic of reuse.gov/cia/publications/factbook/docs/flagsoftheworld.cia. Hand-in: Your HelloWorld and Flag applets and the web pages to run them. Due date: TBA 395 .net (loading quickly since there is a page for each letter of the alphabet) and https://www. including www.

Implement each of these operations and test them thoroughly. Implement and test a method to convert a RationalNumber to its decimal equivalent. Can you do this in a way that is totally transparent to the users of your class? Implement and test a ComplexNumber class. and division. Hand-in: The RationalNumber and ComplexNumber classes.Lab Assignment 6 . In particular.Mathematics I Objectives: To design. In this assignment you will complete the missing parts of chapter 9. Ensure the method is documented. and test classes using the BlueJ environment. Ensure all your work is documented. Background: The textbook speaks about the use of computers in numerical computation. Due date: TBA 396 . This will input a/b and return b/a. Implement and test an inverse operation for RationalNumbers. Ensure the method is documented. Ensure the methods are documented. you will complete the RationalNumber and ComplexNumber classes. multiplication. plus software to test them. Procedure: The textbook implementation of RationalNumber omits the implementation of subtraction. expressed as a double. create. Modify your RationalNumber class so that it uses BigIntegers.

create.Lab Assignment 7 . e = 1/0! + 1/1! + 1/2! + 1/3! + 1/4! + … How well does this approximation work? That is. Hand-in: 397 . π/4 = 1 .wolfram. Note that (2n)! increases very rapidly. How well does this approximation work? That is. Prove that statement is true.1/7 + 1/9 . π has an infinite decimal expansion. Background: Use the mathematical functions in the textbook and those you created in the previous assignment to answer the following questions. so you may wish to rethink the data types in the factorial methods. Procedure: What is the ratio of Fib(n+1)/Fib(n) as n increases? If you have m presents and n people.html introduces Catalan numbers and gives several formulas used to calculate these numbers. One approximation to e is given by the following formula..Mathematics II Objectives: To design. and test classes using the BlueJ environment.com/CatalanNumber. Then develop mathematical methods for the Catalan numbers. Develop a Catalan class which calculates these numbers using the formulas numbered (2) and (3). how many terms in the series do you need to have three digits after the decimal point correct? Do you need five digits? Do you need 10 digits? The last sentence of chapter 10 implies there is no largest integer.. how many ways are there to divide the presents amongst the people. One approximation to π is given by the following formula. perhaps with some people getting 0 presents? Hint: use the choose function. how many terms in the series do you need to have three digits after the decimal point correct? Five digits? 10 digits? The constant e also has an infinite decimal expansion. http://mathworld.1/3 + 1/5 .

Due date: TBA 398 .

The first is straight-forward UNIX environment where they use emacs as the editor. I have not included them here. and compile either from within it or from the command line.Subsequent lab assignments Students will not be working within the BlueJ environment all the time. Thus it is important they see other environments. Since these labs are quite institution-dependent. We had two available for them. The second environment uses Eclipse. 399 .

400 .

248. vi. 385. 93. 310. 150 assignment. 155. 226. 71. 331 assertEquals. 88. 217. 301. ii. 299. 382. 291. 152. 344. 394. 392 addActionListener. 155. 3. 185. 105. 371. 365. 275 Afghanistan. 215. vii. ii. 256. 401 . 254. 374. 168. 77. 225. 38. 287. 247. 75. 253. 237. 320. 372 ActionListener. 315. 43. 104. 52. 320. 210. 345 BigInteger. 289 BindingFactory. 269. 379. x. 234. 345. viii. 14. 42. 304. 288 Address. 255. 211 Bangladesh. 198. 367 Binding. 254. 331 algorithm. 294. 341 Add. 37. 266. 292 abstraction. 353. 4. 21. 300. 92. 217. 323 architecture. 331 aggregation. 258. 110. 7. 212. 109. 355. 372 ad hoc. 156 addBinding. 233. 140. 95. 95. 92. 108. 321. 50. 139 accessibility. 221. 364. 254. 204. 91. 314 BadHourException. 150. 221. 65. 55. 287. 136. 140. 98. 265. iii. 253. 119. 258. 152. 41. 293. 169. 153. 210. 331. 319. 129 Applet. 227. 303 Ackermann. 363. 282. 321 ArrayList. 54. 389 Aruba. 71. 29. 74. 269 Australia. 52 assertSame. 150. 343. 282. 259. 261. 343. 120. 373. 319. 77. 317 AbstractButton. vii. 361. 166. 245. xi. 218. 101. 366. 227. 257. 39. 324 AppletViewer. 46. 75. 266. 295. 25. 220. 322 Abstract Window Toolkit. 360 ALPHABETIC_ORDER. 67. 347 abstract. 184 Albania. 91. 160. 220. 283. 141. 161. 312. 297. 40. 232. 292. 67. iv. 219. 292 ActionEvent. 139. 328. 10. 266 addBindings. 46. 331 bank account. 339. 49. 338. 187. 48. 202. 381. 55. 265. 2. 251. 396. 283. 101. 294. 362. 388. 28. 227 Avogadro. 259. 52. 282. 260. 62. 125. 267. 236. 351. 323. 313. 141 BigDecimal. 292. 86. 265. 386. x. 92.뫰327. 248. 80. ix. 257. 126. 317. 261. 190. 397 Assist. 314. 88. 105. 271 autounboxing. 52. 79. 347. 219. 203. 85. 250. 98. 367 ActionCommand. 184. 156. 235. 348. 47. 210. 274. 149. 391 association. 105 Adapter. 211 BadMinuteException. 72. 304. 126. 243. 197. 267. 372 Apple. 18. 251. 371. 322. 317. 52 assertTrue. 321. 344. 323. 262. 331 African Union. 394 autoboxing. 163. 345. 143. 318. 104. 388. 7. 90. 84. 150. 29. 315. 389. 267. 230. 236 assertNotNull. 312. 83. 182. 275. 380. 334 ArrayIndexOutOfBoundsException. 185. 84. 382. 366. 354. 221. 371. 333. 123. 365. 114. 73. 211 assertNull. 13. 252. 261. 372 addAll. 311. 219. 371. 171. 393. 199. 74. 151. 258. 89. 338 BlueJ. 294. 26. 10. 324. 51. 117. 353 AWT. 158 anonymous class. ii. 268. 260. 74. 377 base class. 304. 187. 88. 87. 124.Index abs. 255.

202. 39. 325. 37. 314. 163. 214. 223. 383. 274. 11. 282 constructor. 385. 364 Builder. 107. 228. 158. 384. 206 Canada. 122. 23. 88. 129 boolean. 282. 66. 78. 232. 226. iii. 105. 178. 386 class diagram. 397. 295 content pane. 208. 24. 148. 394. 268. 168. 40. 147. 182. 151. 339. 84. 276. 182. vi. iv. 147. 148. 399 Comparable. 210. 373. 351 Composite. 126. 90. 217. 116. 159. 72. 66. 282 BorderFactory. 396. 206. 48. 341 collection. 265. 212 Close. 272. 109. 38. 341 bundle. 52. 250. 166. 236. 157. 242. 257. 30. 399 Boole. 307. 159. 292. 336. 148. 349. 145. 321. 184 concrete. 120. 137. 237. 227. 184. 88. 13. 379. 389 Color. 98. 341 Character. 169. 323 Complex number. 72. 353. 105. 270. 167. 306 Burkina Faso. 387 BufferedOutputStream. 158. 67. 156. 173. 310 Compile. 152. 142. 239. 184. 268. 337 Class. 202. 71. 127. 348. 78. 290. 189. 308. 123. 123. 59. 26. 233. 207. x. 171. 284. 185. 106. vi. 300. 176. 341 command line. 63.383. 26. 248. 234. 88. 51. 281. 289. 171. 250. 299. 249. 36. 68. 127. 2. 129. 143. 42. 387. 166. 2. 287. 180. 331 ButtonGroup. 277. 17. 243. 153. 100. 42. 268. 205. 64. 70. 254. 77. 98. 263. 150. 67. 65. 387 Chain of Responsibility. 93. 117. 134. 153. 62. 312. 169. 149. 263. 113. 287. 156. 19. 41. 157. 133. 312. 61. 86. 345 Command. 180. 84. 152. 365 Border. 151. 388. 54. 268. 353. 195. 293 Calendar. 40. 145. 104. 191. 72. 338 BorderLayout. 258. 292. 281. 140. 178 402 . 389. 168. 184. 128. 126. 134. 218. 323. 196. 123. 234. 19. 155. 386. 75. 280. 297 Checkstyle. 211. 38. 29. 281 BoxLayout. 205. 158. 322. 235. 160. 92. 279 Box. 166. 108. 220. 169. 121. 237. 319. 18. 330. 286. 27. 118. 5. 374. 170. 223. viii. 68. 65. 146. 306. 100. 281 Braces. 127. 130. iv. 49. 98. 347. 29. 154. 98. 187. 346. 259. 60. 62. 287 checkbox. 103. 336 CloneNotSupportedException. 161. 178 call stack. 335 Comparator. 379 Code Pad. 73. ix. 383. 283. 132. 72. 3. 356. 1. 363. 381. 280. 308. 149. 233. 288. 316. 129. i. 121. 210. 306. 219. 397 constraint. 293 Cloneable. 98. 164. 182. 198. 13. 261. 341 composition. 135. 306. 86. 109. 149. 150. 147. 154. 175 constant. 204. 199. 71. 383. 181. 173. 66. 54. 70. 150. 199 charAt. 261 controller. 262. 62. 282. 65. 159. 80. 130. 156. 2. 315. 208. 139. 384 ClassNotFoundException. 339 coupling. 45 Code. 323. 167. 102. 280. 132. 55. 163. 238. 74. 345. 199. 91. 84. 195. 124. 279. iii. 55. 56. 99. 163. 218. 130. 43. 168. 209. 276. 77. 301. iv. 65. 220. 233 clearSelection. 152. 252. 201. 185 compare. 27. 185. 47. 40. 65 Bridge. 100. 77. x. 42. 28. 67. 129. 318. 226. 258. 88 Cohesion. 176. 166. 41. 91. 260. 123. 96. 34. 175. 91. 224. 141 condition. 222. 391. 59. 169. 191. 114. 183. 167. 115. 393. 143. 363 container. 136. 259. 70. 341 British Columbia. 125. v. 265.

48. 139. 36. 236. 256. 65. 116. 382. 172. 48. 345. 323. 87. 328 Finally. 315. 362. 325. 240. 236. 56. 244. 266. 267. 40. 271. 226. 177. 314. 290. 113. 2. 162. 207. 281. 316. 27. 384. 204. 319. 250. 215. 239. 336. 339. 292. 205. 244. 59. 341. 88. 236. 33. 140. 190. 275. 29. 193. 220. 286. 154. 30. 300. 210. 128. x. 110 deriveFont. 77. 196. 280 currentThread. 4. 224. 280. 372. 315. 245. 67. 55. 44. 396. 46. 364 fillRect. 261. 43. 364. 255. 233. 282. 384 CPU. 209. 341. 347. 338. 70. 42. 52. 225 destroy. 178. 367 Edge. 362. 115. 117. 152. 36. 362. 282. 370. 47. 153. 265. 381. 233. 217. 111. 140. 191. 215. 141. 205. 55. 351. 372. 183. 358. 125. 355. 371. x. 362. 233. 70. 128. 314. 146. 101. 367. 232. 187. 187. 344. 219. 222. 366. 41 Create Test Class. 213. 11. 217. 84. 1. 322. 109. 267. 17. 228. 208. 76. 117. 239. 330. 223. 79. 271. 27. 331. 161. 235. 349. 107. 256. 385 debt. 187 Formula. 247. 207. 365. 366 Date. 143. 79. 224. 47 createVerticalBox. 362. 210. 208. 185. 145. 38. 176. 344. 219. 139. 302. 170. 283 Efficient. 190. 317. 304. 97. 141. 339. 134. 189. 19. 80. 275. 308. 356. 31. 103. 354 event. 114. 109. 11. 295. 349. 26. 166. 300. 239. 60 Fibonacci. 75. 111. 363. 271. 356. 139. 345 decimal. 220. 266. 62. 28. 226. 388. 20. 102. 136. 194. 282. 310. 211. 172. 230. 278. 180. 230 derived class. 235. 371. 144. 394 for-each. 322 deserialize. 126. 280. 174. x. 14. 113. 33. 343. 116. 266. 289. 203. 389. 377. 173. 165. 217. 117 Direction. 318. 319 dialog. 31. 263. 368 File. 150. 2. 370 Exception. 175. 163. 217. 74. 234. 147. 122. 218. 301. 335. 245. 142. 353. 32. 227. 193. 341. 87. 21. 236. 344. 306. 385. 365 Explore. 140. ix. 228. 245. 369. 345. 137. 91. 322 For. 36. 269 dictionary. 396 drawPolygon. 305. 147. 158. 263. 330. 217. 279. 220. 368 Factory. 353. 274. 173. 33. 341 Department. 193. 205. 322. 397 DecimalFormat. 201. 280. 219. 125. 7. 207. 13. 99. 116. 131. 363 Firefox. 190. 254. 338. 282. 103. 114. 14. 142. 226. 99 Deakin. 115. 211 datatype. 338. 306 FileInputStream. 291. 51. 9. 105. 10. 158. 205. 114. 365 FileOutputStream. 228. 168. 233. 145. 341 Font. 382 DataFormatException. 20. 194. 250. 144. 357. 1 Euclid. 62. 345. iv. 382 FlowLayout. 84. 224. 265. 23. 10. 283 double. 140. ii. 250. 296. 239 database. 330. 55. 220. 231. 125. 4. 84. 3. 164. 260. 214. 42. 294. 152. 192. 259. 345 dynamic programming. 116. 98. 146. 141. 293 Flyweight. 370. 133. 77. 214. 254. 297. 44. 95. 336. 347. 367. 363. 273. 193 Decorator. 258. 369. 61. 318. 264. 315. 162. 292. 283. 339. x. 232. 202. 360 Frame. 264. 249. 252. 140. 277. 345 False. 54. 343. 118.course. 388 EventQueue. 365 FileNotFoundException. 78. 86. 329. 101. 166. 294 403 . 358. 319. 234. 291. 328 drawString. 184. 52. 26. 160. 235.

319. 89. i. 304. 102. 389 Interface. 123. 360. 1. 172. 317. 199 isSelected. 275. 42. 253 increment. 117 GUI. 358.MAXIMIZED_BOTH. 99. 369 GB. 145. 133. 355. 103. 373 Hardware. 164 Import. 223. 236. 77. 344. 123. 126. 213. i. 318. 249. 101. 63. 320 Java. 83. 315. 272. 200. 226. ix. 297 GridLayout. 29. 321 Interpreter. 219. 44. 250. 300. 173. 389 HashSet. 299. 50. 353. 124. 325 i18n. 362. 130. 311. 11. vii. 44. 145. 371 Goal. 2. iii. 16. 223. 23. 321. 10 GCD. 193. 376 InputVerifier. 380 Internet Explorer. 128. 228 Integer. 317. 245. 363. iii. 291. 370. 306 garbage collection. 30. 316. 321. ii. 328. 322 getInstance. 251. 237 hasNext. 314. 273. 226. 341 Inheritance. 250 Guava. 247. 370 IOException. 32. 328 greater than. 324. 101 Instance. 363 invokeLater. 354. 333. 290. x. 72. ix. 371. 218. 308 Identity. 18. 223. 290. 130. 121. 317. 286 getModel. 359. 117. 119. 388. 141. 111. 220. 247. 277. 270. 227. 117. 129 Information Expert. 55. 174. 140. 135. 149 HTML. 264 France. 235. 203. 87. 303 getActionCommand. 62. 7. ix. 65. 356. 86. 13. 80. 35. 339. 314 getSource. 2. 291. 132. 98. 293. 175 Index. 355 GregorianCalendar. 187. 9. 388. vii. 401 Indirection. 13. 275. 271. ix. 40. 347. 292 getAppletInfo. 17. 148. 100. 27. 251. 111. 19. 122. 92. 6. iii. 234. 388. 341 intValue. xi. 274 GridBagLayout. 391 hexadecimal. 128. 169. 11. 327. 290. 37.Frame. 273. 192. 371. 103. 129. v. 404 . 33. 157. 292. 268. 168. i. 328 getRootPane. 65. 72. 132. 74. 365. 224. 292. 216. 141. 316. 26. 369. 126. 10 hashCode. 316. 248. 42. 272. 166. 225. 319. 341 JApplet. 301. 231. 166. 233. 320. 167. 118. iii. 296 Inspect. 239 getFont. 357. 156. 116. 222. 372. 134. 152. 164 instanceof. 276. ii. 391 Google. 69. 66. 137. 102. 3. 227. 322 Graphics. 131. 373. 266. 391. 20. 9. 59. 72. 151. 155. 319 getClassLoader. 364. 196. 63. 365 isLetter. 344 Generic. 117. v. 117. 128. 318. 55. 354. 120. 327 getParameterInfo. 393 GoalieStatistic. 120. 43. 317. 128. 26. 197. 291. 227. 25. 98. 108. 119. 235. 272. 305. 389. 229. 12. 129. 302. 208. 257. viii. 4. 207. 237. 292 getParameter. 207. 179. 97. 124 HashMap. 73 inner class. 248. 292 iterative. 197. 39. 41. 305. 169. 1. 251. 366. 16. 84. 120 getAccessibleContext. 302. 205. 168 greatest common divisor. 125. 131. 323. 193. 336. 315. 121. 15. 226. 129. 341 infinite loop. 158. 118. 201. 366. 271. 205. 382 Interpret. ix. 250. 271. 76. 314. 329. 368 Iterator. 103. 364. 289. 38. 252. 217. 123. 123. 391 Goalie. 131 help. 335. 292. 28.

187. 300. 341 Method. 377. 282. 290 JFormattedTextField. 275. 281 JMenu. 271. 136. 203. 379. 268. 267. 155. 277. 187. 308. 331 Model. 143. 330 JButton. 279. 56. 168. 143. 304. 118. 19 astIndexOf. 224. 345. 251. 207. 301 JMenuBar. 233. vi. 10 Mediator. 260. 260. 270. 29. 251. 166. 341. 302. 244. 2. 282. 294. 263. 394 java. 387. 192.lang. 295. 267. 300. 290. 219. 194. 390.event.security. 248. 148. 240. 217. 248. 248. 209. 286. 362 Libya. 141. 362 Math. 257. 295. 128. vii. 389. 371 JOptionPane. 164. 353. 102. 338. v. 344. 293. 147. 202. 324. 309. 150. v.Math. 299 League. 290. 372. 238. 185. 26. 296 JUnit. ix. 248. 266. 283 JList. 126.Entry. 248. 385. 277. 247. 280. 161. 193. 300. 172 MVC. 385 multimap. 245. 265. 54.swing. 250. 80. 339. 243. 252. 249. 289. 355 Monash. 343. 317. 255. 257. 287. 275. 286. 330 Loop. 205. 369. 239. 258. 336 Marker. 237 JavaHelp. 341. 243. 331. 382. 305 javax. 267. 299. x. 248. 98. 262. 218. 258. 303 JTextField. 257. 281. 17. 345. 197 layout manager. 261. 177 java. iv. 222. 360. 103. 237. 176. 143. 208. 265. 318. 249. 121.io. 202. 250. 284. 248. v. 72. 253. 329. 243 Mark. 280. 248. 295. 148. 364. 347 Math. 63.pow. 326. 293 JRadioButton. 175. 293 JCheckBox. 344 Micronesia. 254. 282. 70. 171. 350. 381 modulus. 230. 349 java. 210. 370 JLabel. 281. 375. 222 java. 288 JComponent. 268. 341 Meeting. 273. 221. 387. 243 Klingon. 358 MB. 158. 279. 264. 311. 322. 281. 299. 167. 119. 349. 224. 301 JMenuItem. 383. 190. 373. 256. 227. 131. 230 java. 101. 253. 263. 225. 307 Long. 260. 136. 115. 259. 51. 242. 279. 145. 241. 261. 268. 250. 46. 255. 358. 337. 347. 52. 274. 277. 335. 280. 391. 50. x. 374. 245. 302. 280. 297 JFrame. 129 Map. 314. 329. 189. 180. 249. 117. 170. 252. 380. x. 274. 275. 307. 71. 249. 336 Math.text. 67. 364 ListSelectionModel. 331 List. 4. 305. 295. 296 Memento. 164. 344. 340 405 . 70.bean. 259. 117 mutable. 230. 299. 371 JPanel. 142. 167. 23. 340 Modelling. 270. 237. 248. 300. 280 Locale.232. 339. 211. 334. 254. 344. vii. 221. 3. 184. 366 Map. 104. 209. 191. 289. 294.awt. 117. 366 JavaBean. 169. 141. 259. 243. 270. 13. 248. 307. 362 mathematics. 149. 253.abs. 291 JSeparator. 274. 330. 300. 152. 300 java. 288. 179. 297. 248. 264. 165. viii. vi. 166. 388. 1. 233. 283. 182. 66.util. 304. 364 java. 272. 380 Kent. 272. 392 less than. 163. 248. 265. 280. 181. 386. 384. 345. 239. 256. 277. 70. 254. 287. 59. 385 key-value. 232. 335. 270. 248. 242. viii. 267. 194. 277. 278. 344. 337. 272.

331. 119. 83. 341 postcondition. 102. 71. 113. 125. 76. 116 NumberFormat. 40. 302. 104. 217. 344. 243. 336 protected. 99. 199. 88. 132. 254. 34. 196. 307. 243 Observer. 211. 243. 16. 118. 226. 11. 102. 362. 122. 379 Object Bench. 134. 226. 217. 30. 48. 106. 214. 236. 159 Object. 268. 236. vi. 252. 186. 107. 107. 318. 237. 230. 363. 105. 44. 145. 123. 222. 294. 354. 9. 217. 100. 243. 153. 388. 301. x. 345. 10. 258. 154. 227. 267. 172. 154. 130. 101. 215. 165. 232. 333. 126. 210. 85. 154. iv. 126. 90. ix. 244. 222. 40. 226. 196. 141 numerator. iii. 120. 292. 45. 51. 316. 262. 146. 284. 199 paradigm. 22. 294. 105. 133. 37. 240. 141. 263. 92. 304. 24. 235. 91. 243 ObjectOutputStream. 270. 111. 215. 316. 406 . 170. 384 println. 86. iii. 145. 349. 220. 146. 235. 89. 203. 208. 31. 37. 329. 206. 339. 324. 106. 224. 183. xi. 127. 107. 210. 387. 109. 392. 238. 126. 115. vi. 98. 133. 43. 43. vi. 89. 220. 86. 185. 347. 33. 222. 26. 296 Planck. 186. 263. 118. 104. 32. 152. 78. 148. 130. 42. 158. 134. 131. 191. 2. 289. 225. 108. 141. 66. 366 Polymorphism. 234. 156. 91. 223. 225. 290. 109. 232. 95. 307 New Zealand. 122. 126. 190. 107. 102. 105. 235. 169. 97. 121. 347. 105. 75. 27. 356. 275. 215. 167. 197. 333. 12. 150. 108. 24. 26. 31. 50. 217. 157. 168. 256. 125. 239. 226. 28. 192. 218. 362 print. 124. 257. 121. 7. 321. 101. 391. 144. x. 132. 221. 59. 249. 341. 366 professor. 33. 348. 394 normalization. 50. 314. 212. 77. 305. 179. 123. 84. 337. 111. 127. 272. 155. 19. 88. 101. 133. 198. 230. 122. 68. 224. 166. 1. 341 Olympic Movement. 389. 116. 238 Prototype. 28. 223. iv. 30. 132. 252. 388 persistence. 353 player. 291 parenthesis. 315. 150. 106. 151. 346. 341 Proxy. 251. 72. 143. 356. 225. 363 ObjectInputStream.MyDate. 232. 357. 102. 221. 103. 237. 71. 122. 287. 227. 308. 308. 330. 161. 167. 141. 77. 4. 55. 109 pattern. 67. 239. 311. 341 public. 85. 270. 159. 257. iii. 193. 174. 210. 153. 222. 384 package. 370. 13. 344 Paint. 142. 198. 364. 216. 147. 231. 123. 227. 62. 196. 42. 382. 202. 212. 149. 217. 32. 300. 89. 49. 143. 121. 140. 119. 95. 233. 107. 7. 50. 206. 22. 334. 108. 48. 32. 209. 320. 335. 303. 18 Point. 209. 348. 343. 75. 254. 300. 174. 155. 133. 159. 97. 354. 393 PMD. 71. 90. 377 penalty. 91. 219. 327. 234. 51. 20. 41. 152. 124. 30. 274. 77. 123. 184. 345. 268. 167. 374 private. 14. 361 parentheses. 314. 390 person. 102. 346. 2. 228. 127. 224. 218. 217. 33. 264. 334. 219. 213. 71. 337. 122. 166. 336. 129. 156. 126. 224. 40. 315 palindrome. 31. 237. x. 149 precondition. 349 NUMERIC_ORDER. 64. 271. 248. 131. 220. 17. 149 primitive. 306. 301. 223. 376 native2ascii. 15 parameter. 63. 328. 219. 346. 222. 220. 279. 156. 340. 34. 106. 300. 347. 128. 226. 3. 327. 219. 108. 164. 331 Open. 242. 51. 148. 62. 136. 200. 101. 338.

237. 279. 142. 341 String. 239 setPreferredSize. 159. 235. 77. 141. 10. 293 setMinimumSize. 319. 361 Refactoring. 190. 71. iv. 197 RelativeConstraints. 178. 210. 87. 222. 266. 255. 78. 217. 242. 295 Serializable. x. vi. 295. 158. 260. 180. 301 setPersistenceDelegate. 301. 216 rational number. 339. 27. 90. 142. 371. 125. 118. 86. 290. 262. 272. vi. 183. 139. 78. 250. 267. 281. 163. 274. 181. 308 Retirement. 130. 174. 283 State. 407 . 85. 257. 219. 33. 169. 307. 370. 132. 193 Start. 144. 288 RelativeLayout. 228. 294. 101. v. 302. 363. 211. 187. 170. 239 setDisplayedMnemonic. 236. 291. 251. 283. 10 RSA. 187. 10. 187. 235. 225. 232. 365 Recursion. 348. 341. 156. 265. 106. 15. 269. 180. 146. 144. 360. 282. 152. 131. 253. 380 Replace. 63. vi. 3. 294. 34. 294. 296 setVisible. 51. 303 setBorder. 272. 184. 156. 7. 284. 152. x. xi. 200. 50. 290. 268. 227. 370 showMessageDialog. 238. 293. 374 Section. 53 Software. 371 Sighting. 254. 155. 178. 166. 238. 233. 240. 254. 167. 232. iv. 92. 157. 279. 293 setCharAt. 218. 121. 224. 131. 146. 243. 153 ROM. 236. 26. 83. 170. 302 setMnemonic. 336. 373 Reference. 239. 273. 124. v. 231. 183. 185. 243. 322. 153. 226. iv. vii. 84 Risks. 109. 292 setVerifyInputWhenFocusTarget. 151. vi. 282. 335. 198. 226. 254. 284. 272. 266. 125. 235. 287. 322 setInputVerifier. 44. 88. 304. 24. 371. 196. 224. 168. 360. 279. 259. 341 Statement. 20. 209. 206. 228. 32. 252. 221. 227. 40. 168 RAM. 264 setExtendedState. 28. iii. 256. 223. 230. 191. 370 Scalable Vector Graphics. 343 Runnable. 172. 164. 376 Security. 119. 256. 334. 377 Smalltalk. 158. 379 Spring. 343. 282. 194. 318. 269 resource bundle. 368 Recursive. 55. 369. 345 setContextClassLoader. 158. 158. 271. 166. 256. 163. xi. 148. 31. 72. 280. 199. 361. 223. 339 Smoke testing. 66. 372. 277. 261. 156. 202. 83 Strategy. 155. 270. 291 setLabelFor. 274. 218. 270. 182. 346. 129. 242. 169. x. 287. 28. 223. 107 Return. 133. viii. 374 question mark. 336 Set. 196. 369. 64. 282. 197. 187. 157. 164. ii. 227. 349 Reading. 111. 239. 181 setColor. 178. 303. 75. 265. 145. 221. 271. 37. 104. 136. 379 regular expression. 264 setFont. 157. 339 ResourceBundle. 225. 208. 271. 373. 245 Scanner. 117. 74. 338. 292 setText. 195. 239. 226. 29.359. 19. 302. 315. 380 setAccessibleDescription. 203. 269. 89. 98 readObject. 179. 76. 289. xi. 262. 372. 201. 330. 324. 357. 345. 370 setSelected. 189. 38. 370. 30. 293. 143. 237. 62. 281. 239 Stop. 245 Singleton. 242. 160. i. 84. 258. 347. 335. 220. 102. 257. 115. 335. 333. 267. 264 setLayout. 133. 296.

253. 224. 408 . 76. 136. 71. 86. 22. 167. 100. 175. 49. 106. 55. 219. 224. 66. 109. 191. 79. 37. 89. 78. 140. 47. 153. 99. 87. 261 Ukraine. 19. 95. 275. 235. 179. 41. 145. 226. 389. 33. 248. 165. 77. 370. 181. 43. 20. 327. 22. 61. 23. 116. 119. 236. 17. 196. 54. 175. 317. 237. 224. 221. 104. 236. 36. 196. 374 Tacoma Narrows Bridge. 42. 111. 31. 187. 64. 36. 156. 100. 127. v. 237. 101. 331. 56. 177. 308. 226. 226. 263. 13. 17. 320. 242. 15. 292. 240. 381. 299. 75. 152. 171. 307 value. 232. 18. 28. 103. 239. 225. 155. 371. 245 Swing. 380 understanding. 23. 124. 347. 105. 31. 282. 304. 105. 224. 233. 196. 201 superscript. 373 transaction. 200. 243. 100. 26. 92. 219. 337. 39. 116. 126. 240 System. 117. 155. 53. 159. 37. 122. 43. 94. 19. 185. 108. 347. 349. iv. 23. 185. 307. ii. 274. 33. 46. 169. 83. 25. 192. 277. 247. v. 117. 172. 55. 225. 153. 33. 115. 55. 73. 190. 180. 220. 35. 91. 168. 26. 54. 369 TIME_ORDER. 161. 28. 236. 203. 22. 37. 150. 223. 329. 169. 187 StringBuilder. 50. 64. 55 SVG. 78. 139. 236. 347. 222. 158. 226. 390. 218. 109. 77. 34. 237. 173. v. 172. 200. 88. 102. 43. 204 transient. 158. vi. 227. 154. 239. 233. 32. 189. 183. 27. 25. 1. 304. 104. 373. 96. 142. 129. 380.exit. 29. 335. iii. 43. 167. 90. 291. 200 typeface. 91. 275. 235. 145. 46. 191. 294. 235. i. 53.307. 150. 62. 259. 84. 54. 76. 219. 211. 185. 306 System. 102. 155. 128.뫰194. 227. 48. 209. 134. 93. 78. 88. 122. 65. 102. 63. 219 Thread. ii. 370. 173. 228. 3. 190. 123. 297 transcript. 245 subscribe. 182. 36. 224. 147. 79. 233. 217 Uses. 202. 197. 88. 56. 365. 31. 151. 320. 56. 126. 57. 284. vi. 337 substring. 126. 169. 101. 183. 134. 24. 182. 334 Terminal. 49. 48. 198. 46. 224. 90. 271. 93. 37. 63. 390 United Arab Emirates. 256. 104. 148. 87. 236. 103. v. 148 URL. 153. 155. 219. 199. 51. 32. 294. 303. 219. 88. 245. 316. 179. 391. 374 System. 223. 105. 237. 319. 379. 345. 150. 233. 155. 90. 191. 240. 354. 176. 247. 30. i. 101. 346. 187. 235. 347. 26. 240. 232. 226. 379 Switzerland. 152. 141. 236. xi. 220. 51. 191. 275. 32. 129. 21. 236. 155. 256. 63. 52. 373. 88. 18. 220. 189. 153. 72. 372. 221. 48. 134. 27. 394 unit test. 135. 243. 235. 59. 53. 393 template. 184. 147. 260. 353 Unicode. 223. 54 Team. 263. 107. 72. 272. 108.err. 20. 225. 372 System. 232. 187 Student. 88. 166. 66. 319. 121. 333. 163. 56. 95. 331 United Kingdom. 331 UML. 74. 133. 50. 172 Try. 329 True. 392. 157. 100. 60. 321. 237 toString. 75. 369. 157. 223. 201. 92. 127. 93. 92. 50. 126.out. 331. 92. 42. 67. 164. 394 United States. 336. 369. 220. 159. 83. 89. 195. 224 TreeSet. 31. 49. 231. 374. 59. 79. 280. 232. 185. 243. 209. 373 Style. 221. 172. 160. 131. 125. 67. 370. 328. 103. 300. 184. 208. ii. 55. 182. 7. 49. 47. 52. 268. 327. 322. 196. vi. 29. 354 UTF-8. 269. 107. 75. 81. 349. 40. 139. 345. 182. 371. 44. 70. 387 Uppercase. 238. 225. 274. 389 StringBuffer. 237 trigonometry. 210. 140. 55. 134. 233. 146. 145. 126. 62. 235. 203. 117. 156. 199. 114.

339. 345. 233. 237. vi. 72. 42 Visitor. 243. 87. 174. 296 View. 384 virtual machine. 362. 248 Wikipedia. 193. 88. 232. 234. 273. 245. 356. 220. 334. 358. 228. 364. 218. 238. 242. 187. 218. 291. 289. 236. 239. 198. 239. 221. 250. 223. 94. 232. 233. 240. 388. 248. 358. 364 XML. vi. 271. 325. vi. 155. 233. 236. 242. 369. 272. 199. 364 409 . 349. 374 valueOf. 244. 198. 341 While. 283 verify. 54. 239. 224. 373. 236. 290. 95. 236. 234. 365. 129. 235. vi. 46. 220. 222. 359. 270. 355. 338. 243. 232. 11. 366. 231. 345. 337. 380 writeObject. 243. 240. 231. 41. 50. 364 XMLDecoder. 117. 394 Widget. 363. 104.344. 345 Vector. 153. 242. 237. 172. 323. 234. 126. 115. 249. 7. 105. 354. 25. 279. 233. 364. 237. 365 XMLEncoder. 225. 235. 120. 371. 240. 243. 232. 251. 247. 219. 270.

410 .