How to change theme in Ext-Gwt (GXT) application

Some time ago Sencha company included new theme in their GXT library. It’s called SLATE and can be viewed in GXT Explorer demo on this site: http://www.sencha.com/examples/explorer.html. I’ve been searching, but I coudn’t find any clear information in web, how to made my gwt app to change theme to new skin instead of standard BLUE or GREY themes. After short investigating I realized, that everything is easy, but only if You keep standard paths in Your app to css/images.

First of all You have to copy to Your’s project directory some directories from GXT example zip file (can be downloaded here: http://www.sencha.com/products/gwt/download.php). Those directories are: css (with BLUE/GREY theme’s csses), images (all gxt standard images) and themes (new SLATE theme). They can be found in resource directory in gxt-x.x.x zip file.

Now, after copying directories to own app in gwt html entry point file it has to be placed following line:   < link rel=”stylesheet” type=”text/css” href=”css/gxt-all.css” /&rt;   That’s all. Nothing more gxt’s csses have to be included (instead of what I’ve found on internet). Why ? Becouse we will switch theme in java code later. In apps entry point java file in onModuleLoad() method we need to insert some code. We want to tell GXT, that we will be using SLATE theme as default, but we would like to change it later. This is made by passing ‘false’ parameter in .setDefaultTheme(..) method. Code for this:   ThemeManager.register(Slate.SLATE); //register non standard theme // Theme.GRAY.set(“file”,”css/gxt-gray.css”); //set custom css’es path for grey theme // Theme.BLUE.set(“file”,”css/gxt-all.css”); //set custom css’es path for standard blue theme // Slate.SLATE.set(“file”,”gxt/themes/slate/css/xtheme-slate.css”); //set custom path for SLATE theme GXT.setDefaultTheme(Slate.SLATE, false); //set default theme to new SLATE skin

That’s not all. If we would like to rearange our paths (i.e. by moving themes/images/css directories in other places) we have to uncoment commented code and set proper paths.

Because we would like to allow user to switch theme by own. We have to add somewhere in our app’s panels ThemeSelector which will do all work. It’s very easy. Just add somewhere this code:

  [ourContainer].add(new ThemeSelector());

You May Also Like

Agile Skills Project at my company

Unfulfilled programmers Erich Fromm, a famous humanist, philosopher and psychologist strongly believed that people are basically good. If he was right, then either our society is a mind-breaking dystopia or we have a great misfortune of working i... Unfulfilled programmers Erich Fromm, a famous humanist, philosopher and psychologist strongly believed that people are basically good. If he was right, then either our society is a mind-breaking dystopia or we have a great misfortune of working i...

Simple trick to DRY your Grails controller

Grails controllers are not very DRY. It's easy to find duplicated code fragments in default generated controller. Take a look at code sample below. It is duplicated four times in show, edit, update and delete actions:

class BookController {
def show() {
def bookInstance = Book.get(params.id)
if (!bookInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])
redirect(action: "list")
return
}
[bookInstance: bookInstance]
}
}

Why is it duplicated?

There is a reason for that duplication, though. If you move this snippet to a method, it can redirect to "list" action, but it can't prevent controller from further execution. After you call redirect, response status changes to 302, but after method exits, controller still runs subsequent code.

Solution

At TouK we've implemented a simple trick to resolve that situation:

  1. wrap everything with a simple withStoppingOnRender method,
  2. whenever you want to render or redirect AND stop controller execution - throw EndRenderingException.

We call it Big Return - return from a method and return from a controller at once. Here is how it works:

class BookController {
def show(Long id) {
withStoppingOnRender {
Book bookInstance = Book.get(id)
validateInstanceExists(bookInstance)
[bookInstance: bookInstance]
}
}

protected Object withStoppingOnRender(Closure closure) {
try {
return closure.call()
} catch (EndRenderingException e) {}
}

private void validateInstanceExists(Book instance) {
if (!instance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])
redirect(action: "list")
throw new EndRenderingException()
}
}
}

class EndRenderingException extends RuntimeException {}

Example usage

For simple CRUD controllers, you can use this solution and create some BaseController class for your controllers. We use withStoppingOnRender in every controller so code doesn't look like a spaghetti, we follow DRY principle and code is self-documented. Win-win-win! Here is a more complex example:

class DealerController {
@Transactional
def update() {
withStoppingOnRender {
Dealer dealerInstance = Dealer.get(params.id)
validateInstanceExists(dealerInstance)
validateAccountInExternalService(dealerInstance)
checkIfInstanceWasConcurrentlyModified(dealerInstance, params.version)
dealerInstance.properties = params
saveUpdatedInstance(dealerInstance)
redirectToAfterUpdate(dealerInstance)
}
}
}

Private fields and methods are not private in groovy

I used to code in Java before I met groovy. Like most of you, groovy attracted me with many enhancements. This was to my surprise to discover that method visibility in groovy is handled different than Java!

Consider this example:

class Person {
private String name
public String surname

private Person() {}

private String signature() { "${name?.substring(0, 1)}. $surname" }

public String toString() { "I am $name $surname" }
}

How is this class interpreted with Java?

  1. Person has private constructor that cannot be accessed
  2. Field "name" is private and cannot be accessed
  3. Method signature() is private and cannot be accessed

Let's see how groovy interpretes Person:

public static void main(String[] args) {
def person = new Person() // constructor is private - compilation error in Java
println(person.toString())

person.@name = 'Mike' // access name field directly - compilation error in Java
println(person.toString())

person.name = 'John' // there is a setter generated by groovy
println(person.toString())

person.@surname = 'Foo' // access surname field directly
println(person.toString())

person.surname = 'Bar' // access auto-generated setter
println(person.toString())

println(person.signature()) // call private method - compilation error in Java
}

I was really astonished by its output:

I am null null
I am Mike null
I am John null
I am John Foo
I am John Bar
J. Bar

As you can see, groovy does not follow visibility directives at all! It treats them as non-existing. Code compiles and executes fine. It's contrary to Java. In Java this code has several errors, pointed out in comments.

I've searched a bit on this topic and it seems that this behaviour is known since version 1.1 and there is a bug report on that: http://jira.codehaus.org/browse/GROOVY-1875. It is not resolved even with groovy 2 release. As Tim Yates mentioned in this Stackoverflow question: "It's not clear if it is a bug or by design". Groovy treats visibility keywords as a hint for a programmer.

I need to keep that lesson in mind next time I want to make some field or method private!