Skip to content

Instantly share code, notes, and snippets.

@takedasoft
Created September 17, 2008 03:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takedasoft/11187 to your computer and use it in GitHub Desktop.
Save takedasoft/11187 to your computer and use it in GitHub Desktop.
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