I am pleased today to announce the availability of release candidate for version 4.2 of Flamingo component suite (code-named Hiolair). It is a stabilization release that adds a few minor features and fixes all known bugs.
Here is the list of minor features added in release 4.2:
Emitting full bounding box coordinates in SVG transcoder
Support for changing the expand listener of ribbon bands
Better tracing of inconsistent ribbon resize policies
If you want to test the ribbon in your applications, you would need the following (the last two only for applications running under Substance look-and-feel):
You are more than welcome to take Flamingo 4.2RC for a ride and report any problems in the project mailing lists, forums or issue tracker. The final release is scheduled for November 2. Only bugs will be fixed until that date.
To see Flamingo ribbon in action, run the following WebStart demo:
The demo above works for the core look-and-feels. To see the ribbon under Substance, run the following WebStart demo:
Here are a few screenshots showing the new features in 4.2RC:
Flamingo component suite provides a pure Swing implementation of Office 2007 ribbon component, and the latest 4.2dev drop of the core library has enhanced the support for ribbon application menu to provide default content of the secondary menu panel.
The application menu button is a big round button in the top left corner of the ribbon:
It is not a direct replacement for the usual application menu bar, but rather a place to hold actions that (as a general rule) do not affect the visual content of the document – such as saving, printing, sharing etc. When the application menu button is clicked, it shows a panel with two levels of actions:
Primary action
Secondary actions for the selected primary action
For example, a primary “Print” action will have a number of secondary actions to print the document as is, print from a dialog with all the options or open the print preview. In order to specify secondary actions, use theĀ RibbonApplicationMenuEntryPrimary.addSecondaryMenuGroup API:
RibbonApplicationMenuEntryPrimary amEntryPrint = new RibbonApplicationMenuEntryPrimary(
new document_print(), "Print", new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Invoked printing document");
}
}, CommandButtonKind.ACTION_AND_POPUP_MAIN_ACTION);
amEntryPrint.setActionKeyTip("P");
amEntryPrint.setPopupKeyTip("W");
RibbonApplicationMenuEntrySecondary amEntryPrintSelect = new RibbonApplicationMenuEntrySecondary(
new printer(), "Print", null, CommandButtonKind.ACTION_ONLY);
amEntryPrintSelect
.setDescriptionText("Select a printer, number of copies and other printing options before printing");
amEntryPrintSelect.setActionKeyTip("P");
RibbonApplicationMenuEntrySecondary amEntryPrintDefault = new RibbonApplicationMenuEntrySecondary(
new document_print(), "Quick Print", null,
CommandButtonKind.ACTION_ONLY);
amEntryPrintDefault
.setDescriptionText("Send the document directly to the default printer without making changes");
amEntryPrintDefault.setActionKeyTip("Q");
RibbonApplicationMenuEntrySecondary amEntryPrintPreview = new RibbonApplicationMenuEntrySecondary(
new document_print_preview(), "Print Preview", null,
CommandButtonKind.ACTION_ONLY);
amEntryPrintPreview
.setDescriptionText("Preview and make changes to the pages before printing");
amEntryPrintPreview.setActionKeyTip("V");
amEntryPrint.addSecondaryMenuGroup("Preview and print the document",
amEntryPrintSelect, amEntryPrintDefault, amEntryPrintPreview);
At runtime when the user moves the mouse over the “Print” entry in the left panel, the matching secondary entries are shown on the right:
While most of the primary entries have a predefined (static) list of secondary entries, some require dynamic content. For example, the “Open” entry shows the list of recently open documents. In order to associate dynamic secondary content, use the RibbonApplicationMenuEntryPrimary.setRolloverCallback API:
RibbonApplicationMenuEntryPrimary amEntryOpen = new RibbonApplicationMenuEntryPrimary(
new document_open(), "Open", new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Invoked opening document");
}
}, CommandButtonKind.ACTION_ONLY);
amEntryOpen
.setRolloverCallback(new RibbonApplicationMenuEntryPrimary.PrimaryRolloverCallback() {
@Override
public void menuEntryActivated(JPanel targetPanel) {
targetPanel.removeAll();
JCommandButtonPanel openHistoryPanel = new JCommandButtonPanel(
CommandButtonDisplayState.MEDIUM);
String groupName = "Recent Documents";
openHistoryPanel.addButtonGroup(groupName);
for (int i = 0; i < 5; i++) {
JCommandButton historyButton = new JCommandButton(i
+ " " + "document" + i + ".html",
new text_html());
historyButton
.setHorizontalAlignment(SwingUtilities.LEFT);
openHistoryPanel
.addButtonToLastGroup(historyButton);
}
openHistoryPanel.setMaxButtonColumns(1);
targetPanel.setLayout(new BorderLayout());
targetPanel.add(openHistoryPanel, BorderLayout.CENTER);
}
});
amEntryOpen.setActionKeyTip("O");
Here, the application code is responsible for clearing and populating the contents of the secondary panel. At runtime when the user moves the mouse over the “Open” entry in the left panel, the application callback is invoked to populate the secondary panel:
The latest 4.2dev drop of Flamingo core library also allows the application code to specify the default content of the secondary panel. This is done with the new RibbonApplicationMenu.setDefaultCallback API. When set, it will be called when the ribbon application menu is shown, and when the currently active (under mouse) primary entry has neither secondary entries, nor rollover callback. In Office 2007 the default content of the secondary panel is the list of recently opened documents, but this API allows you to provide a custom implementation if necessary:
applicationMenu
.setDefaultCallback(new RibbonApplicationMenuEntryPrimary.PrimaryRolloverCallback() {
@Override
public void menuEntryActivated(JPanel targetPanel) {
targetPanel.removeAll();
JCommandButtonPanel openHistoryPanel = new JCommandButtonPanel(
CommandButtonDisplayState.MEDIUM);
String groupName = "Default Documents";
openHistoryPanel.addButtonGroup(groupName);
for (int i = 0; i < 5; i++) {
JCommandButton historyButton = new JCommandButton(i
+ " " + "default" + i + ".html",
new text_html());
historyButton
.setHorizontalAlignment(SwingUtilities.LEFT);
openHistoryPanel
.addButtonToLastGroup(historyButton);
}
openHistoryPanel.setMaxButtonColumns(1);
targetPanel.setLayout(new BorderLayout());
targetPanel.add(openHistoryPanel, BorderLayout.CENTER);
}
});
When the default callback is invoked at runtime (under one of the two scenarios mentioned above), it populates the secondary panel:
If you want to see the enhanced application menu button in action, run the following WebStart demo:
The demo above works for the core look-and-feels. If you want to see this functionality under Substance, run the following WebStart demo:
If you want to test the new functionality in your applications, you would need the following (the last two only for applications running under Substance look-and-feel):
The command button component is a central building block for the Flamingo component suite. It aims to address the deficiencies of the core Swing button components, adding features expected by the modern applications. While the main goal of Flamingo is to provide a pure Java implementation of the Office 2007 ribbon container, the command buttons can certainly be used outside the ribbon.
The latest 4.2dev drop of the core Flamingo library and 6.0dev drop of the Substance Flamingo plugin provide support for command buttons that have no text and/or no icon. This is a big step forward that positions the Flamingo command button as a drop-in replacement for core Swing buttons, and here are a few screenshots to illustrate these new capabilities.
Here is a screenshot of a few command buttons that have both text and icon:
Here, the rows show the functionally equivalent command buttons that arrange the text and icon in different layouts – addressing the varying space available to host the specific button. The first column shows action buttons – clicking anywhere on a button will activate the registered listeners. The second column shows split buttons – clicking on icon / text will activate the listeners, while clicking on the drop arrow will show the popup menu.
The next screenshot shows text / icon command buttons of the other two kinds:
The first column shows another type of split button – where the popup menu is shown when the text is clicked (as opposed to the first split button type where clicking the text activates the main action). The second column is a menu button – clicking anywhere shows the popup menu.
The next two screenshots show the same button arrangement, but this time for buttons with no icons:
And the final screenshot shows the same button arrangement, but this time for buttons with no texts:
With the release 1.1 of Trident animation library available a couple of weeks ago, it’s time to start the development of version 1.2 (code-named Cookie Jar). The first 1.2dev drop has a few minor API enhancements, as well as a small new demo. This demo is based on the Flash mouse star trailer, and is slightly reminiscent of the Glitzer applet from Paul Schmidinger. Here is a video showing “Star Dust” in action:
The code is quite straightforward (see the test.swing.StarDust class). It has a looping timeline that spawns new stars. At every pulse this timeline checks the current location of the mouse. If the mouse is inside the panel, it creates a new Star object, as well as a matching Timeline object. The paintComponent() method of the panel iterates over all “live” stars and paints them based on their current position, size, rotation, alpha and color.
Here is the relevant code for the spawner timeline:
Timeline spawner = new Timeline();
spawner.addCallback(new UIThreadTimelineCallbackAdapter() {
private float currHue = 0.0f;
@Override
public void onTimelinePulse(float durationFraction,
float timelinePosition) {
Point mouseLoc = MouseInfo.getPointerInfo().getLocation();
SwingUtilities.convertPointFromScreen(mouseLoc, mainPanel);
double currX = mouseLoc.getX();
double currY = mouseLoc.getY();
if ((currX < 0) || (currY < 0) || (currX > mainPanel.getWidth())
|| (currY > mainPanel.getHeight()))
return;
double outerStartSpan = 5;
double outerFinalSpan = 20;
Star star = new Star(currX, currY, outerStartSpan);
Here, we use the MouseInfo class to get the mouse location, and then create a Star object centered at that point. Then, we create a timeline to animate the star location, size, rotation and alpha: