Nifty Gui The Manual 1.3.2

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 117

DownloadNifty-gui-the-manual-1.3.2
Open PDF In BrowserView PDF
NIFTY GUI
1.3.2
0

The Missing Manual

Book Credits
Authors
Jens Hohmuth (void)
Martin Karing (mkaring)
(Slick2D chapter)
Wesley Shillingford (wezrule)
(Grammar and spelling changes)

2

Documentversion
Version

Release

Author

Changes

1.0

28.12.2011

Jens Hohmuth (void)

Initial Version

1.1

12.11.2012

Jens Hohmuth (void)

Update for Nifty 1.3.2

3

1.Introduction

10

2.Basics

11

Required Files

11

Additional Files

11

Nifty Service Provider Interface (SPI)

12

Initialize Nifty

13

Render and Update

14

Elements Introduction

14

Get Nifty Version String (Nifty 1.3.2)

15

3.GUI Definition

16

XML GUI

16

Introduction

16

Loading XML

16

Validating XML

17

Special XML Markup

19

Localization

20

JAVA GUI

21

Introduction

21

JAVA Creator Classes

21

JAVA Builder Classes

23

4.Elements

26

Screen

26

What is a Screen?

26

Screen Controller

26
4

Default Focus Element

28

Screen Level Keyboard Events

28

Layer

29

Panel

30

Text

31

Color Encoded Text

32

Additional Text Properties

32

Image

36

General Properties

36

ImageMode Property

37

Common Element Attributes

40

Popup Layers

42

Introduction

42

Define Popup Layers

43

Create Popup Instance

44

Display Popup Instance

44

Close and remove a Popup

44

5.Layout

45

Introduction

45

Vertical Layout

47

Horizontal Layout

51

Center Layout

54

Absolute Layout

57

Clipping

58

Absolute Inside

60
5

Overlay Layout

62

Padding

63

Example for Vertical Layout Padding

63

Example for Horizontal Layout Padding

64

Example for Center Layout Padding

65

Margin (Nifty 1.3.2)

66

Troubleshooting Layout

67

6.Basic Eventhandling

69

Introduction

69

Element Controllers

69

Mouse Events

69

Introduction

69

Call Methods with String Parameters

72

Mouse Coordinates for onClick and onClickMouseMoved

72

Additional Mouse Events

73

OnClickAlternateKey

73

Element Controller Example

74

Keyboard Events

76

Nifty Input Events and NiftyInputMapping

76

Screen Level Keyboard Events

77

Keyboard Events for individual Elements

78

Nifty Event Consuming and Disabling Event Processing (Nifty 1.3.2)

78

Disable event processing globally

78

Disable event processing for individual elements

78

7.Eventbus Eventhandling

80
6

Introduction

80

Subscribe for NiftyEvents

80

Using the @NiftyEventSubscriber annotation

81

Using the @NiftyEventSubscriber Annotation in any class

81

Subscribe directly for events without annotations

82

NiftyEvent Reference

83

Element based Events

83

Mouse based Events

83

Input Events

84

Standard Controls Events

84

General Mouse Event Processing Changes with Nifty 1.3.2

8.Effects

85

86

Introduction

86

Effect Events

88

Hover Effects

89

Manually Starting Effects

90

Effect Parameters

92

Dynamically change effect Parameter

93

Effects Reference

94

Custom Effects

94

9.Runtime Element Modification

96

Introduction

96

Access Elements

96

Request Element Properties

97
7

Modify Element Properties

98

Modify Layout

98

Move Elements to another Parent

99

Remove Elements

99

Change Panel, Image and Text Properties

10.Nifty Styles

100

101

Principles

101

Overwrite Attributes

102

Organize Styles in Files

102

11.Controls

103

Basics

103

Standard Controls and Styles

103

Control Include

103

Control API

105

Control Events

107

Control Reference

107

Custom Controls

108

Control Definition

108

Control Parameters

110

Control Styles

111

12.Integration with other Systems

113

Integration with jme3

113

Integration with slick2d

113

Basic Setup

113
8

Resource Loading API

114

Input forwarding

114

13.Reference

116

9

INTRODUCTION
Nifty GUI is a Java library to create interactive user interfaces. It is well integrated into many
existing rendering systems (JME3, JME2, LWJGL, JOGL, Slick2D and even Java2D). If necessary it
can be easily integrated into other rendering systems by implementing a simple Service Provider
Interface (SPI).
The actual GUI is stored in XML files (using a custom XSD) or it can be created directly from Java.
Java is used to respond to events generated by the GUI and to modify the GUI to reflect changes in
the state of your application, changing a text label for example. Additionally there is a large set of
effects available that can be used to modify the appearance of the GUI. Effects add the "nifty" part
to Nifty GUI :)
Besides many standard controls like buttons, textfields, scrollbars and so on Nifty provides a lot of
freedom and it can be used to create in-game HUD like displays as well. GUIs written with Nifty
can be more visual stunning and exciting of what you‘d usually expect from a Java GUI system.
Here are some screenshots from the Nifty example projects:

This manual will give you an in-depth view on how Nifty works and how you can use it in your own
applications.

10

BASICS
REQUIRED FILES
Since Nifty can be integrated into several different rendering systems there exists quite a number of
adapter jars besides the Nifty core module (one for each rendering system). Usually you won‘t need
all of them and only the one for the rendering system you‘d like to use.
At the very minimum Nifty consists of at least two Jar files:
1. The Nifty core module: nifty-.jar
2. A Nifty rendering system adapter: nifty--.jar
The following table lists all of the available renderer Jar files for Nifty.
System

jar File

Nifty LWJGL

nifty-lwjgl-renderer-1.3.jar

Nifty JME3

(Integrated into JME3)

Nifty JME2

not released yet for Nifty 1.3

Nifty Slick2D

nifty-slick-renderer-1.3.jar

Nifty JOGL

not released yet for Nifty 1.3

Nifty Java2D

not released yet for Nifty 1.3

With the Nifty Core Jar and a renderer Jar you can already create and use Nifty. But there are
additional Jars available.

ADDITIONAL FILES
There is a separate Jar that contains the Nifty standard controls („nifty-default-controls.jar“). This Jar provides standard GUI components like Button, Checkbox, ListBox and so
on.
Everything that this jar provides is based on the Nifty Core module. If you don‘t plan to use the
standard controls then this project can still be useful as a demonstration on how you can combine
the basic mechanism that Nifty provides into more complex controls.
The controls project is meant to be used together with an accompanying style file. We will get into
Nifty styles later in this book. For the moment you can see the „nifty-style-black-.jar“ as
the specification on how the controls will look like. To use the Nifty standard controls you‘ll need to
add both, the „nifty-default-controls-.jar“ and the „nifty-style-black-.jar“ to
your Java classpath.
Last but not least Nifty supports sound output for playing background music or sound effects. For
sound there are two additional Jar files available that use OpenAL (using LWJGL) „nifty-openalsoundsystem-.jar“ or Pauls Soundsystem „nifty-pauls-soundsystem-.jar“ for
sound output.
The following table lists all of the available additional Jars for reference.
11

Name

Jar File

Nifty Standard Controls

nifty-default-controls-.jar

Nifty Standard Controls Style

nifty-style-black-.jar

Nifty OpenAL Soundsystem (LWJGL)

nifty-openal-soundsystem-.jar

Nifty Pauls Soundsystem

nifty-pauls-soundsystem-.jar

NIFTY SERVICE PROVIDER INTERFACE (SPI)
Nifty provides a couple of Java Interfaces that you can implement to make Nifty use whatever
rendering system you want to use. This is called a Service Provider Interface (SPI). The SPI for Nifty
consists of RenderDevice-, SoundSystem- and InputSystem-Java Interfaces. Here is a schematic
view of all the individual components involved in Nifty.

The InputSystem is usually implemented together with a RenderDevice implementation. The next
image shows all of the already available implementations of the Nifty SPI.

12

INITIALIZE NIFTY
To access Nifty and use it you‘ll first need to instantiate the de.lessvoid.nifty.Nifty class. To do so
you‘ll need to call the constructor which looks like this:
public Nifty(
final RenderDevice newRenderDevice,
final SoundDevice newSoundDevice,
final InputSystem newInputSystem,
final TimeProvider newTimeProvider);

As you can see the Nifty constructor requires instances of the three subsystem implementations of
the SPI one for the RenderDevice, the SoundDevice and the InputSystem. Additionally it requires
a de.lessvoid.nifty.tools.TimeProvider instance. The TimeProvider is just a simple class for accessing
the current system time without scattering new Date() calls all over the system.
Currently most Nifty renderer Jars provide implementations for all three subsystems because they
often relate to each other. Usually all you need is the „nifty--renderer-.jar“ for
your rendering system in the Java classpath to access implementations for all subsystems.
Additionally Nifty provides Null implementations for all three Interfaces in the
de.lessvoid.nifty.nulldevice package that you can use if you don‘t require an implementation for one
of the subsystems. So for instance if you don‘t need any sound output in your GUI you can just use
de.lessvoid.nifty.nulldevice.NullSoundDevice as the SoundDevice parameter when constructing the
Nifty instance and Nifty will not output any sound.
EXAMPLE

Here is an example of creating Nifty using LWJGL and no sound output support.
LwjglInputSystem inputSystem = new LwjglInputSystem();
inputSystem.startup();
Nifty nifty = new Nifty(
new LwjglRenderDevice(),
new NullSoundDevice(),
inputSystem,
new TimeProvider());

Please note that most Nifty RenderDevice implementations assume that you have already initialized
the underlying rendering system before you create Nifty using the constructor. In the example using
LWJGL you‘ll need to initialize LWJGL before you can create the Nifty instance.
The reason is that Nifty is probably not the only part of your system that needs to render things. So
Nifty lets you decide when and how you setup your rendering system and it does not try to overtake
your whole system.
We‘ll take a look at rendering and updating Nifty next.

13

RENDER AND UPDATE
There are only two calls to Nifty necessary that you‘ll need to call regularly.
One of them is nifty.render() which will render the GUI in its current state on the screen. There is a
catch however. Nifty assumes that your rendering system is in a state that is appropriate for 2d
rendering and it is up to you to set it up. So in case of using LWJGL you‘ll need to enable 2d ortho
mode prior to calling nifty.render().
Nifty.render() takes a boolean as its only parameter. You set this parameter to true if you like to clear
the screen before rendering Nifty or you can set it to false if Nifty should draw the GUI without
clearing the screen because maybe you‘ve already did this on your own.
// get Nifty Version and output it to system.out
String niftyVersion = nifty.getVersion();
System.out.println(niftyVersion);

The second method you‘ll need to call is nifty.update(). This call will process input events and update
the internal GUI state. The method will return true if Nifty reaches a state that should end the GUI
processing or false if the GUI is still active and should be kept updating and rendering.
In case of using LWJGL calling Display.update() is still up to you. Here is some pseudocode for the
render loop using Nifty when using LWJGL.
// render and update Nifty
boolean done = false;
while (!done) {
// update Nifty
if (nifty.update()) {
done = true;
}
// render Nifty
nifty.render(true);
// render other stuff, call LWJGL Display.update() and so on
}

ELEMENTS INTRODUCTION
At it‘s core Nifty only supports a handful of elements. Nifty can display Text and Image elements as
well as Panels, which are just rectangular areas on the screen that can optionally be visible. Usually
Nifty Panels are invisible and are only used as containers for other elements to help in layout.
These three basic elements are organized or grouped into so called layers and one or more layers
are grouped into a screen. You can think of a Nifty screen as a form of reference for a certain state
of your GUI. There is a whole chapter dedicated to the elements and all of the attributes they
provide. For now it is only important to understand that Nifty really is only about the Panel, Text
and Image elements which you can position, display and interact with (click them, move them
around, change them and so on).
All of the basic elements can be combined into a Nifty control. You can see this as a form of
container for the basic elements and the combination of the elements can be used exactly like the
14

basic elements. A control can simply be a form of a template. If you need the exact same
combination of elements multiple times then you can simply group them, give them a name and
then reuse this combination multiple times.
Another way to see controls are the provided standard controls. There is a button control available
for instance that is a combination of a panel and a text but can be simply seen and used as a single
control, the „button“. There is a dedicated chapter for controls as well.
So to summarize Nifty is about the display and management of elements, where a element can be
one of the build-in elements (Panel, Text, Image) or it is a combination of these build-in elements in
the form of a control.

GET NIFTY VERSION STRING (NIFTY 1.3.2)
Starting with Nifty 1.3.2 the main Nifty instance has a new new getVersion() method that returns
the version of Nifty and the time of the Nifty build.
The result is a String like: „1.3.2 (2012-10-08 00:09:03)“.

15

GUI DEFINITION
XML GUI
INTRODUCTION
One way to define all the elements that make up your GUI is to use XML-Files. This is especially
useful to modify your GUI without the need to recompile any Java files. You just use the same code
and change only some XML files if you need to modify the GUI.
Nifty uses XML-Schema (XSD) to define what elements and attributes are possible. This way you
can use XML tools that can read the XSD information to enable things like auto completion and
syntax checks when writing XML files. Using XML and XSD allows third party tools like the Nifty
GUI editor in the jMonkeyEngine
0
SDK project to parse and „understand“ the GUI definition and
support you even more when designing your GUIs. However please note that currently not all
possible attributes are supported or constrained in the Nifty-XSD.
The correct XML namespace for the Nifty XSD is „http://nifty-gui.sourceforge.net/nifty-1.3.xsd“
and you can download the current XSD by using the namespace URL as well.
A valid Nifty XML file looks like the following example.





It specifies the namespace „xmlns“ attribute as well as the „schemaLocation“ for XML tools that
support the „schemaLocation“ attribute.
The next chapter will explain in detail what this „Nifty XML content“ is and how it works. For now
it‘s just important to understand that the XML file will define everything that your GUI needs to
display. How you can tell Nifty to actually load the XML file(s) is explained in the next section.

LOADING XML
To load a XML file you can use one of the fromXml() Methods the Nifty instance provides. There
are methods available to load a file directly from the filesystem using a filename or from an
InputStream. The methods allow you to specify a „screenId“ of the screen that should be started
after the XML has been loaded. You can find more informations about the concepts of a Nifty
screen in the next chapter.
Here are the standard methods to load a Nifty XML file.
// load Nifty XML file from a file or an InputStream
public void fromXml(String filename, String startScreen);
public void fromXml(String fileId, InputStream input, String startScreen);

16

When you use the method that takes an InputStream as a parameter you‘ll need to specify a „fileId“
for the InputStream. The „fileId“ is used to identify the loaded XML file in case Nifty needs to
decide if a given file has already been loaded. When using the filename method the filename itself
acts as the „fileId“.
Sometimes it is necessary to load a XML file but without starting a screen. There are two other
methods available to just load a Nifty XML file. Again, you can find more informations about the
concepts of a screen in the next chapter.
// only load file or InputStream but don‘t start any screen
public void fromXmlWithoutStartScreen(String filename);
public void fromXmlWithoutStartScreen(String fileId, InputStream input);

As you can see from the method signature the only difference is the missing „startScreen“
parameter.
There is an additional set of methods available that allow you to specify the ScreenControllers to
load. The next chapter will explain what a ScreenController is and why you might want to specify
them when loading a XML file.
// load from a file or InputStream with ScreenController instances
public void fromXml(String filename, String startScreen,
ScreenController ... controllers);
public void fromXml(String fileId, InputStream input, String startScreen,
ScreenController ... controllers);

All of these methods will remove any previously loaded screens and replace everything loaded with
the data from the new XML file. This means that everything you would like to display must be
defined in a single XML file.
If you have many screens or you want to keep them organized in separate files there are two
„addXml“ methods available that will just load an additional XML file. The content of the files are
simply added to whatever XML data has been loaded before.
// add the content of an XML file to the loaded data
public void addXml(String filename);
public void addXml(InputStream stream);

VALIDATING XML
Nifty supports validating of XML-Files using the XSD. This way you can ensure that a given XML
file is valid and does not contain any syntax errors.
XML validation is an optional step which means that all of the loadXml() and addXml() methods
don‘t check the XML. You‘ll need to call a special validateXml() method to check XMLs. This is
because validating XML files takes some time and if you are sure your XML files are valid (because
you‘ve written them using an XML editor that already validated the XML) validating them again
would just be a waste of time.
So if you‘re unsure if your XML is valid you can call validateXml() which looks like this:

17

public void validateXml(String filename) throws Exception;
public void validateXml(InputStream stream) throws Exception;

Both methods will simply return when the XML is valid or they will throw an Exception if
something is wrong with the XML. This check is always performed in respect to the XSD. The
Exception will point out what is wrong.
And now that you know how to load and validate XML files we'll continue with a complete Nifty
XML example!
EXAMPLE

The following XML is a minimal Nifty XML file to display „Hello World“ in the middle of the
screen. Again the details of what ,  and  mean is being explained in detail
in the next chapter.









And as the result we get a black background and a „Hello World!“ text label in the middle of the
screen:

18

Not too bad :)

SPECIAL XML MARKUP
Every attribute of every XML element can contain the special markup „${...}“ that gets replaced
with something else when the XML is loaded. The following values are supported with the „${...}“
syntax:
${id.key}
Lookup resource bundle with "id" and request "key" from it. This is explained in more detail below
in the Localization section.
${ENV.key}
Lookup "key" in all of the environment variables (System.getEnv()) and replace „${ENV.key}“ with
the value of the environment variable „key“.
${PROP.key}
Lookup "key" in the Nifty.setGlobalProperties(Properties) properties or if the properties are not set
use System.getProperties() to lookup "key".
${CALL.method()}
Call method() at the current ScreenController and replace the value that the method() returns.
When used in this way then „method()“ should return a String.
Here is an example. When we change the text in Hello Word example like so.


19

Then „${ENV.HOME}“ will be replaced by the content of your $HOME environment variable!
If the replacement could not be performed successfully then nothing is being replaced and you’ll get
the original „${…}“ String back.

LOCALIZATION
Nifty localization is using standard property file based Java Resourcebundles. This simply means
that you‘ll need to create a property file containing keys that are referenced from Nifty XML using
the current locale settings of the VM.
Let‘s suppose you have the following files:
dialog.properties:
hello = Hello World in Default Language
dialog_de.properties:
hello = Hallo Welt in Deutsch
dialog_en.properties:
hello = hello world in english
Once you have created these files you'll need to tell Nifty where it can find them. You‘ll do that with
the  XML tag. You‘ll need to give the resourceBundle a name using the id
property so that we can later reference this specific resourceBundle (you can have multiple different
ones).


Now that Nifty knows about your ResourceBundle you can access it with the „${id.key}“ XML
markup. Here is an example to access the „hello“ key in the „dialog“ ResourceBundle we have just
registered using the  tag.


Now Nifty will use the current default locale to access the ResourceBundle with the id "dialog" and
looks up the value for "hello".
If for some reason you don’t want Nifty to use the default Locale you can force a specific one with
the "nifty.setLocale(Locale)" method.

20

JAVA GUI
INTRODUCTION
XML is not the only way you can use to define Nifty GUIs. It is possible to create elements directly
from Java. This is necessary when you need to create elements at runtime or when you don‘t want to
be dependent on XML files at all. Everything you can do with XML is possible with Java as well.
Nifty offers two slightly different mechanism to create elements from Java and this chapter will
explain both ways. What way you use is up to you in the end.

JAVA CREATOR CLASSES
This is the old way of creating elements in Nifty. For every standard element there exists a *Creator
class that has simple getter and setter methods to set the attributes of the element. To actually create
a new element you call the create method of the *Creator classes.
EXAMPLE

Here is an example to create a new panel in the layer with the id „baseLayer“.
To create a new element Nifty needs the Nifty instance, the screen and the parent element of the
new element. The new element will be added as a new child element to the given parent element.
For this example we assume that you have the following Nifty XML and that you want to create a
new panel inside the empty „baseLayer“ layer.









So there is this empty layer with id=“baseLayer“. To actually create a new element inside of that
layer, we‘ll first need the screen instance and the layer element. We can get both from the Nifty
instance.
Please note that there is a dedicated chapter „Runtime Element Modification“ that explains how to
access the screen, elements and a lot more in detail.
So this is the code to get the screen and the layer element:
Screen screen = nifty.getCurrentScreen();
Element layer = screen.findElementByName("baseLayer");

When we have both we can finally create the new panel using a PanelCreator instance:

21

// create a 8px height red panel
PanelCreator createPanel = new PanelCreator();
createPanel.setHeight("8px");
createPanel.setBackgroundColor("#f00f");
Element newPanel = createPanel.create(nifty, screen, layer);

And Nifty will create the element and we end up with this as the result:

Please note that the create() method returns the new element. This can be used as the parent
element of other *Creator calls. This way you can build a whole screen with all layers and elements
if necessary.
You can find all build-in *Creator classes in the de.lessvoid.nifty.controls.dynamic package. Here is a
reference of all the available *Creator classes:
Classname

Purpose

CustomControlCreator

Create a new control instance. This is the same
as the  tag in XML.

ImageCreator

Create a new image element.

LayerCreator

Create a new layer. Please note that you have to
use screen.getRootElement() as the parent
element when you call create() in this case.

PanelCreator

Create a new panel.
22

Classname

Purpose

PopupCreator

Create a popup element. Please note that you‘ll
need to call registerPopup() instead of build()
for the PopupCreator since you can only
register new popups with Nifty instead of
creating them directly. Popups have their own
chapter in this book as well.

ScreenCreator

Create a new screen. Please note that the
create() method of the Screen only requires the
Nifty instance.

TextCreator

Create a new text element.

Besides the build-in *Creator classes the standard controls project introduces special classes for each
of the standard controls that allows you to create them. You can find these classes in the
de.lessvoid.nifty.controls..builder package.
Please note that they are called CreateControl. Besides their name they work the
same as the core *Creator classes.

JAVA BUILDER CLASSES
The Java Builder way to create elements works similar to the Creator classes but provides a
somewhat nicer API. The trick is that the *Builder classes are designed in a way that feels more like
a DSL (Domain Specific Language) for Nifty instead of a regular class. This is achieved by nesting
anonymous inner classes with an initialize block.
Here is a short reminder what an initialize block is:
public class Stuff {
{
// you can do things in here to initialize this class
}
}

And here is an anonymous inner class:
void someMethod() {
new Stuff() {
// define methods here and Java will create an anonymous inner class for it
};
}

The Nifty Java Builders combine both so that we can create elements very easily.
EXAMPLE

Here is the panel we‘ve seen before with the *Creator classes in the Java Builder version.
We‘d like to add a new panel to the empty layer in the XML from above.

23

new PanelBuilder() {{
height("8px");
backgroundColor("#f00f");
}}.build(nifty, screen, layer);

So besides the duplicate {{ and }} this looks almost the same as the *Creator version but it is quite a
bit shorter.
But the really interesting things are happening when we nest the Builders.
So in the next example we create the whole screen, with a layer and the panel using only Java
Builders.
EXAMPLE

Create a complete screen with Java Builders only.
Screen screen = new ScreenBuilder("start") {{
layer(new LayerBuilder("baseLayer") {{
childLayoutCenter();
panel(new PanelBuilder() {{
height("8px");
backgroundColor("#f00f");
}});
}});
}}.build(nifty);

And that‘s a very compact way to create a Nifty GUI!
You can find all the Builder classes in the de.lessvoid.nifty.builder package. Here is an overview of
what you can find in that package:
Classname

Purpose

ControlBuilder

Create a new control instance. This is the same
as the  tag in XML.

ControlDefinitionBuilder

Define a new control. This is the same as the
 tag.

EffectBuilder

Create a new effect. You can use this with the
on() methods of any Builder class.

HoverEffectBuilder

Create a new hover effect. You can use this
with the onHover() method of all Builders that
support onHover()

ImageBuilder

Create a new image. Use this with the image()
method.

LayerBuilder

Create a new layer. Use this with the layer()
method.

24

Classname

Purpose

PanelBuilder

Create a new panel. Can be used with the
panel() method.

PopupBuilder

The PopupBuilder is used to register a new
popup with Nifty (see the chapter about popups
for an example)

ScreenBuilder

The ScreenBuilder adds a new screen to a Nifty
instance.

StyleBuilder

Register a new style with Nifty using the
StyleBuilder. This is the same as the XML


As always we can do the same using the Java Builder pattern.
new StyleBuilder() {{
id("redBackgroundCaption");
backgroundColor("#8fff");
}}.build(nifty);

So, that‘s it basically. We can define any attribute we‘d like to apply to other elements later and give
the style definition the name „redBackgroundCaption“ so that we can later reference this exact style.
With the style definition in place we can rewrite our original example to use this style.



101

Nifty will now apply the attributes from the style definition to the text elements.
And we are now able to simply change the style definition and all of the elements where this style is
applied will automatically update accordingly. Besides the benefit of reducing duplication this makes
the GUI definition simpler, easier to read and easier to maintain as well.

OVERWRITE ATTRIBUTES
If required you can overwrite any attribute that has been defined by a style by directly applying the
attribute directly at the element. This allows you to use a base style for your elements and if
required you can use a different value for some of the attributes.
Nifty will apply all of the attributes of the style definition first and all of the attributes that you‘ve
specified last.



In this examples the second text element will use a different font although the
„redBackgroundCaption" style is still being applied.

ORGANIZE STYLES IN FILES
To better organize your style definitions you can put them in a separate XML file and include it into
your actual XML with the  element.
Here is an example Nifty style XML file „styles.xml“.







To include a Nifty style XML file you can use the  element in XML.



Or you can call the method „loadStyleFile“ on the Nifty instance:
nifty.loadStyleFile("styles.xml");

Style files are a great way to switch the look and feel of your GUI. If you put the visual appearance
of your GUI in a Nifty style file you can change the look by simply using a different  file.
102

CONTROLS
BASICS
The basic building blocks of a Nifty GUI are the core elements: panel, image and text. Building
GUIs out of those elements is possible but it's not very practicable. What we want to use instead are
abstractions, like buttons, input fields, scrollbars and so on.
The Nifty GUI way to do that are controls. A Nifty GUI control is the combination of multiple
panels, images and texts that together form a component. The component (control) is defined once
and then it is used multiple times. You can see a control as some form of template as well. Nifty
controls can be defined in XML or from Java using the JavaBuilder.
Before we dive into all of the details on how to create your own controls we‘ll first take a look on
how you can use the standard controls that Nifty provides.

STANDARD CONTROLS AND STYLES
CONTROL INCLUDE
Nifty provides a standard set of controls that you can simply use in your own GUIs. All you need to
do is to add „nifty-default-controls-.jar“ and the „nifty-style-black-.jar“ to your
Java classpath and then you use the  and the  tag to include both into
your XML.
EXAMPLE

Include the Nifty „default-default-controls.xml“ to use the standard controls and the „nifty-defaultstyles.xml“ to use the standard look‘n‘feel.






...

You‘ll need to include both, the styles and the control to access the standard controls. Without the
style file the controls don‘t know how they should look ;)
Of course you can do the same using Java only by calling two methods that the Nifty instance
provides:
// load default styles
nifty.loadStyleFile("nifty-default-styles.xml");
// load standard controls
nifty.loadControlFile("nifty-default-controls.xml");

Once you've included both XML files the standard controls are available.
103

EXAMPLE

You can insert a control into your GUI with the  Tag. Here is an example to use the
standard textfield control in a Nifty GUI XML.














Which will give us a simple textfield centered in the middle of the screen which is 200px width and
contains the initial text of „hello textfield“:

As you see you can use the  tag in the same way as you would use any other Nifty element
(panel, image, text).
104

Using the Java Builder we can get the same result when we use the following Java source:
// create screen
new ScreenBuilder("start") {{
layer(new LayerBuilder("layer") {{
childLayoutCenter();
backgroundColor("#003f");
control(new TextFieldBuilder("input", "hello textfield") {{
width("200px");
}});
}});
}}.build(nifty);
// tell Nifty that it should show the „start“ screen
nifty.gotoScreen("start");

For all of the standard controls there are specific Java Builders that you can use to create a control.
In the example above there is the TextFieldBuilder being used to create the textfield control. The
specific Java Builders have the advantage that they are designed for a specific control and therefore
expose special methods to use.

CONTROL API
Creating a control and adding it to your GUI is great but a control only makes sense when we can
interact with it and in the case of the textfield actually get the text that the user provides or the
control is useless.
To do this all of the standard controls provide an API to access the controls functions. In case of the
textfield the API is the interface de.lessvoid.nifty.controls.TextField and you can access it using the
findNiftyControl() method of the screen.
EXAMPLE

Access the TextField control API interface using the findNiftyControl() method of the screen class:
TextField textField = screen.findNiftyControl("input", TextField.class);

For a better understanding of what that means, here is the actual TextField interface that you get
back.

105

public interface TextField extends NiftyControl {
/**
* Get the current TextField text.
* @return text
*/
String getText();
/**
* Set the Text of the TextField.
* @param text new text
*/
void setText(String text);
/**
* Change the max. input length to a new length.
* @param maxLength max length
*/
void setMaxLength(int maxLength);
/**
* Set the cursor position to the given index.
* @param position new cursor position
*/
void setCursorPosition(int position);
/**
* Enable a password character that is displayed instead of the actual text.
* @param passwordChar character to use, like '*'
*/
void enablePasswordChar(final char passwordChar);
/**
* Disable the password character which displays the text again,
*/
void disablePasswordChar();
/**
* Checks if a password character is currently enabled.
* @return true if password character is enabled and false if not.
*/
boolean isPasswordCharEnabled();
}

So once you‘ve the TextField interface you can call it‘s methods.
EXAMPLE

Get the text of a textfield using the TextField interface API.
TextField textField = screen.findNiftyControl("input", TextField.class);
String text = textField.getText();

There exists similar interfaces for the other standard controls.

106

CONTROL EVENTS
Some of the controls support EventBus notifications when interesting things happen to the control.
The textfield control generates an event whenever the text of the textfield changes.
EXAMPLE

Subscribe for the TextFieldChangedEvent to listen for any text change events.
@NiftyEventSubscriber(id="input")
public void onTextfieldChange(final String id, final TextFieldChangedEvent event) {
System.out.println(event.getText());
}

There exists similar events for the other standard controls as well.

CONTROL REFERENCE
You can find a reference of all standard controls online in the Nifty wiki.
http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Nifty_Standard_Controls_
%28Nifty_1.3%29

107

CUSTOM CONTROLS
CONTROL DEFINITION
Creating your own Nifty controls is not complicated. Let's see next how you can do that.
EXAMPLE

Control definition for a simple button control.






So basically that's a control definition in Nifty XML. We'll look at all the little details in a moment
but first here is the same control definition using the Java Builder pattern:
new ControlDefinitionBuilder("button") {{
controller("de.lessvoid.nifty.controls.button.ButtonControl");
inputMapping("de.lessvoid.nifty.input.mapping.MenuInputMapping");
style("nifty-button");
panel(new PanelBuilder() {{
style("#panel");
focusable(true);
text(new TextBuilder("#text") {{
style("#text");
text(controlParameter("label"));
}});
}});
}}.registerControlDefintion(nifty);

And now let‘s take a look at the details.
With the name attribute you can obviously name your control and if you later want to use the
control you can select the control with its name.
With the control definition in place we can use the control with the  tag using „button“ as
the name and this will work the same as with the name=“textfield“ before.
EXAMPLE

Use the newly defined button control using the  Tag.


Using the newly defined button control using the Java Builder pattern:

108

control(new ControlBuilder("theButton", "button") {{
parameter("label", "OK");
}});

When Nifty parses a Nifty XML file and it finds a control, it looks up a matching control definition
using the control name. If a corresponding control definition is found the content of the control
definition actually replaces the control tag. So all the panels, images and text elements that make up
the control definition are inserted into the element tree at the position of the control. If you look at
it in this way you can imagine controls as a form of a template.
Like screens it is possible to attach a controller class to a control. This works exactly the same as with
screens, whenever something happens the controller is the first address that is called.
When resolving all of the GUI elements Nifty keeps track of the current controller class. The
controller of a control is a Java class that gets all the events of the control. So let's say that we have a
onClick() event on any element inside the control definition that event will not travel immediately to
the screen controller but to the controller of the control. So this way you have a Java class
representing the control and that gets all the events. This is an important mechanism to get controls
working.

109

So to wrap that part up here is the Controller interface all Control classes need to implement:
public interface Controller {
/**
* Bind this Controller to a certain element.
* @param nifty nifty
* @param element the Element
* @param parameter parameters from the xml source to init the controller
* @param listener the ControllerEventListener
*/
void bind(
Nifty nifty,
Screen screen,
Element element,
Properties parameter,
Attributes controlDefinitionAttributes);
/**
* Init the Controller. You can assume that bind() has been called for all other
controls on the screen.
* @param parameter
* @param controlDefinitionAttributes
*/
void init(Properties parameter, Attributes controlDefinitionAttributes);
/**
* Called when the screen is started.
*/
void onStartScreen();
/**
* This controller gets the focus.
* @param getFocus get focus (true) or loose focus (false)
*/
void onFocus(boolean getFocus);
/**
* input event.
* @param inputEvent the NiftyInputEvent to process
* @return true, the event has been handled and false, the event has not been
handled
*/
boolean inputEvent(NiftyInputEvent inputEvent);
}

You‘ll implement this interface and register it with the controlDefinition with the controller
attribute.
You can put several of your own control definitions into a XML file and include it the same way as
we've included the nifty default controls or you can define the control definitions directly in your
Nifty XML.

CONTROL PARAMETERS
In the case of the button example we don't want all of our buttons to have the same label. So we
need a way to customize the control.
110

The way this works is that we can override some attributes when we actual use the control. Maybe
you remember this strange syntax in the button example:






If a attribute value inside of the control definition begins with the "$" character you can later set
this value by using the value after the „$“ character as another attribute. You can think of the „$“
character as a way of introducing a new attribute for your control!
Assigning a value to this new attribute when you use the control will replace the value in the control
definition. This works not only for text attributes but for all attributes of all elements!
EXAMPLE

The „label“ attribute of the button control is set to the value „OK“.


The same works when using the Java Builder:
control(new ControlBuilder("theButton", "button") {{
parameter("label", "OK");
}});

Please note the syntax: The method to set control parameters is called „parameter“ and you‘ll need
to specify the attribute you want as the first parameter and the value as the second parameter.

CONTROL STYLES
The last piece of information that is missing are control styles. When you define your control with
the control definition tag you are free to apply any style to the elements that your control uses. This
works the same as we've seen before and you can just add a style attribute to the elements.
However there is one problem. When we use the control, let's say the button control, the style of the
button will always be fixed. If, for instance, the button is defined as a red button then this button will
always be applied in red and you always get a red button. This might be ok but what we really want
is a control style. If I use the button and apply a different style, let's say the green button style, I
want to use the same control but with the green button style applied.
And actually you can!
If you take a look at the control definition we've shown before, you've noticed two things:
1. The control definition itself has a style attribute and
2. the elements that make up the control use strange style names that begin with a # character.
The style attribute for the control definition is the default style that Nifty applies when you actually
use the control. So if you don't set any other style when you use the control then Nifty will simply
use the style that was given in the control definition tag.
111

Style names inside a control definition that start with a # character are called "sub styles". When
Nifty resolves styles it combines the style name of the control definition ("nifty-button") and the style
at the element inside the control ("#panel") to build a final style name ("nifty-button#panel"). And
this allows us to define the style for the sub style too.
EXAMPLE

This is a sub style for the panel inside of the nifty-button style.


So using a control and not setting a style attribute will fall back to the style that was set in the control
definition.
All the elements that have a sub style attached will get resolved using the combination of the style of
the control definition and the sub style that was attached to the element. Nifty will resolve all of the
sub styles and apply the attributes to the elements as we've seen before.
But this allows us to create a complete new style for a control. All we need to do is to create styles
that consists of our name for the base style, e.g. "green-button" and the sub style given in the control
definition, e.g. "#panel". So we simply define a style: "green-button#panel". When we later use this
style on the control tag we can simply use our new style "green-button".
You can use the existing styles (and sub styles) as the base for your own styles. You only need to make
sure that you‘ll define all sub styles of the control.
You can even change styles dynamically from Java using element.setStyle(). However there is one
catch: Changing sub styles is not supported at runtime currently. So you can only apply the „greenbutton“ style when you create the button but not change a „red-button“ style to a „green-button“
style at runtime.
(You could change the style at runtime but only when this style does not have sub styles applied).

112

INTEGRATION WITH OTHER SYSTEMS
INTEGRATION WITH JME3
This topic is covered in detail on the jMonkeyEngine3 wiki that you can find online at http://
jmonkeyengine.org/wiki/doku.php/jme3:advanced:nifty_gui.

INTEGRATION WITH SLICK2D
The Nifty Slick2D Renderer is the binding between Nifty GUI and Slick2D in matters of graphic,
user input and sound.

BASIC SETUP
The Slick2D renderer provides access to Nifty GUI by extending the
org.newdawn.slick.Game,
org.newdawn.slick.BasicGame,
org.newdawn.slick.state.GameState and
org.newdawn.slick.state.BasicGameState
of Slick2D. Each class or interface is implemented twice. One overlay type and one pure Nifty GUI
type.
The overlay type of the classes are meant to display Nifty GUI as overlay over graphics rendered
outside of Nifty GUI. The pure Nifty GUI classes are meant to display only the Nifty GUI on the
screen.
Each of the implementations have at least one abstract method that you‘ll need to implement.
protected abstract void prepareNifty(Nifty nifty, StateBasedGame game);
protected abstract void prepareNifty(Nifty nifty);

It‘s one of the two methods written above. The first one is for GameState based implementations
and the second one is for Game based implementations.
Inside this method you have to load the things the Nifty GUI is supposed to display. How you load
the GUI is up to you. Either build it inside this method or load a XML file.
When using the overlay classes you‘ll get a few more methods that you‘ll need to implement.
protected abstract void initGameAndGUI(GameContainer container)
throws SlickException;
protected abstract void initGameAndGUI(GameContainer container, StateBasedGame game)
throws SlickException;

These two methods are supposed to be used to initialize the Nifty instance and the game in case you
need it. Initializing the GUI is done by calling the initNifty functions that are provided by the super
classes. These functions have various implementations and it‘s possible to use whatever fits.
Preparing Nifty GUI is not supposed to be done in this function. As named before the prepareNifty()
functions are used for this.
113

The overlay classes now also add two more functions called updateGame() and renderGame(). Both
functions are respective used to handle the game unit. Using those functions ensures that Nifty
receives the update and render calls properly.
So Nifty GUI does not need to be updated or rendered by hand. The library handles this internally.

RESOURCE LOADING API
The resource loading API provides an easy way to add your own methods of loading resouces
(images/sounds/cursors/fonts) into the rendering environment. The basic loader storages can be
found in the package de.lessvoid.nifty.slick2d.loaders. There it is possible to register more loaders to
the Slick devices that are used to load resources.
There are already some implementations of these loaders that utilize most of the possibilities to load
the data.
There are:
• Font loaders: de.lessvoid.nifty.slick2d.render.font.loader
• Cursor loaders: de.lessvoid.nifty.slick2d.render.cursor.loader
• Image loaders: de.lessvoid.nifty.slick2d.render.image.loader
• Sound loaders: de.lessvoid.nifty.slick2d.sound.sound.loader
• Music loaders: de.lessvoid.nifty.slick2d.sound.music.loader
For example when writing a new loader to load images the class needs to implement the
de.lessvoid.nifty.slick2d.render.image.loader.SlickRenderImageLoader interface.
This class has to this class has to make sure to load this image or throw a
de.lessvoid.nifty.slick2d.render.image.SlickLoadImageException in case loading the image fails.
Then the class needs to be added to the loaders stored in
de.lessvoid.nifty.slick2d.loaders.SlickRenderImageLoaders. This loader list will try all registered
image loaders in order to load a resource and use the first one that does not throw a exception.
Those loaders are automatically utilised by the RenderDevice and SourceDevice implementations
that are provided by the Slick2D-Renderer.

INPUT FORWARDING
Especially for the cases where Nifty-GUI is used as overlay over another game is often required that
the game receives all the input event that were not handled by Nifty.
For this purpose there are a few implementations provided that take care for the input forwarding.
de.lessvoid.nifty.slick2d.input.PlainSlickInputSystem
Receives the input events from Slick and forwards them to the Nifty-GUI. All events not handled by
the Nifty-GUI are discarded. In case your application is just supposed to display the Nifty-GUI, this
one is the best choice.
de.lessvoid.nifty.slick2d.input.NiftySlickInputSystem
Receives the input events from Slick and forwards them to the Nifty-GUI. All events not handled by
the Nifty-GUI are forwarded to a de.lessvoid.nifty.NiftyInputConsumer.

114

de.lessvoid.nifty.slick2d.input.SlickSlickInputSystem
Receives the input events from Slick and forwards them to the Nifty-GUI. All events not handled by
the Nifty-GUI are forwarded to a org.newdawn.slick.InputListener
So in case you implement a listener of one of the two libraries, the required implementations are
available. In case you want to write your own input system you should consider using
de.lessvoid.nifty.slick2d.input.AbstractSlickInputSystem. This class already implements the required
logic to forward to the Nifty-GUI and sends all events not handled by the Nifty-GUI to the abstract
function handleInputEvent(...). Also this class takes care for handling events Nifty-GUI usually does
not need. Such as high-level events like dragging, (double-)clicking, and so on.

115

REFERENCE
You can find additional informations online here.
Resource

URL

Project Page

http://sourceforge.net/projects/nifty-gui/

Ohloh.net

http://www.ohloh.net/p/nifty-gui

Wiki

http://sourceforge.net/apps/mediawiki/nifty-gui/index.php?title=Main_Page

Blog

http://nifty-gui.lessvoid.com/

Twitter

http://twitter.com/#!/niftygui

Github

https://github.com/void256/nifty-gui

116

The End

117



Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
Linearized                      : No
Page Count                      : 117
PDF Version                     : 1.4
Title                           : nifty-gui-the-manual-1.3.2
Author                          : Jens Hohmuth
Producer                        : Mac OS X 10.8.2 Quartz PDFContext
Creator                         : Pages
Create Date                     : 2012:11:12 22:00:03Z
Modify Date                     : 2012:11:12 22:00:03Z
EXIF Metadata provided by EXIF.tools

Navigation menu