Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- 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
- }
- }
Add Comment
Please, Sign In to add comment