Over the course of the next few days i’m going to talk about different concepts in the Trident animation library for Java applications. Part six shows simple Swing / SWT examples that highlight Trident support for Java-based UI toolkits.

Simple Swing example

The following example shows how to smoothly change the foreground color of a Swing button on mouse rollover.

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.*;

import org.pushingpixels.trident.Timeline;

public class ButtonFg extends JFrame {
   public ButtonFg() {
      JButton button = new JButton("sample");
      button.setForeground(Color.blue);

      this.setLayout(new FlowLayout());
      this.add(button);

      final Timeline rolloverTimeline = new Timeline(button);
      rolloverTimeline.addPropertyToInterpolate("foreground", Color.blue,
            Color.red);
      rolloverTimeline.setDuration(2500);
      button.addMouseListener(new MouseAdapter() {
         @Override
         public void mouseEntered(MouseEvent e) {
            rolloverTimeline.play();
         }

         @Override
         public void mouseExited(MouseEvent e) {
            rolloverTimeline.playReverse();
         }
      });

      this.setSize(400, 200);
      this.setLocationRelativeTo(null);
      this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         @Override
         public void run() {
            new ButtonFg().setVisible(true);
         }
      });
   }
}

Here, we have a timeline that interpolates the foreground color between blue and red. The mouse listener registered on the button plays this timeline on mouse enter, and plays this timeline in reverse on mouse exit.

This example shows how the JComponent.setForeground(Color) method is used together with the built in property interpolator for the java.awt.Color class to run the timeline that interpolates the foreground color of a Swing button. Note that since the JComponent.setForeground(Color) also repaints the button, there is no need to explicitly repaint it on every timeline pulse.

If you debug this application and put a breakpoint in the JComponent.setForeground(Color) method, you will see that it is called on the Event Dispatch Thread. This is a built-in capability of the Trident core. It recognizes that the timeline is associated with a Swing component, and calls the setter method (during the timeline pulses) on the EDT.

Simple SWT example

The following example is the SWT version of changing the control foreground color on mouse rollover:

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.*;
import org.pushingpixels.trident.Timeline;

public class ButtonFg {
   public static void main(String[] args) {
      Display display = new Display();
      Shell shell = new Shell(display);
      shell.setSize(300, 200);
      GridLayout layout = new GridLayout();
      shell.setLayout(layout);

      Button button = new Button(shell, SWT.RADIO);
      GridData gridData = new GridData(GridData.CENTER, GridData.CENTER,
            true, false);
      button.setLayoutData(gridData);

      button.setText("sample");

      Color blue = display.getSystemColor(SWT.COLOR_BLUE);
      Color red = display.getSystemColor(SWT.COLOR_RED);
      button.setForeground(blue);

      final Timeline rolloverTimeline = new Timeline(button);
      rolloverTimeline.addPropertyToInterpolate("foreground", blue, red);
      rolloverTimeline.setDuration(2500);
      button.addMouseTrackListener(new MouseTrackAdapter() {
         @Override
         public void mouseEnter(MouseEvent e) {
            rolloverTimeline.play();
         }

         @Override
         public void mouseExit(MouseEvent e) {
            rolloverTimeline.playReverse();
         }
      });

      shell.open();
      while (!shell.isDisposed()) {
         if (!display.readAndDispatch())
            display.sleep();
      }
      display.dispose();
   }
}

As with Swing, the Control.setForeground(Color) method is used together with the built in property interpolator for the org.eclipse.swt.graphics.Color class to run the timeline that interpolates the foreground color of an SWT radio button. Note that since the Control.setForeground(Color) also repaints the button, there is no need to explicitly repaint it on every timeline pulse.

If you debug this application and put a breakpoint in the Control.setForeground(Color) method, you will see that it is called on the SWT Thread. This is a built-in capability of the Trident core. It recognizes that the timeline is associated with a SWT component, and calls the setter method (during the timeline pulses) on the SWT thread.

Finally, since both examples are using the Timeline.play() and Timeline.playReverse() methods, the interpolation can be reversed in the middle if the user moves the mouse quickly. The rollover timeline in our example takes 2.5 seconds to complete. Suppose the user moves the mouse over the button, and then after one second moves the mouse away. The call to playReverse detects that this very timeline is already playing, and starts playing it in reverse from its current position.

Release 5.2 of Substance look-and-feel made a few visual changes to the Raven Graphite skins, but these did not address the overall usability of these skins – especially the contrast between the background and the controls, and the background / foreground contrast of text components.

The latest drop of version 5.3dev (code named Reykjavik) features significant overhaul of both Raven Graphite skins, aiming to address the contrast usability issues raised by the users.

Here is a screenshot of a sample application under the Raven Graphite skin in the latest stable 5.2 release:

https://substance.dev.java.net/release-info/5.3/ravengraphite1-old.png

And here is the same application under the 5.3dev drop:

https://substance.dev.java.net/release-info/5.3/ravengraphite1-new.png

Here is another screenshot of the same application under the old Raven Graphite visuals:

https://substance.dev.java.net/release-info/5.3/ravengraphite2-old.png

and the new visuals under the latest 5.3dev drop:

https://substance.dev.java.net/release-info/5.3/ravengraphite2-new.png

The main changes are:

  • Removing the watermark that contributed significant visual noise
  • Darker border color for controls, bringing more delineation to check boxes and radio buttons
  • Darker background color for text components, resulting in better readability

The same changes were made for the Raven Graphite Glass skin. Here is the sample application under the stable 5.2 release:

https://substance.dev.java.net/release-info/5.3/ravengraphiteglass1-old.png

and here is the same application under the latest 5.3dev drop:

https://substance.dev.java.net/release-info/5.3/ravengraphiteglass1-new.png

In addition to the visual changes above, the Raven Graphite Glass skin has removed the glass arc gradient from the toolbars and added a two-tone separator to delineate the title bar / menu bar from the rest of the application content.

To illustrate the visual difference in a larger content, here is a screenshot of a big UI under the stable 5.2 release (click to see the full-size view):

and the same application under the 5.3dev branch:

If you want to take the new visuals for a spin, click on the WebStart button below and change the skin to Raven Graphite and Raven Graphite Glass from the “Skins” menu:

You’re more than welcome to take the latest 5.3dev drop for a spin and leave your comments.

As mentioned in the JavaOne presentation on the Flamingo ribbon component, there are a few small features missing in the Swing implementation. The first drop of version 4.2dev (code-named Hiolair) now provides support for placing small command buttons in ribbon galleries.

A ribbon gallery is a compact way to display a large number of buttons that control the specific visual appearance of the selected document element. The ribbon gallery fits itself to the available horizontal space, and allows two navigation modes:

  • Using the scroll-up and scroll-down buttons to view additional button rows inside the ribbon itself
  • Using the expand button to view all the buttons in a scrollable popup

Here is how a ribbon gallery hosting big command buttons looks like:

And when it is expanded (with the bottom-right button), it looks like this:

Up until now the ribbon has supported placing only big buttons in ribbon galleries. Starting with version 4.2, the new JRibbonBand.addRibbonGallery that gets the CommandButtonDisplayState as one of the parameters can be used to create a ribbon gallery that hosts small command buttons. The following display states are supported:

  • JRibbonBand.BIG_FIXED_LANDSCAPE – this is the default display state. The buttons display big icon and text below it, and the buttons have fixed 5:4 ratio when displayed in the popup.
  • JRibbonBand.BIG_FIXED. The buttons display big icon and text below it, and the buttons have fixed 1:1 ratio when displayed in the popup.
  • CommandButtonDisplayState.SMALL. The buttons display only small icon with no text.

Here is a ribbon gallery that hosts small command buttons (in three rows):

And this is how it looks when it is expanded:

You’re more than welcome to take the first drop of version 4.2dev for a spin. You can also play with the WebStart demo of the ribbon under Substance look-and-feel by clicking on the button below. Switch to “Animations” task for a ribbon gallery with small command buttons.

I’ve just finished presenting my JavaOne session on the ribbon component. Thanks to everybody for coming. To all of you who attended but want to see the slides once again, and to those of you who couldn’t attend, here are the slides:

Since there were no animations in the slides, the two versions should be identical.

The test applications shown in the session can be found in the test.* package of Flamingo and Substance Flamingo distribution archives.