Get your own free workspace
View
 

cs297

Page history last edited by PBworks 4 years, 1 month ago

CS297 - JavaFX as a DSL in Scala / Groovy

by Sadiya Hameed (sadiya AT gmail.com)

Advisor: Dr. Cay Horstmann

Computer Science Dept., San Jose State University

 

From Dr. Horstmann's Project idea page:

At the JavaOne 2007 conference, Java FX was introduced as scripting language for Flash-like effects in Java Swing.

It seems unfortunate that it is yet another language. The modern trend is to provide domain-specific languages (DSLs) inside a larger host language. The goal of this project is to implement the functionality of Java FX as DSLs into the Scala and Groovy languages, and to reason about the suitability of these languages as DSL hosts. Scala claims to have been invented for just this purpose, and Groovy has had practical success in providing DSLs for XML builders, ORM, etc.

 

Link to CS298 blog: CS298

Link to Project proposal:  cs297proposal.pdf

CS297 Report: 297 Report.pdf

 

 

Project Timeline:

 

Timeline

Task

Week 1

(8/23 – 8/29)

Prepare and submit the proposal. Basic environment setup. Read on Java Swing and 2D.

Week 2

(8/30 – 9/05)

Research features of JavaFX (e.g. bind/trigger etc.)

Week 3

(9/06 – 9/12)

Check out a few JavaFX examples to see which features are being used in real life scenarios.

Mimic one JavaFX feature in Scala.

Week 4

(9/13 – 9/19)

Evaluate tools available in Scala that might enable the language to be a domain-specific language’s host

Week 5  to 7

(9/20 – 10/10)

Develop a prototype in Scala

Week 8

(9/27 – 10/17)

Evaluate how successful Groovy’s metaprogramming features would be in implementing a domain-specific language

Week 9 to 11

(10/18 – 11/07)

Develop a prototype in Groovy

Week 12, 13

(11/08 – 11/21)

Comparison and evaluation of prototypes and initial work on the report draft

Week 14, 15

(11/22 – 12/05)

Finalize report and presentation to committee

 

Other Tasks:

  • Explore how other languages implement bind/trigger features
  • Look into Microsoft Linq -- C# 3.0
  • Writeup on triggers and bind
  • How to simulate dur operator

 

Week 15: (11/29 – 12/05)

 

Changed the bind implementation a little. Now the syntax for bind is field1.property.text.bind field2.property.text and now field1.text works as expected (returns the String text).

 

Issue: ActionListener does get invoked on UI input but does not get called on setText() .. Have not found any solution for this yet..

Source Code: src (GroovyBind v3).zip

 

Might be useful someday:  (added the link to reference)

I have been testing the dynamic method invocation in Groovy: It allows method calls such as field1."$methodname"() so we could create the getter and setter method names of the property dynamically and call them.

dollarSignTester.groovy

 

Invalid Syntax:

String foo = "$toUpperCase"

String bar = "bar"

bar.foo()

 

Valid syntax:

String foo = "toUpperCase"

String bar = "bar"

bar."$foo"()

 


 

 

Week 13 & 14: (11/15 – 11/28)

Hours: 

 

To Do:

  1. How to implement bind in Groovy  -- in progress

     

The problem with last week's appraoches was that we wanted to do field1.text.bind field2.text and not  field1.bind field2

Initially I tried to override the dot operator since operators are overload-able in groovy but found out that groovy only allows operator overloading on a selected set of operators and the dot operator was not included.

Next approach was based on trying to override the actual dot method since "Since 1.0, Groovy supports the ability to intercept all method and property access via the invokeMethod and get/setProperty hooks" but the dot method was not captured in the invokeMethod block.

 

So finally I added some magic to the field1.text part by overriding the getProperty method (using ExpandoMetaClass and its overriding magic) on JTextField. Now instead of returning the text property of the JTextField it returns a BoundJTextField, a class that contains a bind method. So the user can do field1.text.bind field2.text and in the background both the text properties get bound to each other. Right now by default the text property is bound but we could potentially bind any property since we are passing in the property name.

 

Issue: ActionListener does get invoked on UI input but does not get called on setText() 

 

Source Code: overriding getProperty.groovy   (Works with Groovy1.1 RC2)

 

Next Step:

I need to move the replace getProperty code to a seperate place and see how to include it.

Also need to try out other components and binding with BoundProp type variables. (BoundProp to BoundProp binding was already done in last week's work)

 

Might be useful someday:

I have been testing the dynamic method invocation in Groovy: It allows method calls such as field1."$methodname"() so we could create the getter and setter method names of the property dynamically and call them.

dollarSignTester.groovy

 

Updates:

Finally I have been able to move the getProperty override code to a seperate class. It only works with the latest version of groovy which I checked out from SVN and built (doesn't even work with Groovy1.1 RC2). Even the latest developer version of Eclipse plugin could not run the code so will have to stick to command line for the time being.

Beauty of it is that the packages just need to be in the project and the user doesn't even have to import anything. All this is done by using the DelegatingMetaClass & Package Name Convention Solution

 

So the code looks something like this (for JTextField):

 

package groovy.runtime.metaclass.javax.swing;  

 

class JTextFieldMetaClass extends DelegatingMetaClass{

 

    JTextFieldMetaClass(MetaClass metaclass)

    {

        super(metaclass);

    }

 

    public Object getProperty(Object object, String property){

       //if property is "text" return a BoundJTextField

       //else return the property value

    }

 

Based on the package and the class name the MetaClass of JTextField is automatically replaced by the above class.

Source Code:src (GroovyBind v2).zip

 


 

Week 12: (11/08 – 11/14)

Hours:  9

 

To Do:

  1. Finalize committee

  2. How to implement bind in Groovy  -- in progress

     

2. Bind in Groovy

1st Approach: Categories

With Categories "To add a method to a class T, simply define a new class with a static method whose first parameter is of type T." e.g.

 

class BoundCategory {

    static void bind(JTextField field1, BoundProp other) {      

        field1.actionPerformed = { e -> println "event fired from component";  other.set(field1.getText()) }   

        other.propertyChange = { e -> println "event fired from boundProperty"; field1.setText(e.getNewValue()) }

    }

}

 

and then to use it

 

    JTextField field1 = new JTextField()

    Book book1 = new Book()   // A class with a member "title" of type BoundProp

 

    use (BoundCategory) {              

        /*binding a JTextField to a property*/

        field1.bind book1.title   

    }

 

but we want to bind the text property of the JTextField and not the field itself. A possible syntax is field1.bind("text", book1.title) .. but this does not seem very intuitive!

 

2nd Approach: BoundJTextField

The other approach was to create our own BoundJTextField class as we did in Scala.. Then the syntax to use it would be..

 

def field1 = new BoundJTextField()

Book book1 = new Book()  

field1.bText.bind book1.title  //could not use field.text because apparently text is a member of JTextField in Groovy

 

Not as great as Scala where you  didnt have to know about BoundJTextField's (except importing headers) and you would get the added functionality automagically.. also this isn't using any of the Dynamic features of Groovy. So no Groovy magic here.

 

3rd Approach: ExpandoMetaClass

You can add new methods to classes using the ExpandoMetaClass.. with the following syntax..

 

JTextField.metaClass.bind << {BoundProp other -> //do binding here}

def field1 = new JTextField()

Book book1 = new Book()

field1.bind book1.title  

 

 

but this has the same problem as the 1st approach. We want to say field1.text.bind not field1.bind.

 

Sample Code for above approaches: (The MetaTester requires Groovy-1.1-rc2)

src (Groovy bind v1).zip

 

Other issues:

  • Support for Generics is patchy even in the newest version. Link to discussion in mailing list:  1.1-rc-2 generics experiment  (second email in the list)
  • Cannot define methods with operators as identifiers. So cannot create the := method like we were using in Scala

 


 

Week 11: (11/01 – 11/07)

Hours: 10

 

To Do:

  1. Fix sample (Stocks) application

  2. Finalize committee

  3. How to implement bind in Groovy  -- started

 

1. Fix sample (Stocks) application

Source Code: src(Sample Application).zip

 

Nice to Have Feature: An overloaded method bind that handles the following situation.

 

val field = new JTextField;

field bind dollarAmount * euroRate

or

val label = new JLabel

label bind "Number of button clicks: {model.numClicks}"

 

Our bind only does a bidirectional bind between two Bound Properties (the Bound Property could belong to a JComponent). It does not allow unidirectional binding where the property can be attached to a Statement/Expression/Closure. If we were to create an overloaded method bind what type of parameter can we pass in it to store the required information?

 

3. How to implement bind in Groovy

 

a) Most promising way seems to be through Categories.  Created a trivial example of adding a method to a JTextField and that ran successfully.

 

b) Another way seems to be through ExpandoMetaClasses but have been unsuccessful yet in getting the following example from link to run

class Book {
String title
}

Book.metaClass.titleInUpperCase << {-> title.toUpperCase() }
def b = new Book(title:"The Stand")
assert "THE STAND" == b.titleInUpperCase()

The above fails with  "No such property: metaClass for class: java.lang.Class" error. Tried to import ExpandoMetaClass but that gives the error "unable to resolve groovy.lang.ExpandoMetaClass"

Will test if my version of Groovy supports ExpandoMetaClass or I need to upgrade.

 

Other useful Groovy features:

1. Parenthesis less methods & named parameters   Reference: UserGuide- statements

Method calls in Groovy can omit the parenthesis if there is at least one parameter and there is no ambiguity.

 

        println "Hello world"

      System.out.println "Nice cheese Gromit!"

 

It is also possible to omit parenthesis when using named arguments. This makes for nicer DSLs:

 

          compare fund: "SuperInvestment", withBench: "NIKEI"

      monster.move from: [3,4], to: [4,5]

 

When calling a method you can pass in named parameters. Parameter names and values are separated by a colon (like the Map syntax) though the parameter names are identifiers rather than Strings. Currently this kind of method passing is only implemented for calling methods which take a Map or for constructing JavaBeans.

 

        def bean = new Expando(name:"James", location:"London", id:123)

        println "Hey " + bean.name

        assert bean.id == 123

 

2.  Adding Listeners in Groovy  Reference: Getting Stated Guide - Groovy Beans

Though Groovy doesn't support anonymous inner classes, it is possible to define action listeners inline through the means of closures. So instead of writing in Java:

 

        Processor deviceProc = ...

        deviceProc.addControllerListener(new ControllerListener() {

           public void controllerUpdate(ControllerEvent ce) {

              ...

           }

        }

 

You can do that in Groovy with a closure:

 

        //Add a closure for a particular method on the listener interface

        deviceProc.controllerUpdate = { ce -> println "I was just called with event $ce" }   

 

Notice how the closure is for a method on the listener interface (controllerUpdate), and not for the interface itself(ControllerListener).  This technique means that Groovy's listener closures are used like a ListenerAdapter where only one method of interest is overridden.

This mechanism is heavily used in the Swing builder to define event listeners for various components and listeners. The JavaBeans introspector is used to make event listener methods available as properties which can be set with a closure 

The Java Beans introspector (java.beans.Introspector) which will look for a BeanInfo for your bean or create one using its own naming conventions. (See the Java Beans spec for details of the naming conventions it uses if you don't provide your own BeanInfo class). We're not performing any naming conventions ourselves - the standard Java Bean introspector does that for us.

Basically the BeanInfo is retrieved for a bean and its EventSetDescriptors are exposed as properties (assuming there is no clash with regular beans). It's actually the EventSetDescriptor.getListenerMethods() which is exposed as a writable property which can be assigned to a closure. 

 

3. Beans in Groovy Reference: Groovy Beans

    When Groovy is compiled to bytecode, the following rules are used.

  • If the name is declared with an access modifier (public, private or protected) then a field is generated.
  • A name declared with no access modifier generates a private field with public getter and setter (i.e. a property).
  • If a property is declared final the private field is created final and no setter is generated.
  • You can declare a property and also declare your own getter or setter.
  • If you want a private or protected property you have to provide your own getter and setter which must be declared private or protected.

 

4. Closures Reference: Groovy Statements

    If a method takes parameters you can leave the closure outside of the parenthesis (provided that the closure parameter is the last parameter on the underlying method).

      def value = [1, 2, 3].inject(0) { count, item -> count + item }

      assert value == 6

 

5. Miscellaneous

  • If you don't want to have NullPointerExceptions thrown you can use the ?. operator rather than . to perform your navigation. 
  • The return statement is optional at the end of methods. Also you don't need to specify a return type (it will default to Object in the bytecode if none is specified).
  • You can use the this keyword inside static methods (which refers to this class).
  • Methods and classes are public by default.
  • Protected in Groovy is the equivalent of both package-protected and protected in Java. i.e. you can have friends in the same package - or derived classes can also see protected members.
  • The throws clause in a method signature is not checked by the Groovy compiler, because there is no difference between checked and unchecked exceptions
  • == means equals on all types. In Java there's a wierd part of the syntax where == means equality for primitive types and == means identity for objects. Since we're using autoboxing this would be very confusing for Java developers.. since x == 5  would be mostly false if x was 5. So for simplicity == means equals() in Groovy. If you really need the identity, you can use the method "is" like foo.is(bar). This does not work on null, but you can still use == here: foo==null.

     


Week 10: (10/25 – 10/31)

Hours: 6

 

To Do:

  1. Create other Bound JComponents and package them up.
  2. Generate Scala docs for the package.
  3. Create real time sample (Stocks) application to show bind in action
  4. Fix BoundBeanProp class for error (Attempt to mutate in notification)         Added a flag to fix the error. 
  5. List JavaFX classes that encapsulates JComponents
  6. Look into Groovy

 

1. Create other Bound JComponents and package them up

boundUtilities.zip

 

2. Generate Scaladoc:

Link to scaladoc man page: http://www.scala-lang.org/docu/files/tools/scaladoc.html

Generated Documentation for BoundUtilities: docs.zip

 

 

5. List JavaFX classes that encapsulates JComponents

Link to API: https://openjfx.dev.java.net/nonav/api/index.html

 

JavaFX has its own classes that encapsulate functionality of many JComponents such as:

 

JavaFX Java
Button JButton
CheckBox JCheckBox
ComboBox JComboBox
Label JLabel
ListBox JList
RadioButton JRadioButton
TextField JTextField
TextArea JTextArea

 

 


Week 9: (10/18 – 10/24)

Hours: 14

 

To Do:

  1. Create BoundBeanProp class
  2. Create real time sample (Stocks) application to show bind in action (waiting for bind to get done..)
  3. How to simulate dur operator
  4. Writeup on triggers and bind (waiting for bind to get done..)

     

1. Create BoundBeanProp class

Problem: The listeners are not getting called when the user changes value in the JTextField (or JComboBox or JList). This is due to the fact that when the value is changed through the UI the firePropertyChange does not happen.

 

How does JavaFX handle this?

JavaFX has its own classes that encapsulate each underlying JComponent class. So it uses other listeners besides propertyChangeListener.

 

Is DocumentListener an option?

Question: Can we assume all BoundBean properties will have a document listener?

Question: Isnt the document listener added to the document or can we add it to the eventSetDescriptor of the BoundBeanProp? If yes which one of the eventSetDescriptors?

 

We are trying to make a BoundBeanProperty class by adding propertyChangeListeners using reflection. After encountering the above problem we decided to do what JavaFX does and create our own TextField class. Now facing another road block because the propertyChangeListeners do get called but with a propertyEvent named "ancestor" (my guess is this happens because the text isn't a property of the JTextField but its ancestor Document). But this leaves us with the problem of how to find which property changed?

Anyways I thought if we were creating our own components anyways (and also adding firepropertychange listeners for each one of the properties manually) so why not go back to the BoundJTextField approach. So with the newly acquired nifty view creating power and a tiny hack I have created the BoundJTextField (JTextField on steroids!) and the user just has to add an import statement to automagically get the power of bind in the good ol' JTextField.

 

import util.BoundJTextField._;

 

and you can do:

 

val field1 = new JTextField;

field1.text bind p.name;     //name is a BoundProp[String] and p is an object of some class Person

 

 

and Voila! you have bi-directional bind:)

Compare this to the JavaFX bind (the nicer readabilty is due to the Declarative syntax!)

TextField {
value: bind model.saying
}

Even if for some reason we decide to plod on with the BoundBeanProperty approach.. this was still worth the time put in just to see the results.. I am officially a Scala convert now:)

 

Source Code for the magic:

src (JTextField Bind).zip

 

 

 


 

Week 8: (10/11 – 10/17)

Hours: 8

 

To Do:

  1. Create BoundBeanProp instead of BoundJTextField and also remove the value variable    --- Questions 
  2. Create real time sample application to show bind in action
  3. How scala does the predef package (move implicit conversions to a seperate package) 
  4. Remove propertyChangeListener from  BoundJTextListener
  5. Are variables public by default in Scala, and how to get Field objects
  6. Why were overridden methods not being called when I used views
  7. How to simulate dur operator
  8. a page of writeup on triggers and bind

 

3. Move implicit conversions to a seperate package

Created companion objects and moved implicit conversion to those. Attached sample src code.

src(Views).zip 

 

4. Remove propertyChangeListener from  BoundJTextListener

If I remove the "with PropertyChangeListener" part from the declaration of class BoundJTextField it gives the following error:

"The method addPropertyChangeListener(PropertyChangeListener) in the type PropertyChangeSupport is not applicable for the arguments (BoundJTextField) ". Why is this happening when JComponent implements PropertyChangeListener? (Answer: Use anonymous inner class)

 

 

5. Are variables public by default in Scala, and how to get Field objects

To get field objects of "private" vars we can do class.getDeclaredField("fieldName"); I was using the getField method which only returns public fields.

Jury still out on whether vars are public/private by default in Scala. From above fact it seems that vars are private but you can specifically say "private var xname : String = _;" in which case you cannot access the var without the getter. So how is this private different than the by default private type behavior? there is apparently no public access modifier in Scala for variables (gives an error if I qualify a var with it!) and the specs do not mention public as an access modifier! (Answer: One is implementation detail)

 

6. Why were overridden methods not being called when I used views

I wanted to add and override some methods in class BigInt using views, I could successfully add the methods but the method that I overrode (toString) were not being called and instead it was just calling the regular toString of BigInt.

Reason from the Scala list:

"The implicit conversion is only applied when it *needs* to be. Since (variable) is declared as a BigInt, and BigInt already defines a toString method, no conversion is necessary. The conversion is inferred separately at each site."

Possible solution is subclass RichInt from BigInt and then override the method.

 


 

Week 7: (10/4 – 10/10)

Hours: 12 hrs

 

To Do:

  1. Sample program to implement person name BoundProperty which is bound to a textbox
  2. Actual usecases for trigger
  3. Can we get field objects in Scala?                  ---This needed for triggers and not for bind, results found on this listed below  
  4. Create a mixin triggerable and overload its constructor to load triggers from a global hashtable --- This we will need to do if we mimic triggers since they are class based as opposed to bind which is object based and hence can be implemented without needing an external hashtable. 
  5. How scala does the predef package (move implicit conversions to a seperate package)   --- Needed for triggers not bind -- still need to check         
  6. Bidirectional implicit conversion                       ---Also needed for triggers not for bind. Tried last week did not work, will try again when implementing triggers
  7. What is the associativity of := operator (will use := if =not possible to overload)      --- Left associative (only operators ending with : are right associative)
  8. Understand views better                             
  9. Look into Microsoft Linq -- C# 3.0

 

1. Sample program to implement  student name BoundProperty which is bound to a textbox

Some success at last!

 

JavaFX syntax

TextField {

            value: bind someVariable

}

 

OurSyntax:

val field1 = new BoundJTextField;

field1.value bind name;                    //name being a BoundProp[String]

 

src(TestBind).zip

 

2. Actual uses of triggers in programs:

Basically on update perform a check, call a function, or take some action. Bind on the other hand is bidirectional update of 2 variables dependent on each other. Sample uses of triggers in a program:

trigger samples.txt

 

Also this javafx script page says

"JavaFX classes don't have constructors, and JavaFX attributes don't have "setters" like Java bean properties. Instead, JavaFX provides SQL-like triggers that allow you to handle data modification events.

Triggers are introduced with the trigger keyword.

A trigger consists of a header and a body. The header specifies the type of event the trigger applies to. The body of the trigger is a procedure that executes whenever the specified event occurs. Inside the body you can use any of the statements available inside the body of an operation. Triggers also behave like member functions/operations, in that the context object is accessible inside the body via the this keyword."

<-- So I think triggers only provide functionality that JavaFX lacks due to absence of constructors and setters.  We could do all the trigger work in setters and constructors. 

 

3. Can we get field objects in Scala?

Field objects are useless since all the class members are actually accessor methods below the hood so we won't have any fields in a scala class when we do javap/scalap.

 

We can get method objects though. But since we don't do bind on class but on objects we don't need to look into this right now.

 

 


 

Week 6: (9/27 – 10/3)

Hours: 8

 

To Do:

  1. Sample program to implement BoundProperty class     ----------     In progress 
  2. How to convert from Scala to Java.                              
  3. Reflection in Scala.                                                        ----------     scala.reflect package
  4. JavaFX triggers are the object based or class based.   ----------     Class level
  5. Scala getters and setter (check -print:era option on compile) --     Link
  6. Look into Microsoft Linq -- C# 3.0

 

1. Sample BoundProp Program: 

JavaFX code we are trying to simulate:

 

class X {

       attribute num: Number?;

}

 

trigger on X.num[oldValue] = newValue {
       System.out.println("X.num: just replaced {oldValue} with {newValue}"); //make everything between the { } into a closure
}

 

var x = X {

      num: 100

};

 

x.num = 3;    // prints X.num: just replaced 100 with 3

 

Code for the BoundProp class and tester (with closures): 

src (BoundProperties).zip

 

Problems:

  1. Triggers are supposed to be class based but Scala does not allow static members so how can I add the closure to the listener member of a class? Scala says static members should be added to a singleton object but we want multiple instances of the BoundProp class.
  2. Instead of have "num = 3" we have "num.value = 3"  (one possible solution was to add this implicit conversion  implicit def toBoundProp[T](x: Int) =  new BoundProp[Int](x); but now the setter wont work since = is now being called on BoundProp and not the variable num)

  3. Unable to overload assignment operator of class

Questions:

  1. Do we really need a List of listeners in the replace trigger case? We can only have one listener which is the closure being passed to the trigger. We will need a List of listeners for bind.

Prof. Horstmann suggested the java beans PropertyChangeListener and implicit conversions. Result still not perfect:( 

Code for the BoundProp class and tester (with java beans PropertyChangeListener):

src (BoundProp--java beans).zip

 

Problems:

  1. Implicit definitions cannot be moved to BoundProp class since the method should be callable without a prefix or it needs to be in a companion object. Not enough documentation on companion objects to understand how to create one yet. (But there should be some way of doing this since scala has classes like RichInt which supposedly are made using implicit conversions)
  2. Triggers are supposed to be class based and not object based but we cannot addPropertyChangeListener to class 
  3. Implicit definition works for val name : String = x.name but not for  x.name = "Fred"
  4. Unable to overload assignment operator of class

     

 

About overloading assignment (=) operator:

Source: Scala mailing list

 

"The short answer to your question is that assignment isn't an operator defined for a class, it's an operation treated specially by the compiler.

 
The long answer: in Scala, "operators" are really messages sent to objects.
 
1 + 2 is really
 
1.+(2)
 
But if you try to look at assignment that way, you run into a problem.
 
val foo = new Foo()
 
would become
 
val foo.=(new Foo())
 
So what class would define the method to receive the message?  No Foo exists before the Foo is constructed and after the Foo is constructed we don't want to assign it to itself.  The only answer is that, in some situations at least, the compiler has to have a default mechanism for assignment.  Scala takes the simplest path - all assignments use that same mechanism."

 

Look at:

  • Proxy
  • implicit conversions

 

2. How to convert from Scala to Java: 

"Scala is designed to be Java compatible, and its translation attempts to map like constructs to like. Scala classes become same-named Java classes, etc. To know for sure, however, you must use tools like javap." 

 Reference

 


 

 

Week 5: (9/20 – 9/26)

Hours: 8

 

To Do:

  1. Are classes publicly default? What is final in class definition? 
  2. Precedence of user defined operators without first character as formal operators
  3. Can you override the default getters and setters?
  4. Did any of the Scala features of last week allow us to do replace triggers?
  5. Understand Views in Scala
  6. Sample program to implement BoundProperty class
  7. Look into Microsoft Linq -- C# 3.0

     

 

1. Access level + Final and sealed modifiers:  Reference: Scala Language Specification

Tested with a sample program and classes are public by default.

 

The final modifier applies to class member definitions and to class definitions. A final class member definition may not be overridden in subclasses. A final class may not be inherited by a template. final is redundant for object definitions. Members of final classes or objects are implicitly also final, so the final modifier is redundant for them, too. final may not be applied to incomplete members, and it may not be combined in one modifier list with private or sealed.

The sealed modifier applies to class definitions. A sealed class may not be directly inherited, except if the inheriting template is defined the same source file as the inherited class. However, subclasses of a sealed class can inherited anywhere.

 

2. Operator Precedence: Reference: Scala Overview

The precedence of an infix operator is determined by its first character; it coincides with the operator precedence of Java for those operators that start with an operator character used in these languages. The following

lists operators in increasing precedence:

 (all letters)

 |

 ^

 &

 < >

 = !

 :

 + *

 / %

 (all other special characters)

Operators are usually left-associative, i.e. x + y + z is interpreted as (x + y) + z. The only exception to that rule are operators ending in a colon. These are treated as right-associative. An example is the list-consing operator ::. Here, x :: y :: zs is interpreted as x :: (y :: zs). Right-associative operators are also treated differently with respect to method lookup. Whereas normal operators take their left operand as receiver, right-associative operators take their right operand as receiver. For instance, the list consing sequence x :: y :: zs is treated as equivalent to zs.::(y).::(x). In fact, :: is implemented as a method in Scala’s List class, which prefixes a given argument to the receiver list and returns the resulting list as result.

 

4. Override default getter and setters:

Tried in code to override default accessors but it does not allow this either in class or even in subclasses.

Though this Link says you could do override in subclasses but I tried to run the code and it gave me an error "error overriding variable x in class Foo of type Int;  method x_= cannot override a mutable variable"

 

 

The link said:

"You can override the setters/getters in a subclass:

class Foo {
var x: Int = _;
}

class Bar extends Foo {
override def x_=(x: Int): Unit = {
assert(x > 0);
super.x = x;
}
}"

 Also read up on properties in C#

 

5. Did any of the Scala features of last week allow us to do replace triggers?

On a second look the statement

"For every definition of a variable var x: T in a class, Scala defines setter and getter methods as follows.

 def x: T

 def x_= (newval: T): unit"

seems to be talk about defining getters and setters only in terms of explaining how we can do variable dereferencing and assignment if every operation is a method call. They don't seem to be getters and setters in the real sense (of accessors) since the following does not work

 

class Kelvin {

  private var d: int = 0      //private variable

}

 

object KelvinTester {

  def main(args: Array[String]) {

    val k:Kelvin = new Kelvin();

       k.d_ = 5                                //error value d_ is not a member of Kelvin

       k.d = 5                                 //variable d cannot be accessed in Kelvin

    System.out.println("k.d: " + k.d);         //variable d cannot be accessed in Kelvin

  }

}

which makes sense since you cannot override these "getters and setters" so what use could they be to begin with?

 

so when they say Scala allows one to define properties in the C# sense, I think this is only possible when the actual variable name is different then the name of the setters/getters or there is no variable, just a getter and setter function

 

class Celsius {

    private var d: int = 0

    def degree: int = d

    def degree_=(x: int): unit = if (x >= 273)

        d = x

}

 

This does not seem to help us define a replace trigger:

trigger on c.degree = newValue{

    //do some action (call a function or print something etc.) when an assignment takes place.

}

even regular C# style properties would not help in defining triggers since triggers are defined outside of the class.. and we shouldn't be going back and changing the class definition .... hmm back to square 1 .. no idea how to do triggers(new or replace type).

Is JavaFX able to do triggers cause they have methods declared outside the class definition and override the new or "=" operator when a trigger is defined?

 

Is it possible to change a class from outside the class definition (like add a method or override a method) in Scala? Then I could define a triggerOnNew(String className) and in that method override the new method of the given class or triggerOnReplace(String className, String variableName) and override the setter method of the className.variableName in the method.

 

On a side note this problem of not being able to add methods to existing classes is called external extensibility problem according to Scala Overview. Interesting project called MultiJava extends java to add open classes to it!

 

So In the end I think views might be the best options since "views allow one to augment a class with new members and supported traits." Understand them a little better now. So next trying to make a small code example to see how we could use those to may be a add some functionality to a class. 

 


 

 

Week 4: (9/13 – 9/19)

Hours: 16

 

To Do:

  1. List of Scala syntax tricks
  2. Think how to do triggers in Scala
  3. How to do XPath & XML type things in Scala
  4. Pattern matching in Scala
  5. Look into Microsoft Linq -- C# 3.0 
  6. Look into Named Parameters (like in smalltalk)
  7. Read up on Bound Properties
  8. Create a Scala Program to get comfortable with the syntax

 

Scala Features:

 

Includes ideas for triggers and XML, pattern matching etc. in Scala

 

 


 

Week 3: (9/06 – 9/12)

Hours: 8

 

To Do:

  1. Check out a few JavaFX examples to see which features are being used in real life scenarios.

  2. Mimic one JavaFX feature in Scala

 

Examples and Features used in them:

 

New discovery:dur operator (from “duration”): "When assigning any value with an array of possible values and the operator dur, JavaFX will create a background thread (or, more likely, push events into the AWT event queue) which will assign the range of values into the variable. By binding the location, size or transformation of a graphical element, this can create a smooth animation". Reference:Chaotic Java

Notes: To simulate multiple inheritance in scala look at mixins/Traits.

 

1. iTunes Display Shelf:

Link to demo and code: http://blogs.sun.com/chrisoliver/feed/entries/atom?cat=%2FF3

Uses bind extensively. Trigger is used only on replace (mostly call a function on trigger). Some list comprehension, do/do later and dur operator also used.

 

2. Yahoo Maps:

Link to demo and code: http://blogs.sun.com/chrisoliver/entry/more_f3_demos

Uses bind extensively. Trigger is used only on replace. Some embedded HTML (Search errors). Also uses list comprehension, do/do later and dur operator.

 

3. Mariah Carey website:

Link and code: http://javaboutique.internet.com/tutorials/javafx/

Used bind operator and possible areas of use for embedding HTML (for links and news etc.). Used dur a lot as well.

 

Insert keyword mimicked in scala:

Code files: src.zip

Results: The syntax is not as cool as JavaFX's "insert 5 into array". Also still need to figure out a way to mimic "insert 5 before expression in array" feature. Still working to find a better solution.

 

 


 

Week 2: (8/30 – 9/05)

Hours: 13

 

To Do:

  1. See what makes JavaFX tick. Enumerate all special features such as bind/trigger etc.
  2. Try to mimic some of the functionalities with just Java.

 

Features:

 

1. Incremental dependency-based evaluation (automatic data binding): [1] Considering the following model/View type example, the value of the View's title is dependent upon the model's saying attribute. The dependency between View's textField and Model's saying attribute is bi-directional. Initially the value of the title and textField are set by model.saying but when the user updates the textField value the model.saying is automatically updated (which in turn updates the title).

 

import javafx.ui.*;

class HelloWorldModel {
attribute saying: String;
}

var model = HelloWorldModel {
saying: "Hello World"
};

Frame {
title: bind "{model.saying} JavaFX"
width: 200
content: TextField {
value: bind model.saying //the bind operator indicates incremental update. This means that whenever the value of model.saying changes
//the text attribute of the label will be updated to the same value. 
}
visible: true
};
The same functionality mimicked in java code is HelloWorldTest.java
It also allows lazy incremental evaluation by using the keyword "lazy" [2]

2. Update Triggers: [2] JavaFX provides Triggers for data modification instead of constructors, destructors and setters etc.

You can trigger on

  • new
  • insert
  • delete
  • replace (trigger on oldValue = newValue)

 

 Example:

import java.lang.System;

class X {
attribute nums: Number*;
}

trigger on new X {
insert [3,4] into this.nums;
}

var x = new X();
System.out.println(x.nums == [3,4]); // prints true

 

3. List Comprehensions: [2] You can perform complex queries on arrays by using "select" and "foreach" key words. These are called List Comprehensions. Also note the use of conditional keyword "where".

 

Examples:

var a:Integer* = select n*n from n in [1..10] where (n%2 == 0); //  yields [4,16,36,64,100]
var a:Integer* = foreach(n in [1..4], m in [100,200] where (n%2 == 0) )
n*m; // also yields [200, 400, 400, 800]

 

4. Declarative syntax: Allows both declarative and procedural syntax. The declarative syntax makes for an easier read.

 

5. Static Typing: It does static typing (efficient compilation, compile time errors and warnings)

 

6. Type Inference: [2] Allows the programmer to omit the type in which case the interpreter tries to resolve the type.

 

7. First-class functions: [3] Treats functions as first-class objects.

 

8. Ability to embed HTML: [1] Allows embedding HTML in Labels (find out where else) .. seemed like the same thing as JSTL. # and ? operators where # stringifies the operand and ? dereferences it.

 

9. Multiple Inheritance: [2] Allows a class to extend from multiple classes (unlike Java).

 

10. Misc.: [2]

 

  • Note that in JavaFX technology, any object can be thrown and caught, not just those that extend java.lang.Throwable.

     

  • Normally, JavaFX code executes in the AWT Event Dispatch Thread (EDT) -- only code contained in the body of a do statement is allowed to execute in another thread. The do statement has a second form, do later, that allows for asynchronous execution of its body in the EDT rather than synchronous execution in a background thread, similar to the functionality provided by java.awt.EventQueue.invokeLater().
  • It allows the programmer to specify an inverse clause in the declaration of an attribute to show bi-directional relationship with another attribute, in which case JavaFX automatically updates the value of the specified attribute when the original one changes.
  • JavaFX allows Xquery-Update (similar to XPath) predicates in statements. e.g. 

     

    insert 13 after x[. == 2];        // yields [1, 12, 2, 13, 3, 10];

 

References:

  1. Learning more About JavaFX
  2. Learning JavaFX Script, Part 1
  3. Getting started with JavaFX 

 


 

Week 1: (8/23 – 8/29)

Hours: 10

 

To do:

  1. Project Proposal
  2. Read Java Swing chapters from Core Java.
  3. Update Eclipse to version 3.3 and install scala plugin for eclipse.

 

Deliverable :

Project proposal

 

Issues/Questions:

What are views in Scala? (supposedly enable metaprogramming)

 

Activities:

Aug 23: Initial research for proposal material

Aug 24: Created first draft of project proposal

Aug 26: Apparently cannot update Eclipse so installed a 3.3 along with the old 3.2 one (don't want to redo all the pluggins!).  Draft two of proposal created and uploaded.

Aug 27: Installed scala plugin in Eclipse. Proposal finalized.

  


 

Week 0:

 

JavaFX:

 

Scala:

  • Downloaded scala-2.5.1 from link and configured it to run through command line.
  • Downloaded the "beginner's guide" and ran the helloworld example through command line.

 

Comments (0)

You don't have permission to comment on this page.