ラジオボタンに対応する庭園クラスがあるのですが、それぞれの庭園クラスの親クラスを実装し、イベントアクション内では親クラスを操作するという形になっています。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 件のコメント:
コメントを投稿