DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

  1. DZone
  2. Refcards
  3. GWT Style, Configuration and JSNI Reference
refcard cover
Refcard #001

GWT Style, Configuration and JSNI Reference

Using the Google Web Toolkit

Introduces Ajax, a group interrelated techniques used in client-side web development for creating asynchronous web applications.

Download Refcard
Free PDF for Easy Reference
refcard cover

Written By

author avatar Robert Hansen
Sr. Software Eng., CuriousBob
Table of Contents
► About Google Web Toolkit (GWT) ► Official GWT Web Sites ► Styling Widgets with CSS ► GWT Model Configuration ► JavaScript Native Interface
Section 1

About Google Web Toolkit (GWT)

By Robert Hanson

The Google Web Toolkit is a set of tools for writing JavaScript applications in Java. The cornerstone of the tool suite is a Java to JavaScript compiler that can not only compile Java down to JavaScript, but can also compress and optimize your code as well. GWT was released to the public in June of 2006 and has been an overwhelming success, boasting 1 million downloads in its first year.

The benefit of using GWT over some of the other JavaScript frameworks like JQuery or Ext-JS is the environment in which you code. GWT allows a Java developer to use the same tools they use today like Eclipse, Maven, and JUnit, making the transition from Java server-side development to GWT client-side development nearly seamless.

The GWT toolkit comes ready with its own widget library, internationalization tools, image bundling tools, tools for client-server communication, and many others. Since its launch GWT has become an open-source project, and although led by the GWT team at Google, many from the community have contributed patches to the toolkit. GWT boasts a thriving community, proving for a multitude of free widgets, integration tools, and utilities.

This reference card is a guide to everything that your IDE can't already tell you. Specifically, IDEs like Eclipse provide auto-completion capabilities for perusing a list of methods on an object, and often they also provide support for viewing javadocs in the IDE as well. This refcard is meant to supplement that capability by providing details that are only available in books and online documentation. Specifically this includes a CSS style for the widgets that ship with GWT, a reference for the JavaScript Native Interface, and a complete guide to the GWT module configuration file.

Section 2

Official GWT Web Sites

  • WebSite: http://code.google.com/webtoolkit/
  • Blog: http://googlewebtoolkit.blogspot.com/
  • Forum: http://groups.google.com/group/Google-Web-Toolkit
  • Issue Tracker: http://code.google.com/webtoolkit/issues/
  • Articles: http://code.google.com/webtoolkit/articles.html
  • Examples: http://code.google.com/webtoolkit/examples/
  • Dev Guide: http://code.google.com/webtoolkit/documentation/
Section 3

Styling Widgets with CSS

Styling widgets is done using Cascading Style Sheets (CSS). CSS can be applied to the widgets in the application three different ways.

Adding a style element inside the <head> of the HTML page that is hosting the application.

1
<style type='text/css'>
2
/* CSS style rules*/
3
</style>

Adding a <link> element to the <head> of the HTML page, referencing an external CSS stylesheet.

1
1
<link type="text/css' rel='stylesheet' href='url-to-file.css' />

Adding a <stylesheet> element to the GWT project's module configuration, causing the stylesheet to be injected into the host HTML page.

1
1
<stylesheet src='url-to-file.css'/>

Most of the widgets that come with GWT have been pre-assigned CSS class names. For example, the Button widget uses the CSS class name gwt-Button. So you could set the width of all Button widgets in your application by using the following CSS rule. In order to reference a CSS class in a CSS rule you prefix the class name with a period ".".

3
1
.gwt-Button {
2
        width: 100px;
3
}

Altering Style Names

You can programmatically alter the CSS class name used on a widget by calling any of these methods.

widget.setStylePrimaryName("styleName")

In HTML you may provide any number of CSS class names on an element by separating them with spaces, like in the HTML snippet below.

1
1
<div class="style1 style2 style3"></div>

The primary style name in GWT is defined as the first style name in the class attribute. In the example provided, this would be the style "style1". Calling setStylePrimaryName() allows you to alter this first style.

widget.addStyleDependentName("styleName")

When you add a dependent style name, its name in the HTML is the primary name plus the depende nt name, separated with a dash ("-").

Example:

3
1
Button button = new Button();
2
button.setStylePrimaryName("foo");
3
button.addStyleDependentName("bar");

Result:

1
1
<BUTTON class="foo foo-bar"></BUTTON>

widget.setStyleName("styleName")

Using setStylename() will clear all current style names, including the primary style name, and adds the one provided.

widget.addStyleName("styleName")

Adds an additional style name to any existing style names.

Example

3
1
Button button = new Button();
2
button.setStyleName("foo");
3
button.addStyleName("bar");

Result:

1
1
<BUTTON class="foo bar"></BUTTON>

widget.removeStyleName("styleName")

Allows you to remove an existing style name on a widget.

Default GWT Widget Style Names

Most of the widgets provided by the GWT library have pre-defined primary style names. The following is a list of the default names for each widget.

Widget Default Name
Button
1
1
.gwt-Button { }
Checkbox
1
1
.gwt-CheckBox { }
DialogBox
3
1
.gwt-DialogBox { the box
2
container }
3
.gwt-DialogBox .Caption { the box caption }
DisclosurePanel
6
1
.gwt-DisclosurePanel { primary
2
style }
3
.gwt-DisclosurePanel-open { when open }
4
.gwt-DisclosurePanel-closed { when closed }
5
.header { the panel header area }
6
.content { the panel content area }
HorizontalSplitPanel
3
1
.gwt-HorizontalSplitPanel { the
2
panel }
3
.gwt-HorizontalSplitPanel hsplitter { splitter }
HTML
1
1
.gwt-HTML { }
Hyperlink
1
1
.gwt-Hyperlink { }
Image
1
1
.gwt-Image { }

Note: Transformations between clipped and upclipped will result in the loss of any CSS style names that were set or added.

Label
1
1
.gwt-Label { }
ListBox
1
1
.gwt-ListBox { }
MenuBar
5
1
.gwt-MenuBar { the menu bar
2
itself }
3
.gwt-MenuBar .gwt-MenuItem { menu items }
4
.gwt-MenuBar .gwt-MenuItem-selected { selected menu items
5
}
PasswordTextBox
4
1
.gwt-PasswordTextBox { primary
2
style }
3
.gwt-PasswordTextBox-readonly { dependent style set when the
4
password text box is read-only }
PushButton
7
1
.gwt-PushButton-up {}
2
.gwt-PushButton-down {}
3
.gwt-PushButton-up-hovering {}
4
.gwt-PushButton-down-hovering {}
5
.gwt-PushButton-up-disabled {}
6
.gwt-PushButton-down-disabled {}
7
<any of the above> .html-face {}
RadioButton
1
1
.gwt-RadioButton { }
RichTextArea
2
1
.gwt-RichTextArea {
2
}
StackPanel
5
1
.gwt-StackPanel { the panel
2
itself }
3
.gwt-StackPanel .gwt-StackPanelItem { unselected items }
4
.gwt-StackPanel .gwt-StackPanelItem-selected { selected items
5
}
SuggestBox
6
1
.gwt-SuggestBox { the suggest
2
box itself }
3
.gwt-SuggestBoxPopup { the suggestion popup }
4
.gwt-SuggestBoxPopup .item { an unselected suggestion }
5
.gwt-SuggestBoxPopup .item-selected { a selected suggestion
6
}
TabBar
7
1
.gwt-TabBar { the tab bar itself
2
}
3
.gwt-TabBar .gwt-TabBarFirst { the left edge of the bar }
4
.gwt-TabBar .gwt-TabBarRest { the right edge of the bar }
5
.gwt-TabBar .gwt-TabBarItem { unselected tabs }
6
.gwt-TabBar .gwt-TabBarItem-selected { additional style for
7
selected tabs }
TabPanel
4
1
.gwt-TabPanel { the tab panel
2
itself }
3
.gwt-TabPanelBottom { the bottom section of the tab panel (the deck
4
containing the widget) }
TextArea
4
1
.gwt-TextArea { primary style
2
}
3
.gwt-TextArea-readonly { dependent style set when the text area is
4
read-only }
TextBox
4
1
.gwt-TextBox { primary style
2
}
3
.gwt-TextBox-readonly { dependent style set when the text box is
4
read-only }
ToggleButton
7
1
.gwt- ToggleButton-up {}
2
.gwt- ToggleButton-down {}
3
.gwt- ToggleButton-up-hovering {}
4
.gwt- ToggleButton-down-hovering {}
5
.gwt- ToggleButton-up-disabled {}
6
gwt- ToggleButton-down-disabled {}
7
<any of the above> .html-face {}
Tree
5
1
.gwt-Tree { the tree itself
2
}
3
.gwt-Tree .gwt-TreeItem { a tree item }
4
.gwt-Tree .gwt-TreeItem-selected { a selected tree item
5
}
VerticalSplitPanel
3
1
.gwt-VerticalSplitPanel { the
2
panel itself }
3
.gwt-VerticalSplitPanel vsplitter { the splitter }
Section 4

GWT Model Configuration

A module in GWT is best described as a set of classes that are bound by a single module configuration file. The module configuration defines what classes are a part of the module, what other modules that the module depends on, as well as rules for deferred binding, resource injection, and everything else that the GWT compiler and shell needs to know about your module.

A module configuration file is located in the GWT project, with an extension of ".gwt.xml". The location on the classpath and the module configuration file name determine the full module name.

Module Name = Java Package + Module File Name (-gwt.xml)

For example, if you have a module configuration file named Demo.gwt.xml, in the java package com.gwtsandbox.demo, the module name would be com.gwtsandbox.demo.Demo.

Hot Tip

The module configuration is only used at design and compile-time, it is not used at run-time. This is a common mistake for new GWT developers.

Simple Module Configuration

A simple module configuration must inherit the User module and specify a single entry point. The entry point is the class that implements the EntryPoint interface and acts as the starting point for the application.

4
1
<module>
2
        <inherits name='com.google.gwt.user.User' />
3
        <entry-point class=’org.gwtsandbox.demo.client.Demo’ />
4
</module>

From the basic module configuration you can build on it by adding additional elements to inherit additional modules, change the default source path, add servlet mappings, and add deferred binding rules.

Inheriting Modules

If your GWT project needs to reference external GWT modules you must explicitly inherit them in your module configuration. The core GWT libraries are split into several modules, each of which is listed here. You will always need to include the User module, and optionally one or more of the others.

GWT widgets and core utilities


2
1
<inherits name="com.google.gwt.user.User"
2
/>


RequestBuilder and associated classes


2
1
<inherits name="com.google.gwt.http.HTTP"
2
/>


Internationalization tools and date/number formatting


2
1
<inherits name="com.google.gwt.i18n.I18N"
2
/>


Tools for using RPC with JavaScript Object Notation


2
1
<inherits name="com.google.gwt.json.JSON"
2
/>


XML parser and associated classes


2
1
<inherits name="com.google.gwt.xml.XML"
2
/>


Source Path

The source path is a relative path name used to override the default location of the client-side Java source destined to be compiled into JavaScript. The source path you specify is appended to the path where the module configuration file resides, and you may specify multiple source paths.

​x
1
​
2
<source path="path"/>
3
​
4
​

By default the source path is "client". So by way of example, if your GWT module configuration file is located at com.example.MyApp.gwt.xml, then the default path of "client" will dictate that your client-side Java source will be located in the Java package com.example.client.*, as well as all packages below this one.

All source code in the source path(s) must be able to be compiled to JavaScript with the GWT compiler. This implies that only classes from the JRE emulation library and GWT user library be used. For example, you can not include Java servlets or use the java.sql.* classes under this path.

Public Path

The public path is used to store non-Java files that need to be included in the application. This includes HTML files, JavaScript files, images, CSS, and anything else. By default this will be the "public" directory below where the module configuration is stored.

You can override the default by using the <public> tag in the module configuration.

4
1
​
2
<public path="path"/>
3
​
4
​

You may specify multiple public paths if required for your project.

Defining GWT-RPC Servlets

You can use the <servlet> tag in the module configuration to define your GWT-RPC servlets.

4
1
​
2
<servlet path="/path" class="org.gwtsandbox.demo.server.Demo" />
3
​
4
​

The path specified should be absolute.

Hot Tip

These servlet mappings are for the benefit of hosted-mode use only, and does not imply that these mappings will be carried over to your production environment. For that you would set them up in the deployment descriptor, just as you would with any other servlet.

Resource Injection

You can have external JavaScript and CSS files automatically injected into the hosting web page. By injecting the resources you avoid the need to have the hosting HTML page explicitly include them with %lt;link> and <script> tags. Resources loaded in this way will be loaded prior to the executing of the GWT application.

5
1
​
2
<script src="js-url"/>
3
<stylesheet src="css-url"/>
4
​
5
​

To inject a resource you can either place the JavaScript or CSS file into the public package of the GWT module (see above), referencing it with a relative path, or reference an external CSS file by using a full URL.

Deferred Binding

In some cases you need to write low-level functionality that differs based on the client browser, or you need to trigger a generator to generate code at compile time. For these functions you use deferred binding. Deferred binding allows you to write code to an interface and have the concrete class determined at compile-time.

For example, you may be familiar with GWT's RPC mechanism. You use the GWT.create() method to return a concrete class that can serialize and send your data to the server.

4
1
​
2
MyServiceAsync svc = (MyServiceAsync) GWT.create(MyService.class);
3
​
4
​

When this code is compiled the compiler examines the argument passed to the create method, then attempts to match the target class to a set of rules that reside in the module configuration.

Using Generate-With to Trigger Generators

In this case the compiler rule is specified in the module com.google.gwt.user.RemoteService, which is inherited from your module when using GWT-RPC.

6
1
​
2
<generate-with class="com.google.gwt.user.rebind.rpc.ServiceInterfaceProxyGenerator">
3
        <when-type-assignable class="com.google.gwt.user.client.rpc.RemoteService"/>
4
</generate-with>
5
​
6
​

This rule states that when the target class of the GWT.create() is assignable to RemoteService, that the generator ServiceInterfaceProxyGenerator is executed. The generator then creates the code and returns the name of the class that should be returned by the create method.

Using Replace-With to Trigger Class Replacement

The other use of deferred binding is to specify a alternate class to be returned by GWT.create() based on available properties. The most common use of this is to use an alternate class depending on the client browser. The property that can be examined to determine this is "user.agent".

For example, the DOM class in GWT is used to perform low-level functions, where the browser implementations can differ. In order to allow for different browsers the following rule can be found in the com.google.gwt.user.DOM module.

7
1
​
2
<replace-with class="com.google.gwt.user.client.impl.DOMImplIE6">
3
        <when-type-is class="com.google.gwt.user.client.impl.DOMImpl"/>
4
        <when-property-is name="user.agent" value="ie6"/>
5
</replace-with>
6
​
7
​

In the DOM class the following code is used to "create" the correct implementation of the DOM class.

4
1
​
2
DOMImpl impl = (DOMImpl) GWT.create(DOMImpl.class);
3
​
4
​

When the user.agent property is "ie6" the replace-with rule specified above will return a DOM implementation that is specifically designed for Internet Explorer.

Generate-With and Replace-With Expressions

The following expression tags can be used within generate-with and replace-with tags. When any of the expression tags within the rule returns a true value, the code generation or class replacement is performed.

4
1
​
2
<when-property-is name="prop-name" value="matched-value" />
3
​
4
​

Returns true when the value of the property matches the specified value. For details on setting properties, see the Setting Properties section.

4
1
​
2
<when-type-assignable class="assignable-type" />
3
​
4
​

The target class is tested to see if it can be assigned to the specified assignable type.

4
1
​
2
<when-type-is class="type" />
3
​
4
​

Similar to when-type-assignable, except that the class must be an exact match.

4
1
​
2
<all>, <any>, <none>
3
​
4
​

Use these expression tags to group other expression tags. The <all> tag implies that all of the tags contained within it must be true. The <any> tag requires only one of the containing expressions to be true. The <none> tag requires that all contained expression tags return false.

Setting Properties

Property names and their possible values can be defined in the module configuration.

4
1
​
2
<define-property name="prop-name" values="vals" />
3
​
4
​

Creates a new property and comma separated list of the possible values. For example, you could use the following to define a view property that could be used to define three unique view types for the application.

4
1
​
2
<extend-property name="prop-name" values="vals" />
3
​
4
​

Extends the possible values for a property that has already been defined.

4
1
​
2
<set-property name="prop-name" value="value" />
3
​
4
​

Sets the value of a defined property. The value must be one of the possible values as defined by the <define-property> tag or one of the extended values as defined by the <extended-property> tag.

4
1
​
2
<property-provider name="prop-name">
3
​
4
​

Property values can be set at run-time by supplying a property provider. The contents of the <property-provider> tag is a block of JavaScript that returns the property value. The JavaScript code must be placed in a CDATA block to avoid parsing errors.

10
1
​
2
<property-provider name="view"><![CDATA[
3
        var view = __gwt_getMetaProperty("view");
4
        if (!__gwt_isKnownPropertyValue("view", view)) {
5
                view = 'basic';
6
        }
7
        return view;
8
]]></property-provider>
9
​
10
​

The JavaScript block can utilize the __gwt_getMetaProperty() method to get the value of GWT property defined in a <meta> tag in the HTML page, and can use __gwt_isKnownPropertyValue() to test that it is an allowed value. Here's an example of using the HTML <meta> tag to set the view as "extended".

4
1
​
2
<meta name="gwt:property" content="view=extended" />
3
​
4
​
Section 5

JavaScript Native Interface

The JSNI interface is used as a gateway between your Java and JavaScript code. It allows you to create Java methods that have JavaScript code in the body, and then to have the JavaScript code call Java methods.

JSNI Methods

Methods containing JavaScript must use the native modifier so that a Java compiler will not validate its contents. Methods in Java marked as native may not have a method body.

4
1
​
2
public native void doStuff ();
3
​
4
​

GWT introduces a special comment syntax that follows the Java native rule of having no method body, while allowing you to provide JavaScript code that can be picked up by the GWT compiler.

6
1
​
2
public native void doStuff () /*-{
3
        // JavaScript code goes here
4
}-*/;
5
​
6
​

JSNI Variables

Due to the way GWT applications load, the "window" and "document" JavaScript objects point to the wrong objects. GWT provides these special variables for use in JSNI methods.

Variable Purpose
$wnd Alias for the JavaScript "window" object
$doc Alias for the JavaScript "document" object
6
1
​
2
public native void doStuff () /*-{
3
        $wnd.alert("Hello World");
4
}-*/;
5
​
6
​

Passing Values Between Java and JavaScript

You can pass both Java primitives and objects into a JSNI method. The following rules define how Java values are available in JSNI methods and visa versa.

Java type Where created JavaScript type
numeric primitive (byte, short, char, int, long, float, double) Both numeric value
boolean primitive Both boolean value
String Both string value
JavaScriptObject Must be created in JSNI method An object
Java array Must be created in Java Not directly usable, can be passed back into Java code
All other Java objects Must be created in Java Special, see below

JSNI methods that have Java objects passed to them may use a special syntax in order to call methods and access properties of the object.

Calling Java Methods from JavaScript

The following syntax is used to call a Java method from a JSNI method.

4
1
​
2
[instance-expr.]@class-name::method-name(param-signature) (arguments)
3
​
4
​

The instance expression is the name of the variable passed into the method, or "this" to refer to the class instance, or blank for calling static methods.

The class name is the fully qualified name, followed by double colons and the method name.

The parameter signature is a list of the parameter types in the method that you are calling. This is needed in order to distinguish between two Java methods that have the same name but different sets or parameters. The following table defines the codes used to specify the parameter type.

Type Code Java Type
Z Boolean
B Byte
C Char
S Short
I Int
J Long
F Float
D Double
L fully-qualified-class ; Java objects. Uses "/" to delimit parts of the package name, e.g. "Ljava/lang/String;"
[ type Int

Types are listed one after the other without spaces. For example, "ZLjava/lang/String;[F" defines the method signature (boolean, String, float[]).

The argument list is exactly that, a list of the arguments being passed to the method. Below are examples of calling methods from JavaScript on well known Java types.

Calling instance method with no arguments:

6
1
​
2
public native long extractTime (Date date) /*-{
3
        return date.@java.util.Date::getTime()();
4
}-*/;
5
​
6
​

Calling instance method with a single argument:

7
1
​
2
public native void appendText (StringBuffer sb, String txt)
3
/*-{
4
        sb.@java.lang.StringBuffer::append(Ljava/lang/String;)(txt);
5
}-*/;
6
​
7
​

Calling static method with multiple arguments:

6
1
​
2
public native int maxValue (int x, int y) /*-{
3
        return @java.lang.Math::max(II)(x, y);
4
}-*/;
5
​
6
​

Accessing Java properties from JavaScript

Accessing properties of a Java object from JavaScript is similar to calling a Java method.

4
1
​
2
[instance-expr.]@class-name::field-name
3
​
4
​

The same value rules apply as calling methods (see Calling Java Methods from JavaScript). The instance expression is the variable name passed into the JSNI method, "this" for the instance of the class, or left off to access a static property. The class name is the fully qualified package and class, and is separated from the field name with two colons. On the following page are some examples.

Reading and writing to field on "this"

6
1
​
2
// int currentIndex;
3
var cur = this.@org.example.Demo::currentIndex;
4
this.@org.example.Demo::currentIndex = 0;
5
​
6
​

Reading and writing to field on object

6
1
​
2
// String welcomeMessage;
3
var msg = obj.@org.example.Demo::welcomeMessage;
4
obj.@org.example.Demo::welcomeMessage = "Hello";
5
​
6
​

Reading and writing to a static field

6
1
​
2
// boolean lastResult;
3
var last = @org.example.Demo::lastResult;
4
@org.example.Demo::lastResult = true;
5
​
6
​

Hot Tip

You can use JSNI to dynamically create JavaScript methods that can be used by external JavaScript code to make calls into your application. The following code creates a JavaScript method jsMethod(string) on startup in the browser that can be used to call the javaMethod(String) in the GWT application.

16
1
​
2
public void onModuleLoad () {
3
        createJsMethod(this);
4
}
5
private native void createJsMethod (Main obj) /*-{
6
        $wnd.jsMethod = function (s) {
7
        return
8
        obj.@com.getsandbox.demo.client.Main::javaMethod(Ljava/lang/String;)(s);
9
        };
10
}-*/;
11
public String javaMethod (String in) {
12
        return "I got your message: " + in;
13
}
14
<button onclick="alert(jsMethod('Hello'))">Say Hello</button>
15
​
16
​

Like This Refcard? Read More From DZone

related article thumbnail

DZone Article

Parsing JavaScript with JavaScript
related article thumbnail

DZone Article

Top JavaScript Libraries for Making AJAX Calls
related article thumbnail

DZone Article

Scaling DevOps With NGINX Caching: Reducing Latency and Backend Load
related article thumbnail

DZone Article

The Role of Retrieval Augmented Generation (RAG) in Development of AI-Infused Enterprise Applications
related refcard thumbnail

Free DZone Refcard

Java Application Containerization and Deployment
related refcard thumbnail

Free DZone Refcard

Introduction to Cloud-Native Java
related refcard thumbnail

Free DZone Refcard

Java 15
related refcard thumbnail

Free DZone Refcard

Java 14

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: