MVC$COMP$401$Spring$2013$Lecture$23$4/11/2013$Classic$MVC$2$h<p://www.oracle.com/technetwork/arCcles/javase/mvcF136693.html$Alternate$MVC$3$h<p://www.oracle.com/technetwork/arCcles/javase/mvcF136693.html$MVC$Calculator$Design$Start$with$the$model.$What$does$the$model$need$to$encapsulate?$lec23.v1$• CalculatorModel$– Encapsulates$a$history$(i.e.,$a$sequence)$of$operaCons.$– A$current$value$on$which$the$next$operaCon$will$occur.$– Observable$• NoCfies$observers$when$model$changes$which$in$this$case$is$whenever$a$new$operaCon$occurs.$• OperaCon$– Specifies$an$operaCon$• NoCce$it$doesn’t$specify$the$value$that$the$operaCon$applied$to$or$the$result.$– Why$doesn’t$that$ma<er?$MVC$Calculator$Design$• Now$design$the$view$• lec23.v2$Controller$• Controller$sits$between$model$and$view$– Responds$to$what$happens$in$the$view$• In$our$case:$bu<on$pushes$– Instructs$view$to$change$when$necessary$• In$our$case:$what$is$in$the$display,$what$is$on$the$tape$– Manipulates$the$model$• Registers$operaCons$to$affect$the$value$– Responds$to$model$changes$• Causes$registered$operaCons$to$appear$on$the$tape$Controller$$• We$need$a$way$for$controller$to$register$itself$with$all$of$the$view’s$bu<ons.$– lec23.v3$– NoCce$that$controller$encapsulates$references$to$model$and$view.$• Model$and$view,$however,$don’t$know$about$each$other$or$the$controller.$Handling$Digits$• What$should$happen$when$a$digit$is$pressed?$– Depends$on$what$has$happened$before.$• If$we$are$starCng$a$new$number,$we$should$replace$the$display$with$this$digit.$• If$we$have$already$started$a$number,$we$should$append$the$digit$to$the$number$already$in$the$display.$– Keeping$track$of$this$kind$of$logic$and$doing$the$right$this$is$exactly$the$job$of$the$controller.$• Things$we$need$to$add:$– A$way$for$the$controller$to$get/set$the$display$– A$field$in$controller$to$keep$track$of$whether$we$are$starCng$a$new$number$or$not$and$corresponding$logic$– lec23.v4$Handling$Decimal$Point$• Should$only$allow$one$decimal$point$so $needs$to$check$to$see$if$one$is$already$there.$• Special$case$for$beginning$of$number$• What$we$need:$– Indicator$of$whether$or$not$decimal$point$has$already$been$pressed.$– Logic$to$handle$the$bu<on$– lec23.v5$Handling$OperaCons$• What$happens$when$an$operator$is$pressed?$– The$operator$indicates$which$operaCon$is$now$in$progress.$• But$we$can’t$actually$do$the$operaCon$unCl$another$number$is$entered.$• If$an$operaCon$was$already$in$progress,$that$operaCon$should$now$complete$using$number$in$the$display$• Things$we$need$to$add:$– Indicator$of$which$operaCon$is$in$progress.$– lec23.v6$Seeing$the$Output$• Controller$now$handling$most$bu<ons$and$sending$operaCons$to$model$– Need$to$react$to$changes$in$the$model$• What$we$need:$– Implement$observer$– A<ach$to$model$– Handle$observed$operaCons$– lec23.v7$Four$Bugs$and$An$Inversion$• Delay$in$seeing$result$when$pressing$=$– No$need$to$wait$for$next$number$when$=$is$current$operaCon$• Tape$doesn’t$scroll$– Just$need$to$put$it$in$a$ScrollPane$• Can’t$change$mind$about$operaCon$– Shouldn’t$do$operaCon$if$at$start$of$number$• Can’t$make$a$zero$– Logic$for$starCng$a$number$incorrect$– Need$to$separate$case$of$starCng$a$number$from$the$case$that$the$number$started$is$zero$• SCll$need$to$handle$+/F$– Interacts$with$number$is$zero$– Need$to$watch$out$for$fact$that$first$character$of$this$bu<on$is$same$as$addiCon$operaCon.$• lec23.v8$Reconsidering$Design$• Things$work$(for$the$most$part)$• But$something$is$wrong$with$our$design…$– …$think$about$what$we$would$need$to$do$in$order$to$support$keyboard$numbers.$– …$think$about$what$we$would$need$to$do$in$order$to$support$bu<ons$with$imageFbased$icons$• Current$interacCon$between$controller$and$view$requires$controller$to$know$about$view$internals.$– Instead$of$exposing$raw$underlying$UI$events,$we$should$translate$them$into$something$more$abstracConFspecific.$– lec23.v9$• And$now$we$can$add$keyboard$input$–
View Full Document