Created
September 17, 2008 03:24
-
-
Save takedasoft/11187 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) { | |
prepareAxis(g) | |
def drawRed = draw(g)(Color.red)_ //curry(部分適用) | |
drawRed( this.points() ) | |
} | |
/** 関数のセッター */ | |
def setFunc(func:Int=>Int){ | |
this.func = func | |
} | |
/** Seq[Point]を線分で結ぶ */ | |
private 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) ) | |
} | |
} | |
/** 設定した関数による各点の計算結果 */ | |
private 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 軸最大値*/ | |
private var cx = 0 | |
private var cy = 0 | |
/**実点 to 描画点変換*/ | |
private def onx(x:Double):Int = cx+x.toInt | |
private def ony(y:Double):Int = cy-y.toInt | |
/** 軸設定と描画 */ | |
private 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 { | |
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]( | |
x => x | |
, x => x*x / 200 | |
, Math.pow(_,3).toInt/40000 | |
, x => (100*Math.sin( 3.14 * x /180 )).toInt | |
, x => Math.abs(x) | |
, x => x match{ case 0 => Int.MaxValue case _ => 200/x } | |
, x => x % 20 match{ case 0 => x case _ => 0 } | |
, f7 | |
) | |
/** 現在表示中の関数インデックス */ | |
var current:Int = 0 | |
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