1. Introduction
Themes may be switched at any time based on two conditions:
-
a valid value for
ThemeManager.currentTheme
is set -
the application’s Locale is updated
The following controller shows 4 actions showing how to trigger each one of
these conditions. The application assumes there are two themes named red
and
blue
and that there are locale aware versions of these themes for English and
Spanish
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import griffon.core.artifact.GriffonController
import griffon.metadata.ArtifactProviderFor
import griffon.plugins.theme.ThemeManager
import javax.inject.Inject
@ArtifactProviderFor(GriffonController)
class SampleController {
@Inject
private ThemeManager themeManager
void red(evt) { themeManager.currentTheme = 'red' }
void blue(evt) { themeManager.currentTheme = 'blue' }
void spanish(evt) { application.localeAsString = 'es' }
void english(evt) { application.localeAsString = 'en' }
}
Classes that should participate in theme injection must be anotated with
@griffon.plugins.theme.ThemeAware
and have their properties anotated with @InjectedResource
,
for example
1
2
3
4
5
6
7
8
9
10
11
12
import griffon.core.artifact.GriffonModel
import griffon.metadata.ArtifactProviderFor
import java.awt.Color
import griffon.transform.Observable
import griffon.core.resources.InjectedResource
@griffon.plugins.theme.ThemeAware
@ArtifactProviderFor(GriffonModel)
class SampleModel {
@Observable @InjectedResource Color color
@Observable @InjectedResource String message
}
The resource injection mechanism relies on application events in order to handle
injections on instances. All griffon artifacts trigger an event upon creation
(NewInstance
) and destruction (DestroyInstance
). Non griffon artifact
instances can still participate in resource injection as long their classes
are bound within a Module
.
Marking bean properties as observable makes it easier for the application to
update itself when a theme change occurs. For example, a View may use the
color
and message
model properties in this way
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package org.example
import griffon.core.artifact.GriffonView
import griffon.metadata.ArtifactProviderFor
import javax.swing.SwingConstants
@ArtifactProviderFor(GriffonView)
class SampleView {
FactoryBuilderSupport builder
SampleModel model
void initUI() {
builder.with {
application(title: 'Themes',
preferredSize: [320, 240], pack: true,
locationByPlatform: true) {
borderLayout()
label(text: bind { model.message },
foreground: bind { model.color },
constraints: CENTER)
panel(constraints: WEST) {
gridLayout(cols: 1, rows: 4)
button(redAction)
button(blueAction)
button(spanishAction)
button(englishAction)
}
}
}
}
}
It’s worth noting that if a resource cannot be resolved by a theme then the
default application resources will be searched until the resource can be
resolved or a NoSuchResourceException
is thrown.
1.1. Configuration
Theme files look exactly the same as resources files. For the example shown above, the application expects the following files to exist
-
griffon-app/i18n/red.properties
-
griffon-app/i18n/red_es.properties
-
griffon-app/i18n/blue.properties
-
griffon-app/i18n/blue_es.properties
These themes must be registered using a Module, for example
bind(ResourceResolver.class)
.withClassifier(named("red"))
.toProvider(new ResourceResolverProvider("red"))
.asSingleton();
bind(ResourceResolver.class)
.withClassifier(named("blue"))
.toProvider(new ResourceResolverProvider("blue"))
.asSingleton();
Griffon version: 2.12.0
2. Build Configuration
2.1. Gradle
You have two options for configuring this plugin: automatic and manual.
2.1.1. Automatic
As long as the project has the org.codehaus.griffon.griffon
plugin applied to it you
may include the following snippet in build.gradle
dependencies {
griffon 'org.codehaus.griffon.plugins:griffon-theme-plugin:2.1.0'
}
The griffon
plugin will take care of the rest given its configuration.
2.2. Maven
First configure the griffon-theme-plugin
BOM in your POM file, by placing the following
snippet before the <build>
element
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.codehaus.griffon.plugins</groupId>
<artifactId>griffon-theme-plugin</artifactId>
<version>2.1.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Next configure dependencies as required by your particular setup
<dependency>
<groupId>org.codehaus.griffon.plugins</groupId>
<artifactId>griffon-theme-core</artifactId>
</dependency>
3. Modules
The following sections display all bindings per module. Use this information to successfully override a binding on your own modules or to troubleshoot a module binding if the wrong type has been applied by the Griffon runtime.