gof/Visitor/visitor/scala/Visitor.scala

  1: //..+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8
  2: /*
  3:  * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
  4:  */ 
  5: package components
  6: 
  7: import java.awt.Dimension
  8: import javax.swing.Box
  9: import swing._
 10: import swing.event._
 11: 
 12: // ----------------------------------------
 13: object VacationDisplay {
 14:   val version =          VacationDisplay
 15:     .getClass.getName+": #1.0.38"
 16: }
 17: 
 18: // ---------------------------------------- Visitor::ObjectStructure
 19: class VacationDisplay(val frame: Frame) extends GridPanel(1,2) {
 20: 
 21:   val employees = Array(
 22:       new Employee("Susan Bear",    55000, 12, 1), 
 23:       new Employee("Adam Gehr",    150000,  9, 0), 
 24:       new Employee("Fred Harris",   50000, 15, 2), 
 25:       new Employee("David Oakley",  57000, 12, 2), 
 26:       new Employee("Larry Thomas", 100000, 20, 6), 
 27:       new Boss("Leslie Susi",      175000, 16, 4, 12),
 28:       new Boss("Laurence Byerly",   35000, 17, 6, 17))
 29: 
 30:   val items = (for (e <- employees)
 31:     yield { e.name }).toArray
 32:   new ListView(items) {
 33:     contents += this
 34:   }
 35: 
 36:   // ----------------------------------------
 37:   val total = new TextField(
 38:     5) {
 39:     horizontalAlignment = Alignment.Center
 40:   }      
 41:   val bonus_total = new TextField(
 42:     5) {
 43:     horizontalAlignment = Alignment.Center
 44:   }      
 45:   def display: VacationDisplay = this
 46:   val vacation = new CommandButton(
 47:     "Vacations") {
 48:     command = new VacationCommand(display)
 49:   }
 50: 
 51:   contents += new BoxPanel(Orientation.Vertical) {
 52:     contents += total
 53:     peer.add(Box.createVerticalStrut(10))
 54:     contents += bonus_total
 55:     peer.add(Box.createVerticalStrut(10))
 56:     contents += vacation
 57:     peer.add(Box.createVerticalStrut(50))
 58:   }
 59: 
 60:   // ----------------------------------------
 61:   frame.title = "Vacation Display"
 62:   frame.preferredSize = new Dimension(300, 200)
 63: }
 64: 
 65: // ---------------------------------------- Visitor::Element
 66: trait Element {
 67:   def accept(visitor: Visitor)
 68: }
 69: 
 70: // ---------------------------------------- Visitor::ConcreteElement
 71: class Employee(
 72:   val name: String,
 73:   val salary: Float,
 74:   val vacDays: Int,
 75:   val sickDays: Int)
 76:   extends Element {
 77:   def accept(visitor: Visitor) = visitor. visit(this)
 78: }
 79: 
 80: // ---------------------------------------- Visitor::ConcreteElement
 81: class Boss(
 82:   override val name: String,
 83:   override val salary: Float,
 84:   override val vacDays: Int,
 85:   override val sickDays: Int,
 86:   val bonusDays: Int)
 87:   extends Employee(name, salary, vacDays, sickDays) {
 88:   override def accept(visitor: Visitor) = visitor. visit(this)
 89: }
 90: 
 91: // ---------------------------------------- Visitor::Visitor
 92: trait Visitor {
 93:   var total_days = 0
 94:   def visit(e: Employee)
 95:   def visit(e: Boss)
 96: }
 97: 
 98: // ---------------------------------------- Visitor::ConcreteVisitor
 99: class VacationVisitor extends Visitor {
100:   def visit(e: Employee) {
101:     total_days += e.vacDays
102:   }
103:   def visit(e: Boss) {
104:     total_days += e.vacDays
105:   }
106: }
107: 
108: // ---------------------------------------- Visitor::ConcreteVisitor
109: class BVacationVisitor extends Visitor {
110:   def visit(e: Employee) {
111:     total_days += e.vacDays
112:   }
113:   def visit(e: Boss) {
114:     total_days += e.vacDays
115:     total_days += e.bonusDays
116:   }
117: }
118: 
119: // ---------------------------------------- Command::Invoker
120: trait CommandHolder extends Publisher {
121:   private var _command: Command = Command.NoCommand
122:   def command: Command = _command
123:   def command_=(a: Command) {
124:     _command = a
125:     command.listenTo(this)
126:   }
127: }
128: 
129: class CommandButton(override val text: String)
130:   extends Button(text)
131:   with CommandHolder
132: 
133: // ---------------------------------------- Command::Command
134: object Command {
135:   object NoCommand extends Command {
136:     reactions += {
137:       case ButtonClicked(source) =>
138:         println(":: ButtonClicked")
139:     }
140:   }
141: }
142: class Command extends Publisher
143: 
144: // ---------------------------------------- Command::ConcreteCommand
145: // ---------------------------------------- Command::Receiver
146: class VacationCommand(val panel: VacationDisplay)
147:   extends Command {
148:   reactions += {
149:     case ButtonClicked(source) =>
150:       val vac  = new VacationVisitor()
151:       val bvac = new BVacationVisitor()
152:       for (e <- panel.employees) {
153:         e.accept(vac)
154:         e.accept(bvac)
155:       }
156:       panel.total      .text = vac. total_days.toString
157:       panel.bonus_total.text = bvac.total_days.toString
158:   }
159: }
160: 
161: // ========================================