|
|
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 5 of 5
The previous article in this series focused on Bernhard Pauler's balloontip project. For that article, I built an application GUI, called VerifyAge, that included a balloon tip. Figure 1 reveals one small problem with the GUI: the balloon tip's undecorated dialog container hides part of the window's frame, preventing access to the frame's Minimize and Maximize buttons, and making the overall GUI look unsightly.

Although it would have been better to render that part of the undecorated dialog not presenting the balloon tip transparent,
Java does not support transparent windows. Fortunately, we can solve this problem using the com.sun.jna.examples.WindowUtils class located in JNA's examples.jar file.
WindowUtils provides utility methods that use JNA to achieve transparent windows on Unix, Linux, Mac OS X, and Windows platforms. For
example, public static void setWindowMask(final Window w, Icon mask) lets you choose which part of a window to make transparent based on pixels not defined by its mask argument. This task is demonstrated in Listing 10.
// Create a mask for this dialog. This mask has the same shape as the
// dialog's rounded balloon tip and ensures that only the balloon tip
// part of the dialog will be visible. All other dialog pixels will
// disappear because they correspond to transparent mask pixels.
// Note: The drawing code is based on the drawing code in
// RoundedBalloonBorder.
Rectangle bounds = getBounds ();
BufferedImage bi = new BufferedImage (bounds.width, bounds.height,
BufferedImage.TYPE_INT_ARGB);
Graphics g = bi.createGraphics ();
g.fillRoundRect (0, 0, bounds.width, bounds.height-VERT_OFFSET,
ARC_WIDTH*2, ARC_HEIGHT*2);
g.drawRoundRect (0, 0, bounds.width-1, bounds.height-VERT_OFFSET-1,
ARC_WIDTH*2, ARC_HEIGHT*2);
int [] xPoints = { HORZ_OFFSET, HORZ_OFFSET+VERT_OFFSET, HORZ_OFFSET };
int [] yPoints = { bounds.height-VERT_OFFSET-1, bounds.height-VERT_OFFSET
-1, bounds.height-1 };
g.fillPolygon (xPoints, yPoints, 3);
g.drawLine (xPoints [0], yPoints [0], xPoints [2], yPoints [2]);
g.drawLine (xPoints [1], yPoints [1], xPoints [2], yPoints [2]);
g.dispose ();
WindowUtils.setWindowMask (this, new ImageIcon (bi));
The code fragment in Listing 10 is an excerpt from the end of the TipFrame constructor in an enhanced VerifyAge2 application, which is included in this article's code archive. The constructor defines a mask in the shape of the rounded balloon tip, where only drawn pixels are non-transparent.
Assuming that your current directory contains examples.jar, jna.jar, and VerifyAge2.java, invoke javac -cp examples.jar;balloontip.jar VerifyAge2.java to compile the source code. Then invoke java -Dsun.java2d.noddraw=true -cp examples.jar;balloontip.jar;. VerifyAge2 to run the application. Figure 2 reveals transparency.

JNA is a project with a long history (stretching back to 1999) but it was first released in November 2006. Since then it has been slowly gaining the attention of developers who need to integrate native C code into Java-based projects. JNA has also made some waves among JRuby programmers because it can be used to work around one of JRuby's pervasive problems, lack of support for POSIX calls. JNA has also been proposed as a solution for extending Ruby with low-level C code.
I enjoyed working with JNA and believe you will find it easier and safer to use than JNI for accessing native code. Needless to say, there is more to JNA than I could cover in a single article. See the Resources section to learn more about this open source Java project. Experiment with it and share your experiences in the discussion forum for this series. I'll be back next month with another lesser known open source project that could benefit your everyday Java development.
Shortly after writing this article I discovered that Java supports translucent and shaped windows as of the 6u10 build. After
reading about this topic in Kirill Grouchnikov's blog, I modified VerifyAge2 to use this new alternative to WindowUtils.setWindowMask(), as follows:
// Create and install a balloon tip shape to ensure that only this part
// of the dialog will be visible.
Rectangle bounds = getBounds ();
GeneralPath gp;
gp = new GeneralPath (new RoundRectangle2D.Double (bounds.x, bounds.y,
bounds.width,
bounds.height-
VERT_OFFSET,
ARC_WIDTH*2-1,
ARC_HEIGHT*2-1));
gp.moveTo (HORZ_OFFSET, bounds.height-VERT_OFFSET);
gp.lineTo (HORZ_OFFSET, bounds.height);
gp.lineTo (HORZ_OFFSET+VERT_OFFSET+1, bounds.height-VERT_OFFSET);
AWTUtilities.setWindowShape (this, gp);
This code uses the new AWTUtilities class (located in the com.sun.awt package) and its public void setWindowShape(Window w, Shape s) method to reshape the TipFrame JDialog window into a balloon shape.
Read more about Tools & Methods in JavaWorld's Tools & Methods section.
jna.jar and examples.jar from the JNA downloads page.
Archived Discussions (Read only)