Home > Articles > Programming > User Interface (UI)

Introduce Animated Cursors to Java GUIs, Part 1

  • Print
  • + Share This
  • 💬 Discuss
Like this article? We recommend
Jeff Friesen begins a three-part series introducing three implementations of his Java-based animated cursor library, which extracts cursor images and other data from Windows-based .ani files and animates the cursors over Java components. Each implementation builds on its predecessor, gradually turning the library into an extremely useful product. This article describes the most basic implementation and introduces an application for testing all three implementations.

Animated cursors are supported by most of Microsoft’s Windows operating systems. For example, Windows XP makes it possible to change the default arrow pointer to a walking dinosaur, or to a pointer with animated rainbow colors. Because Java doesn’t support animated cursors, though, I’ve developed a library that brings Windows-based animated cursors to Java.

This article begins a three-part series that introduces three implementations of my Java-based animated cursor library. The article first presents a Swing application that demonstrates the capabilities of all implementations, and then examines the source code for the most basic implementation. Future articles introduce improved implementations.

Let There Be Animated Cursors

The AniCursorDemo Swing application demonstrates the animated cursor library. This program uses the library to extract cursor images from a Windows-based .ani (animated cursor) file identified via the command line. It also uses the library to start and stop an animation thread, which takes care of animating these images over a label component. Listing 1 presents AniCursorDemo’s source code.

Listing 1 AniCursorDemo.java.

// AniCursorDemo.java

// Test an animated cursor.

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import ca.mb.javajeff.anicursor.*;

public class AniCursorDemo extends JFrame
{
  AniCursor anicursor;

  JButton btnStop;

  JLabel label;

  public AniCursorDemo (final String aniName)
  {
   super ("AniCursorDemo");
   setDefaultCloseOperation (EXIT_ON_CLOSE);

   GPanel gpanel = new GPanel ();

   final JButton btnStart = new JButton ("Start");
   ActionListener al;
   al = new ActionListener ()
      {
        public void actionPerformed (ActionEvent ae)
        {
         if (anicursor == null)
           try
           {
             anicursor = new AniCursor (aniName, label);
           }
           catch (Exception ex)
           {
             System.err.println (ex.getMessage ());
             return;
           }

         btnStop.setEnabled (true);
         btnStart.setEnabled (false);
         anicursor.start ();
        }
      };
   btnStart.addActionListener (al);
   gpanel.add (btnStart);

   gpanel.add (label = new JLabel ("Animated cursor only appears over this "+
                   "label!"));
   label.setBorder (BorderFactory.
            createCompoundBorder (BorderFactory.
                       createEtchedBorder (),
                       BorderFactory.
                       createEmptyBorder (5, 5, 5, 5)));

   btnStop = new JButton ("Stop");
   btnStop.setEnabled (false);
   al = new ActionListener ()
      {
        public void actionPerformed (ActionEvent ae)
        {
         anicursor.stop ();
         btnStart.setEnabled (true);
         btnStop.setEnabled (false);
        }
      };
   btnStop.addActionListener (al);
   gpanel.add (btnStop);

   setContentPane (gpanel);

   pack ();
   setResizable (false);
   setVisible (true);
  }

  public static void main (final String [] args)
  {
   Runnable r;
   r = new Runnable ()
     {
       public void run ()
       {
         new AniCursorDemo (args.length == 0 ? null : args [0]);
       }
     };
   EventQueue.invokeLater (r);
  }
}

class GPanel extends JPanel
{
  private GradientPaint gp;

  public void paintComponent (Graphics g)
  {
   Graphics2D g2d = (Graphics2D) g;

   if (gp == null)
     gp = new GradientPaint (0, 0, Color.white, 0,
                 getHeight (), Color.pink);

   // Paint a nice gradient background with white at the top and pink at
   // the bottom.

   g2d.setPaint (gp);
   g.fillRect (0, 0, getWidth (), getHeight ());
  }
}

AniCursorDemo creates a singleton AniCursor instance from within the action listener assigned to the Start button. This instance, which represents an animated cursor, is initialized with the name (and optional path) of a Windows .ani file. It’s also initialized with a reference to a label component, which is associated with the animated cursor.

After creating the AniCursor instance, the listener tells this instance to start its animation thread. Whenever the mouse moves over the previously specified label, the animated cursor will appear over this component. The Stop button’s action listener tells the AniCursor instance to stop the animation thread.

Compile and Run the Application

This article’s code archive contains AniCursorDemo.java and the library’s source files. You will need to compile all of these files before you can run this application. Follow these steps to take care of the compilation task:

  1. Unzip the code archive.
  2. Make the unzipped AniCursorDemo directory the current directory.
  3. Compile the code via the following command (assuming Windows XP):
    javac -cp ../ AniCursorDemo.java

    Assuming that AniCursorDemo is still the current directory, and assuming a Windows XP platform, you would invoke the following:

    java -cp ../;. AniCursorDemo

Figure 1 shows the GUI after clicking the Start button.

Figure 1

Figure 1 The default animated cursor is a rotating two-way arrow.

If you don’t specify a Windows .ani file via the command line, AniCursorDemo passes null to AniCursor’s constructor. This value selects the default rotating two-way arrow cursor, which is built into AniCursor.

You can easily specify the path and name of a Windows .ani file via a command-line argument. For example, invoke the following to reveal Windows XP’s colorful arrow pointer, which is shown in Figure 2:

java -cp ../;. AniCursorDemo \windows\cursors\rainbow.ani
Figure 2

Figure 2 The arrow pointer reveals a rainbow of color.

For a final example, invoking the following command causes Windows XP’s walking dinosaur (shown in Figure 3) to appear whenever the mouse moves over the label:

java -cp ../;. AniCursorDemo \windows\cursors\dinosaur.ani
Figure 3

Figure 3 Not all dinosaurs are extinct!

  • + Share This
  • 🔖 Save To Your Account

Discussions

comments powered by Disqus