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:

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:

https://flamingo.dev.java.net/release-info/4.2/ribbon-appmenu-defaultcontent.png

https://flamingo.dev.java.net/release-info/4.2/command-buttons-no-icon1.png

https://flamingo.dev.java.net/release-info/4.2/command-buttons-no-icon2.png

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:

https://flamingo.dev.java.net/release-info/4.2/ribbon-appmenu-notshowing.png

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:

https://flamingo.dev.java.net/release-info/4.2/ribbon-appmenu-rollovermenu.png

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:

https://flamingo.dev.java.net/release-info/4.2/ribbon-appmenu-rollovercontent.png

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:

https://flamingo.dev.java.net/release-info/4.2/ribbon-appmenu-defaultcontent.png

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:

https://flamingo.dev.java.net/release-info/4.2/command-buttons-icon-and-text1.png

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:

https://flamingo.dev.java.net/release-info/4.2/command-buttons-icon-and-text2.png

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:

https://flamingo.dev.java.net/release-info/4.2/command-buttons-no-icon1.png

https://flamingo.dev.java.net/release-info/4.2/command-buttons-no-icon2.png

And the final screenshot shows the same button arrangement, but this time for buttons with no texts:

https://flamingo.dev.java.net/release-info/4.2/command-buttons-no-text.png

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:

Timeline starTimeline = new Timeline(star);
double angle = Math.random() * 2.0 * Math.PI;
double distance = 20.0 + 30.0 * Math.random();
starTimeline.addPropertyToInterpolate("x", currX, currX
	+ distance * Math.cos(angle));
starTimeline.addPropertyToInterpolate("y", currY, currY
	+ distance * Math.sin(angle));
starTimeline.addPropertyToInterpolate("alpha", 1.0f, 0.0f);
starTimeline.addPropertyToInterpolate("rotation", 0.0f,
	(float) (2 * Math.PI * Math.random()));
starTimeline.addPropertyToInterpolate("outerSpan",
	outerStartSpan, outerFinalSpan);
starTimeline.addPropertyToInterpolate("color", Color.white,
	new Color(Color.HSBtoRGB(currHue, 0.8f, 0.7f)));
currHue += 0.01f;

When the timeline for the specific star is created, it is simply played for 3 seconds. The main spawning timeline is looped indefinitely:

      starTimeline.setDuration(3000);
      starTimeline.play();
   }
});
spawner.playLoop(RepeatBehavior.LOOP);

If you have Java 6 or later on your machine, click on the button below to launch the WebStart demo of “Star Dust”: