Last week i have written about improving the visuals of text components, comboboxes and spinners in the 6.0dev branch of Substance look-and-feel library. Today, it’s time to talk about the micro-design of these components – aligning perceived boundaries, text baseline and other visual elements of user input controls.

I have started looking into the precise micro-design around three years ago, with the main inspiration coming from JGoodies Looks library developed by Karsten Lentzsch. The micro-design looks at how the controls look like when they are placed next to each other – do they have the same perceived height, are the texts aligned on the same line etc. While these issues do not directly affect the business functionality of your application, they most certainly contribute to the overall polish and end user experience. Since then, the work in Substance has grown into complete support for resolution independence – scaling the entire visuals of all supported controls based on the current desktop font settings.

With the recent redesign of the visual appearance of user input controls in the next Substance release, there were two major changes that required revisiting the implementation:

  • Uneditable comboboxes now have appearance identical to that of buttons. This means that the button visuals should now be micro-aligned with those of comboboxes and, by extension, with those of all text based controls.
  • Editable text based controls have double borders. The outer border is lighter and blends with the container, and the inner border is darker, creating the inset look. The perceived vertical bounds of these controls is delineated by the inner border.

Let’s look at a few screenshots. All the screenshots in this entry will show the same collection of controls – text field, formatted text field, password field, spinner, editable combo, uneditable combo and a button. Here is how these controls look under the latest 6.0dev drop of Substance:

https://substance.dev.java.net/release-info/6.0/alignment-substance-business.png

And here is the same application, with grid lines delineating the perceived bounds of the controls (red) and the text baseline (green):

https://substance.dev.java.net/release-info/6.0/alignment-substance-business-overlays.png

Here, the perceived bounds and the texts are perfectly aligned. It’s important to note that the actual bounds of text fields as compared to that of button is different – the text field is two pixels higher than the button. However, since those two pixels are painted with a color much closer to the containing panel background, the perceived bounds of the text field is defined by the inner darker contour.

This visual alignment is consistent across all Substance skins. Here are the controls under Dust Coffee:

https://substance.dev.java.net/release-info/6.0/alignment-substance-dustcoffee.png

https://substance.dev.java.net/release-info/6.0/alignment-substance-dustcoffee-overlays.png

and Graphite:

https://substance.dev.java.net/release-info/6.0/alignment-substance-graphite.png

https://substance.dev.java.net/release-info/6.0/alignment-substance-graphite-overlays.png

Now let’s see how Substance 6.0dev fares against other core and active third-party look-and-feels – all under Windows Vista with the font settings specific to the relevant look-and-feel.

We’ll start with the default Metal / Ocean:

https://substance.dev.java.net/release-info/6.0/alignment-metal.png

The guider lines highlight the problematic areas:

https://substance.dev.java.net/release-info/6.0/alignment-metal-overlays.png

Button is one pixel taller than combos, and combos are quite a few pixels taller than text fields / spinners. Also, even though technically the bottom spinner button is aligned with the bottom edge of the spinner, the perceived alignment is off by one pixel (since the colors used on these two parts have inverted brightness). Finally, the dot characters of the password field appear to be 1-2 pixels too high.

Let’s look at the native Windows look-and-feel:

https://substance.dev.java.net/release-info/6.0/alignment-windows.png

Apart from the archaic usage of Tahoma 11 (and not the platform Segoe UI 12), there are two visual problems. The top border of the spinner control is cut off (see UI guidelines for the correct visuals), and there are extra pixels around the corners of the uneditable comboboxes. Let’s look at the guider lines:

https://substance.dev.java.net/release-info/6.0/alignment-windows-overlays.png

The text baselines are perfectly aligned, and the only issue is the one-pixel difference in the height of button and combo.

Let’s look at Nimbus – the new addition to 6u10+.

https://substance.dev.java.net/release-info/6.0/alignment-nimbus.png

Before looking at the guider lines, notice how the bottom edge of the arrow button on the editable combobox does not visually align with the much lighter bottom edge of the control itself. The visual result is that the button looks much heavier, appearing to “hang” off the right side of the control. The same applies to the bottom edge of the spinner. Let’s now look at the guider lines:

https://substance.dev.java.net/release-info/6.0/alignment-nimbus-overlays.png

Here, the controls heights are inconsistent. While the button has the same height as the text fields and spinners, the comboboxes are two pixels shorter. Also, the star characters on the password field appear to be 2-3 pixels too high.

Now let’s look at JGoodies Looks. First, the Plastic XP skin:

https://substance.dev.java.net/release-info/6.0/alignment-jgoodies-plasticxp.png

The guider lines show that everything is pixel-perfect:

https://substance.dev.java.net/release-info/6.0/alignment-jgoodies-plasticxp-overlays.png

Now let’s look at the Plastic skin:

https://substance.dev.java.net/release-info/6.0/alignment-jgoodies-plastic.png

Here, most of the texts appear to be too low, and this is confirmed by the guider lines:

https://substance.dev.java.net/release-info/6.0/alignment-jgoodies-plastic-overlays.png

Note how the button text baseline is one pixel higher than the rest.

Finally, let’s task a look at Synthetica. We’ll start with the Base skin:

https://substance.dev.java.net/release-info/6.0/alignment-synthetica-base.png

Overlaying the guider lines:

https://substance.dev.java.net/release-info/6.0/alignment-synthetica-base-overlays.png

Shows that the button is 2 pixels higher than the rest of the controls. However, everything else looks perfect, including the bounds and text baseline.

Next, the newly added Black Eye skin:

https://substance.dev.java.net/release-info/6.0/alignment-synthetica-blackeye.png

Let’s overlay the guider lines:

https://substance.dev.java.net/release-info/6.0/alignment-synthetica-blackeye-overlays.png

Here, we can see that the button is much taller than the rest of the controls, and the spinner is 2 pixels shorter than text fields and combos. Also, the star characters of the password field appear to be 3-4 pixels too high.

The last skin to analyze is the Orange Metallic:

https://substance.dev.java.net/release-info/6.0/alignment-synthetica-orangemetallic.png

And the guider lines:

https://substance.dev.java.net/release-info/6.0/alignment-synthetica-orangemetallic-overlays.png

Here, we can see that the buttons are taller than the combos, and the combos are taller than the text fields and spinners. Also, the star characters of the password field appear to be 3-4 pixels too high. Finally, the button font is bold, while the rest of the controls use plain font.

If you’re interested to see what Substance 6.0dev can bring to your application, take it for a spin. Stay tuned for the next entry which will talk about control alignment in Substance across different font sizes.

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