Created
September 17, 2008 03:26
-
-
Save takedasoft/11188 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.takeda_soft.examples | |
import javax.swing.{JPanel,JFrame,JButton} | |
import java.awt.{Color,Graphics,Point,BorderLayout} | |
import java.awt.event.{ActionListener,ActionEvent} | |
/** | |
JButton+Actionの記述をDSL化する | |
*/ | |
class SButton extends JButton{ | |
def this(label:String,action: => Unit){ | |
this() | |
this.setText(label) | |
this.addActionListener( new ActionListener{ | |
def actionPerformed( e:ActionEvent ){ | |
//特に意味はない。キャストってこれでいいのか? | |
val b:SButton = e.getSource.asInstanceOf[SButton] | |
//コードブロックの実行 | |
action | |
} | |
} | |
) | |
} | |
} | |
/** | |
設定した関数の計算結果を描画するプロッター。 | |
*/ | |
class Plotter(var func:Int => Int) extends JPanel{ | |
/** | |
Swing機構からコールされるフックメソッド。 | |
全描画処理のエントリポイント。 | |
*/ | |
override def paintComponent(g:Graphics) { | |
//val g2:Graphics2D = g.asInstanceOf[Graphics2D] //他にcastの方法は? | |
prepareAxis(g) | |
def drawRed = draw(g)(Color.red)_ //curry(部分適用) | |
drawRed( this.points() ) | |
} | |
/** Seq[Point]を線分で結ぶ */ | |
def draw(g:Graphics)(color:Color)(points:Seq[Point]){ | |
g.setColor( color ) | |
for( i <- 0 to points.size - 2 ){ | |
g.drawLine( onx(points( i ).getX),ony(points( i ).getY), | |
onx(points(i+1).getX),ony(points(i+1).getY) ) | |
} | |
} | |
/** 関数のセッター */ | |
def setFunc(func:Int=>Int){ | |
this.func = func | |
} | |
/** 設定した関数による各点の計算結果 */ | |
def points():Seq[Point] = { | |
val xs = -cx.toInt to cx.toInt //X軸の範囲 | |
//val xs2 = xs.start until xs.end by xs.step+1 //読み飛ばしもできる | |
xs.map { x => new Point( x, func(x) ) } | |
} | |
/**中心点 or 軸最大値*/ | |
var cx = 0 | |
var cy = 0 | |
/**実点 to 描画点変換*/ | |
def onx(x:Double):Int = cx+x.toInt | |
def ony(y:Double):Int = cy-y.toInt | |
/** 軸設定と描画 */ | |
def prepareAxis(g:Graphics){ | |
cx = getWidth/2 | |
cy = getHeight/2 | |
g.setColor( Color.black ) | |
g.drawLine( cx, 0 ,cx, cy*2 ) | |
g.drawLine( 0, cy, cx*2, cy) | |
} | |
} | |
object Main extends JFrame { | |
//この関数定義をきれいに書く方法? | |
//無名関数のListって作れない? | |
val f0:Int=>Int = x => x | |
val f1:Int=>Int = x => x*x / 200 | |
val f2:Int=>Int = x => x*x*x / 40000 | |
val f3:Int=>Int = x => ( 100 * Math.sin( 3.14 * x / 180 ) ).toInt | |
val f4:Int=>Int = x => if( x >= 0 ) x else Math.abs(x) | |
val f5:Int=>Int = x => x match{ case 0 => Int.MaxValue case _ => 200/x } | |
val f6:Int=>Int = x => x % 20 match{ case 0 => x case _ => 0 } | |
val f7:Int=>Int = x => if( x > 0 ) f7(x-1) - 1 | |
else if( x < 0 ) f7(x+1) + 1 | |
else 0 | |
/** 関数サンプル集 */ | |
val functions:List[Int=>Int] = f0::f1::f2::f3::f4::f5::f6::f7::Nil | |
/** 現在表示中の関数インデックス */ | |
var current:Int = 7 | |
def main(args: Array[String]){ | |
val plotter = new Plotter( functions(current) ) | |
val button = new SButton("change function", | |
{ | |
current = if( current == functions.size - 1 ) 0 | |
else current + 1 | |
plotter.setFunc(functions(current)) | |
this.repaint() | |
} | |
) | |
//Swing | |
this.getContentPane().add(button,BorderLayout.SOUTH) | |
this.getContentPane().add(plotter) | |
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) | |
this.setBounds(10, 10, 400, 400) | |
this.setTitle("function plotter") | |
this.show | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment