The latest 5.0dev drop of Flamingo provides a flexible color selector popup that you can associate with the command buttons that control the color selection of elements in your application. Here is how a color selector popup looks like under left-to-right and right-to-left orientation:

To associate a color selector popup with the specific command button (that has a popup area), return an instance of JColorSelectorPopupMenu from the PopupPanelCallback. This class extends the JCommandPopupMenu and allows adding command menu buttons, command toggle menu buttons and separators. The screenshot above shows two command menu buttons in the color selector popup – one at the top and another at the bottom.
In adition, the JColorSelectorPopupMenu provides the following APIs to add color selector sections:
- addColorSection that gets 10 colors. The “Standard Colors” in the screenshot above is an example.
- addColorSectionWithDerived that gets 10 primary colors. Each primary color will show a column of 5 derived colors below it. The “Theme Colors” in the screenshot above is an example.
- addRecentSection. Shows the LRU list of the recently selected colors.
A JColorSelectorPopupMenu is created with an instance of ColorSelectorCallback. This interface has two methods:
- onColorRollover(Color) – allows your application to show the live preview of the color under the mouse. When called with null, the application needs to unset the live preview.
- onColorSelected(Color) – called when the user selects one of the colors in the popup.
The selector sections added with the APIs above will be automatically wired to the color selector callback that you pass in the constructor. If your design requires displaying additional menu buttons to select color, these will need to be explicitly wired to the callback and the list of recently selected colors.
The test.common.TestColorSelector application shows sample code on how to do this. The top button selects a default color. It has an ActionListener which calls the same logic as onColorSelected(), and a ChangeListener that tracks changes to the rollover state of the menu button and calls the same logic as onColorRollover(). The bottom button in this sample application launches the core JColorChooser. When a color is selected in that chooser, the custom application code calls the same logic as onColorSelected().
When a color is selected in both custom menu buttons, the list of recently selected colors is updated – so that the user can quickly choose it again in the future. The relevant APIs in the JColorSelectorPopupMenu are:
- static getRecentlyUsedColors(). The last element in the list is the most recently selected.
- static addColorToRecentlyUsed() adds the specified color to the list. If the color is already there, it is moved to the end of the list.
This list is guaranteed to contain at most ten colors.
If you want to take the new color selector popup for a spin, you will need the following:
Note that the last two are required if you’re running your application under one of Substance skins.
Exactly a year ago I’ve introduced project Onyx – animation blueprints for Swing using the Trident animation library. Onyx is a small application that loads album information for the specific artist from the Internet and displays it as a scrollable gallery. Here is how Onyx looked a year ago:

And here is how Onyx looks now:

Along with running on Java 6 (with Java 7 weekly binaries for Mac nowhere in sight), Onyx also has received a slight visual facelift for the main window. First, let’s see the code for disposing a window by fading it out:
public static void fadeOutAndDispose(final Window window,
int fadeOutDuration) {
Timeline dispose = new Timeline(window);
try {
Class clazz = Class.forName("com.sun.awt.AWTUtilities");
final Method opacityMethod = clazz.getDeclaredMethod(
"setWindowOpacity", Window.class, float.class);
dispose.addPropertyToInterpolate(Timeline. property(
"opacity").from(1.0f).to(0.0f).setWith(
new PropertySetter() {
@Override
public void set(Object obj, String fieldName,
Float value) {
try {
opacityMethod.invoke(null, obj, value);
} catch (Exception exc) {
exc.printStackTrace();
}
}
}));
dispose.addCallback(new UIThreadTimelineCallbackAdapter() {
@Override
public void onTimelineStateChanged(TimelineState oldState,
TimelineState newState, float durationFraction,
float timelinePosition) {
if (newState == TimelineState.DONE) {
window.dispose();
}
}
});
dispose.setDuration(fadeOutDuration);
dispose.play();
} catch (Exception exc) {
exc.printStackTrace();
}
}
With Java 7, you can simply do this:
dispose.addPropertyToInterpolate("opacity", 1.0f, 0.0f);
and let Trident call Window.setOpacity method at every timeline pulse. In Java 6 (starting with 6u10), the AWTUtilities.setWindowOpacity needs to be called on every pulse explicitly.
And here is the code for painting the main content window. First, we store the current clip and enable anti-aliasing:
@Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
Shape clip = g2d.getClip();
g2d.setStroke(new BasicStroke(1.0f));
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Next, we compute the outer and inner contours of the panel (the inner contour will be painted with slightly brighter colors as shown in the screenshot above):
int radius = 16;
Shape contour = new RoundRectangle2D.Double(0, 0, getWidth() - 1,
getHeight() - 1, radius, radius);
Shape innerContour = new RoundRectangle2D.Double(1, 1, getWidth() - 3,
getHeight() - 3, radius - 1, radius - 1);
When the main window is first shown and disposed, a special timeline is played to make the window appear and disappear smoothly. The timeline interpolates the alpha field between 0.0 and 0.9. The main panel has two parts – the bright blue header and the black content. While the content is painted based on the current value of alpha, the header uses less translucency:
g2d.setComposite(AlphaComposite.SrcOver.derive(1.0f - (float) Math.pow(
1.0f - alpha, 3.0)));
To paint the header, we first update the current clip to make sure that the painting is only done in the header section. Next, we fill the contour, draw the inner contour and draw the outer contour – all based on the specific colors required by the target design:
// top part
g2d.clipRect(0, 0, getWidth(), TITLE_HEIGHT);
g2d.setPaint(new LinearGradientPaint(0, 0, 0, TITLE_HEIGHT,
new float[] { 0.0f, 0.49999f, 0.5f, 1.0f }, new Color[] {
new Color(119, 152, 251), new Color(80, 127, 250),
new Color(48, 109, 250), new Color(10, 97, 250) }));
g2d.fill(contour);
g2d.setPaint(new GradientPaint(0, 0, new Color(151, 179, 253), 0,
TITLE_HEIGHT, new Color(19, 92, 233)));
g2d.draw(innerContour);
g2d.setColor(new Color(11, 61, 200));
g2d.draw(contour);
Now we restore the clip:
g2d.setClip(clip);
If we have an artist name to display, we position it in the middle of the title area (using font ascent for proper baseline alignment) and paint the string twice to create a lighting effect:
if (this.searchString != null) {
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2d.setFont(UIManager.getFont("Label.font").deriveFont(14.0f)
.deriveFont(Font.BOLD));
int fa = g2d.getFontMetrics().getAscent();
int x = (getWidth() - g2d.getFontMetrics().stringWidth(
this.searchString)) / 2;
int y = (TITLE_HEIGHT + fa) / 2;
g2d.setColor(new Color(31, 60, 114));
g2d.drawString(this.searchString, x, y + 1);
g2d.setColor(new Color(255, 255, 255));
g2d.drawString(this.searchString, x, y);
}
The main content area is painted in the same way as the header. We update the clip, fill the contour, draw the inner contour and draw the outer contour:
// bottom part
g2d.setComposite(AlphaComposite.SrcOver.derive(this.alpha));
g2d.clipRect(0, TITLE_HEIGHT, getWidth(), getHeight() - TITLE_HEIGHT
+ 1);
g2d.setColor(new Color(0, 0, 0));
g2d.fill(contour);
g2d.setPaint(new GradientPaint(0, TITLE_HEIGHT, new Color(57, 56, 57),
0, getHeight() - TITLE_HEIGHT, new Color(50, 48, 50)));
g2d.draw(innerContour);
g2d.setPaint(new GradientPaint(0, TITLE_HEIGHT, new Color(13, 11, 15),
0, getHeight() - TITLE_HEIGHT, new Color(15, 8, 13)));
g2d.draw(contour);
Finally, we draw a single line separator between the title and main content areas:
// separator
g2d.setClip(clip);
g2d.setColor(new Color(12, 11, 12));
g2d.drawLine(1, TITLE_HEIGHT, getWidth() - 2, TITLE_HEIGHT);
g2d.dispose();
}
To see the latest Onyx in action, click on the button below to launch the WebStart demo. Use the mouse wheel to scroll between the albums. Click a specific album to show a larger cover and the track list.

If you cannot run the demo, here is a short video of Onyx in action:
Toggle menu buttons were added to the Flamingo component library a few days ago, and their functionality has been enhanced following feedback from Pedro. In addition to tweaking the visual layout of the area between the icon and the text, the two improvements are:
- Showing a checkmark when the selected toggle menu button does not have an icon
- Popup menus that are not automatically dismissed when a child menu button is clicked
The second entry enhances the usability of popup menus that have multiple toggle menu buttons. Here is a screenshot to demonstrate such a scenario (note checkmarks on the selected buttons):

If this menu controls a set of boolean options / preferences, dismissing the menu after a single button has been clicked (selected toggled) is a bad user experience if the user wanted to change multiple settings. To prevent the auto-dismissal, call the new JCommandPopupMenu.setToDismissOnChildClick(false) API. This way the menu will stay up until the user clicks anywhere outside it or hits the Escape key.
If you want to take the new toggle menu buttons for a spin, you will need the following:
Note that the last two are required if you’re running your application under one of Substance skins.