Scala: How do I dynamically instantiate an object and invoke a method using reflection?
にサンプルがあったのでメモ。
class Foo { def hello(name: String): String = "Hello there, %s".format(name) } object FooMain { def main(args: Array[String]) { val foo = Class.forName("Foo").newInstance.asInstanceOf[{ def hello(name: String): String }] println(foo.hello("Walter")) // prints "Hello there, Walter" } }この方法を利用すると以前書いたAbstractFactoryのサンプルをこれで書きかえることができるので書きかえてみた。
// ラジオボタンのアクションを設定する 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 } } }の部分は
// ラジオボタンのアクションを設定する reactions += { case ButtonClicked(b) => { garden = Class.forName(buttonMap.getOrElse(b.text, "")).newInstance.asInstanceOf[Garden]; gardenPlot.clearPlants; } }だけでOKになる。 全ソースはこちら
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 buttonMap = Map("菜園" -> "VegieGarden" , "一年草園" -> "AnnualGarden" , "多年草園" -> "PerennialGarden"); // ButtonGroupの生成と設定 val group = new ButtonGroup for ((key, value) <- buttonMap) { val button = new RadioButton(key) 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) => { garden = Class.forName(buttonMap.getOrElse(b.text, "")).newInstance.asInstanceOf[Garden]; 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 件のコメント:
コメントを投稿