ラジオボタンに対応する庭園クラスがあるのですが、それぞれの庭園クラスの親クラスを実装し、イベントアクション内では親クラスを操作するという形になっています。Factoryクラスは直感的だから、そんなに説明も必要ないとは思いますが・・・・
このサンプルは、特に困ることもなく実装できました。 強いて言うと、GridBagPanelクラスの中で利用するConstraintsオブジェクトをどうやって生成するのだろう?というところで、少しつまづいたぐらいでした。 結局GridBagPanelクラスの中のpairConstraintsメソッドから生成する方法ぐらいしかわかりませんでした。 まあ、こちらのメソッドの利用方法はAPIドキュメントをみればすぐわかると思うので、あえてここでは何も書きません。
本サンプルのソースはこちら
import java.awt.Color import scala.swing._ import scala.swing.event._ /** * メインオブジェクト */ object Gardener extends SimpleSwingApplication { def top = new MainFrame { title = "AbstractFactory Sample" var garden:Garden = new NoGarden val gardenPlot = new GardenPanel{background = Color.WHITE}; val buttonList = List("菜園", "一年草園", "多年草園"); // ButtonGroupの生成と設定 val group = new ButtonGroup buttonList.foreach(name => { val button = new RadioButton(name) group.buttons += button listenTo(button) }); contents = new GridPanel(1,2) { // 左パネルの生成 contents += new GridBagPanel { val constraints = pair2Constraints(0, 0) constraints.anchor = GridBagPanel.Anchor.FirstLineStart layout += new Label("庭園の種類") -> constraints; // ラジオボタンを配置する for (i <- 0 to (group.buttons.toList.length - 1)) { val constraints = pair2Constraints(0, (i + 1)); constraints.anchor = GridBagPanel.Anchor.FirstLineStart constraints.ipady = 70 layout += group.buttons.toList(i) -> constraints } } // 右パネルの生成 contents += new GridBagPanel { val constraints = pair2Constraints(0, 0); constraints.ipady = 210 constraints.ipadx = 210 constraints.gridwidth = 3 constraints.fill = GridBagPanel.Fill.Horizontal constraints.insets = new Insets(10, 5, 0, 5) layout += gardenPlot -> constraints // ボタンの生成と設定 val list = List("Center", "Border", "Shade") for (i <- 0 to (list.length - 1)) { setButton(list(i), i, 1) } setButton("Quit", 1, 2) /** * ボタンを生成し、パネル上に配置する * * @param String buttoName * @param Int x * @param Int y * @return Unit */ private def setButton(buttonName:String, x:Int, y:Int) = { val button = new Button(buttonName) val const = pair2Constraints(x, y); const.insets = new Insets(10, 5, 0, 5) layout += button -> const listenTo(button) } // ボタンのアクションを設定する reactions += { case ButtonClicked(b) => b.text match { case "Center" => { gardenPlot.centerPlant = garden.center.name gardenPlot.repaint } case "Border" => { gardenPlot.borderPlant = garden.border.name gardenPlot.repaint } case "Shade" => { gardenPlot.shadePlant = garden.shade.name gardenPlot.repaint } case "Quit" => System.exit(0) } } } } // ラジオボタンのアクションを設定する reactions += { case ButtonClicked(b) => b.text match { case "菜園" => { garden = new VegieGarden gardenPlot.clearPlants } case "一年草園" => { garden = new AnnualGarden gardenPlot.clearPlants } case "多年草園" => { garden = new PerennialGarden gardenPlot.clearPlants } } } } } /** * 植物を表すクラス */ case class Plant(name:String) /** * 庭トレイと */ trait Garden { def shade:Plant def center:Plant def border:Plant } /** * デフォルトの庭クラス */ class NoGarden extends Garden { def shade = new Plant("") def center = new Plant("") def border = new Plant("") } /** * 一年草園の庭クラス */ class AnnualGarden extends Garden { def border = Plant("アブラナ") def center = Plant("キンセンカ") def shade = Plant("コレウス") } /** * 多年草園の庭クラス */ class PerennialGarden extends Garden { def border = Plant("ベンケイソウ") def center = Plant("ケマンソウ") def shade = Plant("チダケサシ") } /** * 菜園の庭クラス */ class VegieGarden extends Garden { def border = Plant("エンドウ") def center = Plant("トウモロコシ") def shade = Plant("ブロッコリ") } /** * 庭の様子を表示するパネル */ class GardenPanel extends Panel { var borderPlant = ""; var centerPlant = ""; var shadePlant = ""; var garden = new NoGarden def clearPlants = { borderPlant = "" centerPlant = "" shadePlant = "" repaint() } override def paint(g:Graphics2D) = { super.paint(g) g.setColor(Color.LIGHT_GRAY) g.fillArc(1, 1, 80, 80, 0, 360) g.setColor(Color.BLACK) g.drawRect(0, 0, size.width - 1, size.height - 1) g.drawString(centerPlant, 100, 50) g.drawString(borderPlant, 75, 120) g.drawString(shadePlant, 10, 40) } }
0 件のコメント:
コメントを投稿