• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Scala+swing
 

Scala+swing

on

  • 6,748 views

 

Statistics

Views

Total Views
6,748
Views on SlideShare
6,745
Embed Views
3

Actions

Likes
4
Downloads
64
Comments
0

2 Embeds 3

http://us-w1.rockmelt.com 2
http://b.hatena.ne.jp 1

Accessibility

Categories

Upload Details

Uploaded via as OpenOffice

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Scala+swing Scala+swing Presentation Transcript

    • Scala Swing Ken Scambler
    • Origins of Swing
      • Java’s main desktop programming environment
      • Single Threaded, MVC framework
      • Developed from Abstract Windowing Toolkit (AWT) in the late 90s
      • Sun has focused on the web rather than desktop
      • Has faded from the limelight
      • However still has many users and devotees
    • Swing’s Advantages
      • Cross-platform (mostly!)
      • Extremely powerful
      • Flexible
      • Extensible
      • Uses hardware acceleration
      • Comparable to native performance (nowadays!)
    • Swing’s Disadvantages
      • Huge, complex API
      • Requires very verbose code
      • Events require anonymous inner class gymnastics!
      • Doesn’t integrate with Collection API
      • Models aren’t typesafe
    • Introducing Scala Swing
      • Thin wrapper framework
      • Far less code
      • Dramatically simpler API
      • Full integration with Scala Collections
    • Introducing Scala Swing
      • Scala getter/setter properties
      • Events use pattern-matching and partial functions
      • Performance is just as good
    • Panels & Layouts
      • Layouts are built into the panel
      • Eg. BorderPanel, GridPanel, FlowPanel
      • Add components with 'contents' buffer
    • FlowPanel new FlowPanel { contents += new Button( "A" ) contents += new Button( "B" ) contents += new Button( "C" ) contents += new Button( "D" ) }
    • GridPanel new GridPanel(3,3) { contents ++= 1 to 9 map ( n => new Button(n.toString)) }
    • BorderPanel new BorderPanel { import BorderPanel.Position._ layout( new Button( "West" )) = West layout( new Button( "Center" )) = Center layout( new Button( "North" )) = North }
    • Events
      • No more XXXListeners!
      • Individual events are case classes
      • Event handlers are PartialFunctions which pattern match on events
      • Classes which emit events have the Publisher trait
      • Classes which listen to Publishers have the Reactor trait.
    • Publishers & Reactors trait Reactor { val reactions: Reactions def listenTo(ps: Publisher*): Unit def deafTo(ps: Publisher*): Unit } trait Publisher extends Reactor { def publish(e: Event): Unit listenTo( this ) }
    • ButtonClicked events new FlowPanel { // Panels are Reactors // Buttons are Publishers val button = new Button( "abc" ) listenTo(button) reactions += { case ButtonClicked(b) => println( "Clicked " + b.text) } //... }
    • ButtonClicked events // All publishers are reactors // that listen to themselves new Button( "abc" ) { reactions += { case ButtonClicked(b) => println( "Clicked " + b.text) } }
    • Mouse Events new FlowPanel { val pub = new FlowPanel listenTo( pub .mouse.clicks, pub .mouse.moves, pub .mouse.wheel) reactions += { case me: MouseClicked => case me: MouseDragged => case me: MouseEntered => case me: MouseExited => case me: MouseMoved => case me: MouseWheelMoved => } }
    • Selection Events new FlowPanel { val fruitList = List( "apples", "bananas", "pears" ) val listView = new ListView(fruitList ) listenTo( listView .selection) reactions += { case SelectionChanged(`fruitList`) => } }
    • ListViews class ListView[A] extends Component { def this (items: Seq[A]) = //... //... }
    • ListViews case class City(name: String, country: String, population: Int , capital: Boolean ) val items = List( City( "Lausanne" , "Schweiz" , 129273, false ), City( "Paris" , "France" , 2203817, true ), City( "New York" , "USA" , 8363710 , false ), City( "Berlin" , "Germany" , 3416300, true ), City( "Tokyo" , "Japan" , 12787981, true )) val view = new ListView(items) val cityNames = view.selection.items.map(_.name)
    • Renderers
      • From the last example...
      val view = new ListView(items) { renderer = ListView.Renderer(_.name) }
      • From the last example...
    • Custom Painting val panel = new Panel { background = Color.blue override protected def paintComponent(g: Graphics2D) { super .paintComponent(g) g setColor Color.red for (x <- 0 until size.width by 10) g.drawLine(x, 0, x, size.height) } }
    • Fun with mixins trait BlueBackground { this : Panel => background = Color.blue} trait BlackBackground { this : Panel => background = Color.black} trait VerticalLines extends Panel { override protected def paintComponent(g: Graphics2D) { super .paintComponent(g) g setColor Color.red for (x <- 0 until size.width by 10) g.drawLine(x, 0, x, size.height) } } trait HorizontalLines extends Panel { override protected def paintComponent(g: Graphics2D) { super .paintComponent(g) g setColor Color.white for (y <- 0 until size.height by 20) g.drawLine(0, y, size.width, y) } } trait Blobs extends Panel { override protected def paintComponent(g: Graphics2D) { super .paintComponent(g) g setColor Color.green for (x <- 0 until size.width by 20; y <- 0 until size.height by 40) g.fillOval(x-4, y-4, 8, 8) } }
    • Fun with mixins val panel = new Panel with BlueBackground with HorizontalLines with VerticalLines with Blobs
    • Fun with mixins val panel = new Panel with BlackBackground with Blobs with VerticalLines with HorizontalLines
    • A basic complete app object SwingTalk extends SimpleSwingApplication { def top = new MainFrame { contents = new GridPanel(1, 4) { val nameLabel = new Label( &quot;Name&quot; ) val nameText = new TextField val helloButton = new Button( &quot;Say Hello&quot; ) val goodbyeButton = new Button( &quot;Say Goodbye&quot; ) listenTo(helloButton, goodbyeButton) contents ++= nameLabel :: nameText :: helloButton :: goodbyeButton :: Nil reactions += { case ButtonClicked(`helloButton`) => Dialog.showMessage(nameLabel, &quot;Hello, &quot; + nameText.text) case ButtonClicked(`goodbyeButton`) => Dialog.showMessage(nameLabel, &quot;Goodbye, &quot; + nameText.text) } } } }
    • What's missing?
      • Work in progress
        • Drag N' Drop
        • Tree views
        • Better actor support for multi-threading
      • EPFL are snowed under!
      • Community contributions will make a big difference
    • Questions