0
Scala Swing Ken Scambler
Origins of Swing  <ul><li>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 </li></ul>
Swing’s Advantages <ul><li>Cross-platform (mostly!)
Extremely powerful
Flexible
Extensible
Uses hardware acceleration
Comparable to native performance (nowadays!) </li></ul>
Swing’s Disadvantages <ul><li>Huge, complex API
Requires very verbose code
Events require anonymous inner class gymnastics!
Doesn’t integrate with Collection API
Models aren’t typesafe </li></ul>
Introducing Scala Swing <ul><li>Thin wrapper framework
Far less code
Dramatically simpler API
Full integration with Scala Collections </li></ul>
Introducing Scala Swing <ul><li>Scala getter/setter properties
Events use pattern-matching and partial functions
Performance is just as good </li></ul>
Panels & Layouts <ul><li>Layouts are built into the panel
Upcoming SlideShare
Loading in...5
×

Scala+swing

7,226

Published on

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
7,226
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
77
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

Transcript of "Scala+swing"

  1. 1. Scala Swing Ken Scambler
  2. 2. Origins of Swing <ul><li>Java’s main desktop programming environment
  3. 3. Single Threaded, MVC framework
  4. 4. Developed from Abstract Windowing Toolkit (AWT) in the late 90s
  5. 5. Sun has focused on the web rather than desktop
  6. 6. Has faded from the limelight
  7. 7. However still has many users and devotees </li></ul>
  8. 8. Swing’s Advantages <ul><li>Cross-platform (mostly!)
  9. 9. Extremely powerful
  10. 10. Flexible
  11. 11. Extensible
  12. 12. Uses hardware acceleration
  13. 13. Comparable to native performance (nowadays!) </li></ul>
  14. 14. Swing’s Disadvantages <ul><li>Huge, complex API
  15. 15. Requires very verbose code
  16. 16. Events require anonymous inner class gymnastics!
  17. 17. Doesn’t integrate with Collection API
  18. 18. Models aren’t typesafe </li></ul>
  19. 19. Introducing Scala Swing <ul><li>Thin wrapper framework
  20. 20. Far less code
  21. 21. Dramatically simpler API
  22. 22. Full integration with Scala Collections </li></ul>
  23. 23. Introducing Scala Swing <ul><li>Scala getter/setter properties
  24. 24. Events use pattern-matching and partial functions
  25. 25. Performance is just as good </li></ul>
  26. 26. Panels & Layouts <ul><li>Layouts are built into the panel
  27. 27. Eg. BorderPanel, GridPanel, FlowPanel
  28. 28. Add components with 'contents' buffer </li></ul>
  29. 29. FlowPanel new FlowPanel { contents += new Button( &quot;A&quot; ) contents += new Button( &quot;B&quot; ) contents += new Button( &quot;C&quot; ) contents += new Button( &quot;D&quot; ) }
  30. 30. GridPanel new GridPanel(3,3) { contents ++= 1 to 9 map ( n => new Button(n.toString)) }
  31. 31. BorderPanel new BorderPanel { import BorderPanel.Position._ layout( new Button( &quot;West&quot; )) = West layout( new Button( &quot;Center&quot; )) = Center layout( new Button( &quot;North&quot; )) = North }
  32. 32. Events <ul><li>No more XXXListeners!
  33. 33. Individual events are case classes
  34. 34. Event handlers are PartialFunctions which pattern match on events
  35. 35. Classes which emit events have the Publisher trait
  36. 36. Classes which listen to Publishers have the Reactor trait. </li></ul>
  37. 37. 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 ) }
  38. 38. ButtonClicked events new FlowPanel { // Panels are Reactors // Buttons are Publishers val button = new Button( &quot;abc&quot; ) listenTo(button) reactions += { case ButtonClicked(b) => println( &quot;Clicked &quot; + b.text) } //... }
  39. 39. ButtonClicked events // All publishers are reactors // that listen to themselves new Button( &quot;abc&quot; ) { reactions += { case ButtonClicked(b) => println( &quot;Clicked &quot; + b.text) } }
  40. 40. 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 => } }
  41. 41. Selection Events new FlowPanel { val fruitList = List( &quot;apples&quot;, &quot;bananas&quot;, &quot;pears&quot; ) val listView = new ListView(fruitList ) listenTo( listView .selection) reactions += { case SelectionChanged(`fruitList`) => } }
  42. 42. ListViews class ListView[A] extends Component { def this (items: Seq[A]) = //... //... }
  43. 43. ListViews case class City(name: String, country: String, population: Int , capital: Boolean ) val items = List( City( &quot;Lausanne&quot; , &quot;Schweiz&quot; , 129273, false ), City( &quot;Paris&quot; , &quot;France&quot; , 2203817, true ), City( &quot;New York&quot; , &quot;USA&quot; , 8363710 , false ), City( &quot;Berlin&quot; , &quot;Germany&quot; , 3416300, true ), City( &quot;Tokyo&quot; , &quot;Japan&quot; , 12787981, true )) val view = new ListView(items) val cityNames = view.selection.items.map(_.name)
  44. 44. Renderers <ul><li>From the last example... </li></ul>val view = new ListView(items) { renderer = ListView.Renderer(_.name) } <ul><li>From the last example... </li></ul>
  45. 45. 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) } }
  46. 46. 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) } }
  47. 47. Fun with mixins val panel = new Panel with BlueBackground with HorizontalLines with VerticalLines with Blobs
  48. 48. Fun with mixins val panel = new Panel with BlackBackground with Blobs with VerticalLines with HorizontalLines
  49. 49. 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) } } } }
  50. 50. What's missing? <ul><li>Work in progress </li><ul><li>Drag N' Drop
  51. 51. Tree views
  52. 52. Better actor support for multi-threading </li></ul><li>EPFL are snowed under!
  53. 53. Community contributions will make a big difference </li></ul>
  54. 54. Questions
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×