Search code examples
scalascala-swing

While creating Object, setting values to methods or variable without using def or val keyword


I come from a Java background and as expected, am having problem understanding some patterns used in Scala (see below). Every time I feel that I have a good understanding of Scala patterns or programming methodology, something pops up that is beyond my programming understanding and puts me back in learning mode. I guess that's a beauty of scala that always inspires me to keep learning :)

Anyway I trying to do some sample programming in scala swing.............

val frame = new MainFrame {
title = "Electronic Classroom"
contents = new BorderPanel {
  layout += new GridPanel(1, 2) {

    contents += new ScrollPane(semesterList)
    contents += new ScrollPane(courseList)
  } -> West

}

menuBar = new MenuBar {
  contents += new Menu("File") {

    contents += new MenuItem("Login") {
      action = Action("Login"){
          login
            user match{
          case Some(inst:Instructor) => instructorMenu.enabled = true
           enabled = false
           case Some(_) => instructorMenu.enabled = false
             enabled = false
          case _ =>
        }
      }

    }
    contents += new Separator
    contents += new MenuItem(Action("Exit")(sys.exit(0)))
  }
        }
  contents += instructorMenu
}

size = new Dimension(1000, 600)
centerOnScreen
 }

Here we are setting values to def and val without using def or val keyword while defining them (like title, size, contents etc) and it's now looking more like a body script which is different that the way we do in java where all the assignments etc takes place in a method body.. I guess I am missing a big design pattern here

Can someone help, abd explain to me the Scala design pattern??


Solution

  • This is actually not very different from Java—instead of creating an instance and then customising it, you are creating anonymous sub classes. E.g.

    val frame = new MainFrame {
      title = "Electronic Classroom"
    }
    

    instead of

    val frame = new MainFrame
    frame.title = "Electronic Classroom"
    

    The difference to Java is that since Scala doesn't have dedicated constructor methods but treats all expressions within the body of a class part of the constructor, your anonymous sub class kind of "overrides" the constructor.

    To compare directly with Java, lets say it wasn't anonymous:

    class MyMainFrame extends MainFrame {
      title = "Electronic Classroom"
    }
    

    In Java, this would be roughly equivalent to:

    public class MyMainFrame extends JFrame {
        public MyMainFrame() {
            super();
            setTitle("Electronic Classroom");
        }
    }
    

    (I hope this is valid Java syntax, I'm a bit rusty)


    This is the same case for MenuBar, Menu, MenuItem. Only Action { ... } is not subclassing but calling method apply on the Action companion object, making the syntax a bit more succinct (this way you won't have "constructor" statements, e.g. you couldn't write accelerator = None and so forth).