User Tools

Site Tools


Sidebar

Dave Orme muses about agile and functional programming.

My current work emphasizes SOA applications using Scala, Kubernetes, and AWS with a React-based SPA front-end. I'm also interested in progressive web applications and developer tools.


Blog

Scala, Clojure, and FP

Agile

The Cloud

Data-First Development

Older work

Coconut Palm Software home


Donate Bitcoin:

1Ecnr9vtkC8b9FvmQjQaJ9ZsHB127UzVD6

Keywords:

Kubernetes, Docker, Streaming Data, Spark, Scala, Clojure, OSGi, Karaf, GCP, AWS, SQL

Disclaimer:

Everything I say here is my own opinion and not necessarily that of my employer.

blog:xscalawt_stylesheets

XScalaWT Stylesheets

Tonight I finished a first cut at adding style sheet support to XScalaWT. I'm interested in peoples' thoughts/suggestions on the syntax and so forth.

Here's how to define a style sheet in XScalaWT:

val WHITE = Display.getDefault.getSystemColor(SWT.COLOR_WHITE)
val RED = Display.getDefault.getSystemColor(SWT.COLOR_RED)
val INVALID_INPUT="INVALID_INPUT"
 
object loginStyles extends Stylesheet(
  $[Control] (       // all Controls have a white background
    _.setBackground(WHITE)
  ),
 
  $class[Control](INVALID_INPUT) (
    _.setForeground(RED)
  )
)

Here we're defining a login dialog box. We want the entire background to be white, and we want to define a style class that can be used to control how things look when there's invalid input in the dialog.

(Note that I changed the dollar-sign syntax to mean $tyle, rather than to be the generic object construction syntax. We will see the new generic object construction syntax next.)

Here is how we can use this style sheet:

var passwordLabel : Label = null
 
val window = shell("Please log in",
  group("User information",
    setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)),
    setLayout(new GridLayout(1, false)),
 
    label("Username"),
    text (
      setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false))
    ),
 
    label(""),
 
    label("Password", passwordLabel = _),
    *[Text](SWT.BORDER | SWT.PASSWORD) (     // The manual, "specify everything" syntax
      setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false))
    )
  ),
 
  // OK/Cancel buttons
  composite (
    setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)),
    setLayout(new GridLayout(2, true)),
 
    button("OK", { e : SelectionEvent => passwordLabel.setStyleClass(INVALID_INPUT) }),
    button("Cancel", { e : SelectionEvent => e.widget.asInstanceOf[Button].getShell.close() } )
  )
)
loginStyles.apply(window)

Here we actually lay out our login dialog. We apply the style sheet to the dialog on the last line of code. And to prove that we can update a given widget's style class after the fact and have it automatically update, we make the OK button set the password label's style. The result is that clicking “OK” will turn the password label red.

(This is accomplished by using Scala implicits to type-safe add the setStyleClass method to Widget and all of its subclasses.)

The XScalaWT style sheet support is implemented in exactly 100 lines of Scala, including white space–another illustration of how flexible and expressive Scala is.

As usual, full XScalaWT source code is available at http://bitbucket.org/djo/xscalawt/

For reference, here is the source code to the entire example:

object LoginBoxStyled {
  def main(args : Array[String]) : Unit = {
    val WHITE = Display.getDefault.getSystemColor(SWT.COLOR_WHITE)
    val RED = Display.getDefault.getSystemColor(SWT.COLOR_RED)
 
    var passwordLabel : Label = null
 
    val INVALID_INPUT="INVALID_INPUT"
 
    object loginStyles extends Stylesheet(
      $[Control] (
        _.setBackground(WHITE)
      ),
 
      $class[Control](INVALID_INPUT) (
        _.setForeground(RED)
      )
    )
 
    val window = shell("Please log in",
      group("User information",
        setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false)),
        setLayout(new GridLayout(1, false)),
 
        label("Username"),
        text (
          setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false))
        ),
 
        label(""),
 
        label("Password", passwordLabel = _),
        *[Text](SWT.BORDER | SWT.PASSWORD) (     // The manual, "specify everything" syntax
          setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false))
        )
      ),
 
      // OK/Cancel buttons
      composite (
        setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false)),
        setLayout(new GridLayout(2, true)),
 
        button("OK", { e : SelectionEvent => passwordLabel.setStyleClass(INVALID_INPUT) }),
        button("Cancel", { e : SelectionEvent => e.widget.asInstanceOf[Button].getShell.close() } )
      )
    )
    loginStyles.apply(window)
 
    window.pack
    val size = window.getSize()
    window.setSize(250, size.y)
 
    runEventLoop(window)
  }
}

~~LINKBACK~~ ~~DISCUSSION~~

blog/xscalawt_stylesheets.txt · Last modified: 2014/10/17 22:08 (external edit)