Helping ordinary people create extraordinary websites!
GET OUR NEWSLETTER
Your Email:
 

Advanced Synth

By Michael Abernethy
2005-04-16


Working with Custom Painters

The final piece to defining the example login screen in Figure 2 is to draw the gradient background with the curved line. This probably looks tough to do in XML, and frankly it is. But it gives me a chance to show that Synth doesn't limit you to using only images and simple colors in UI designs. You can use it to draw anything.

Synth lets you override its paint methods (the ones in javax.swing.plaf.synth.SynthPainter) by subclassing SynthPainter and overriding only the specific functions you wish to custom paint. In the example, you need to custom paint the paintPanelBackground method, because the design can't be described in the Synth XML format.

To use a custom painter, or to create a class in any way in the XML, you use the <object> tag. The <object> tag allows for creation and persistence of any Java classes you want to use to supplement the Synth rendering. The <object> tag takes two elements:

• class: The full name of the class that should be created
• id: The ID name you'll use to reference this class instance in the XML document

By using objects, you not only can create the instance of the BackgroundPainter class -- the class that will paint the background. You can also create an instance of a ColorUIResource class, where you define the background colors. Think about it: Defining the colors used in the background inside the BackgroundPainter class itself would contradict Synth's goal of defining everything in an external XML file rather than hard-coding it in a Java file.

The final step to using a custom painter is to tell the Synth rendering engine that you, not the SynthPainter class, will be supplying the function. In the example, you define the paintPanelBackground function in the BackgroundPainter class and let Synth use its SynthPainter class to define the rest of the paint functions. The <painter> tag lets you override the SynthPainter function. It takes two elements:

• method: The method that the custom painter should override. As you know from Using images, you can find these functions in the javax.swing.plaf.synth.SynthPainter class but should remove the paint string at the beginning of each function. (So paintPanelBackground in SynthPainter should be panelBackground in the XML file, for example.)

• id: The reference to the class that will override the method.

In order to use the colors in the custom painter, you must store them in the javax.swing.UIDefaults class. As you can see in Listings 7 and 8, storing colors in UIDefaults is straightforward and should be familiar to anyone who's worked with UI creation. The key you define in the XML will be the reference in the UIManager you use to get the colors in the actual Java code for BackgroundPainter.

Listing 7 shows the XML code for working with custom painters in the example application. Notice that you must define the colors first.

Listing 7. Working with custom painters

<style id="button">

<state>
<imagePainter method="buttonBackground" path="images/button.png"
sourceInsets="9 10 9 12" paintCenter="true" stretch="true"/>
<insets top="9" left="10" bottom="9" right="12"/>
<font name="Aharoni" size="16"/>
<color type="TEXT_FOREGROUND" value="#FFFFFF"/>
</state>
<state value="MOUSE_OVER">
<imagePainter method="buttonBackground" path="images/button_on.png"
sourceInsets="9 10 9 12" paintCenter="true" stretch="true"/>
<insets top="9" left="10" bottom="9" right="12"/>
<color type="TEXT_FOREGROUND" value="#FFFFFF"/>
</state>
<state value="PRESSED">
<imagePainter method="buttonBackground" path="images/button_press.png"
sourceInsets="10 12 8 9" paintCenter="true" stretch="true"/>
<insets top="10" left="12" bottom="8" right="9"/>
<color type="TEXT_FOREGROUND" value="#FFFFFF"/>
</state>
<property key="Button.margin" type="insets" value="0 0 0 0"/>
</style>
<bind style="button" type="region" key="Button"/>
Listing 8 shows the Java code for the example application's custom-painting class:

Listing 8. Java code for custom painting

public class BackgroundPainter extends SynthPainter

{

public void paintPanelBackground(SynthContext context,
Graphics g, int x, int y,
int w, int h)
{
Color start = UIManager.getColor("Panel.startBackground");
Color end = UIManager.getColor("Panel.endBackground");
Graphics2D g2 = (Graphics2D)g;
GradientPaint grPaint = new GradientPaint(
(float)x, (float)y, start,
(float)w, (float)h, end);
g2.setPaint(grPaint);
g2.fillRect(x, y, w, h);
g2.setPaint(null);
g2.setColor(new Color(255, 255, 255, 120));
g2.setRenderingHint(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
CubicCurve2D.Double arc2d = new CubicCurve2D.Double(
0, h/4, w/3, h/10, 66 * w, 1.5 * h, w, h/8);
g2.draw(arc2d);
g2.setRenderingHint(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
}
}


Tutorial Pages:
» Custom UIs are a Breeze with the Newest Swing Look and Feel
» Beauty's Only Skin Deep
» Synth Basics
» Demo Application
» Changing a Color and Font
» Using Images
» Handling Different States
» Working with Custom Painters
» More-Advanced Settings
» Examining Synth Performance, Reliability, and Efficiency
» Conclusion
» Resources


First published by IBM DeveloperWorks


 | Bookmark
Related Tutorials:
» All about JAXP, Part 1
» Make Database Queries Without the Database
» Load List Values for Improved Efficiency
» 2 Ways To Implement Session Tracking
» A Simple Way to Read an XML File in Java
» Develop Aspect-Oriented Java Applications with Eclipse and AJDT

Advertise with Us!


Tutorials Scripts Web Hosting Developer Manuals
Resources