Creating a Screensaver

From CompSciWiki
Jump to: navigation, search

COMP 1010 Home > Back to Chapter Topics


Introduction

Have you just completed your first Java based programming course? Are you sick of writing console based text applications? Good news! With this tutorial and its accompanying framework, we can create a Windows screensaver right now.

   

{{{Body}}}


This tutorial is intended for Java programmers who have completed COMP 1010. If this isn't you, but you're feeling adventurous, install the Java SE Development Kit and join us for the ride! You'll also appreciate a good text editor, such as Notepad++. Alternatively, you may wish to join the University of Manitoba's early computer science students and use a demo version of TextPad.

For the sake of this tutorial, our screensaver will be named "Butterflies". Feel free to substitute in a different name while working through this tutorial.


Setting up the Framework and Template

Create Screensaver.java by pasting the code available on that page into a new file with the same name. This will act as a framework off of which we can build our screensaver.

At this point, you may be tempted to try to understand the "Screensaver" class. I suppose that's what makes us programmers! However, please understand that "What the heck is going on in this class?!" is the expected reaction of a programmer who has only been exposed to programming in a single course so far. There are a few other things that this tutorial will ignore; rest assured, drawing graphics isn't one of them!

Create Butterflies.java by either pasting the code available on that page into a new file or using the following template:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JOptionPane;

public class Butterflies extends Screensaver {
  public static void main (String[] args) {
    // args contains arguments passed to the program as it starts.  For example,
    // if the screensaver is run as "java Butterflies /c", args[0] will contain
    // the first argument, "/c".
    if (args.length > 0 && args[0].startsWith ("/c")) {
      // YOUR SETTINGS DIALOG CODE GOES HERE.
    } else if (args.length > 0 && args[0].startsWith ("/p")) {
      // Screensaver preview code goes here.  Windows displays previews in the
      // monitor of the screensaver dialog.  This can safely be ignored.
    } else {
      // Start the screensaver.
      final int SECONDS = 1;
      setFrameDelay (SECONDS);
      new Butterflies();
    }
  }

  // Draw a frame of this screensaver.
  public void drawFrame (Graphics g) {
    // YOUR DRAWING CODE GOES HERE.
  }
} // Butterflies

The following aspects of the above template don't need to be understood:

  • The "extends" keyword.
  • Why drawFrame isn't a static method.
  • The line "new Butterflies();".


Adding Custom Code

Add code for drawing frames of the screensaver. Your methods may be static even though drawFrame isn't. If you opted to use the template, I encourage you to view the sample Butterflies.java source file for an understanding of the code you could add at this point. While the sample file demonstrates "g.setColor" and "g.fillOval", we could also use other Graphics methods, such as:

  • g.drawArc (int x, int y, int width, int height, int startAngle, int arcAngle)
  • g.drawLine (int x1, int y1, int x2, int y2)
  • g.drawOval (int x, int y, int width, int height)
  • g.drawPolygon (int[] xPoints, int[] yPoints, int nPoints)
  • g.drawPolyline (int[] xPoints, int[] yPoints, int nPoints)
  • g.drawRect (int x, int y, int width, int height)
  • g.drawRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight)
  • g.fillArc (int x, int y, int width, int height, int startAngle, int arcAngle)
  • g.fillOval (int x, int y, int width, int height)
  • g.fillPolygon (int[] xPoints, int[] yPoints, int nPoints)
  • g.fillRect (int x, int y, int width, int height)
  • g.fillRoundRect (int x, int y, int width, int height, int arcWidth, int arcHeight)

Notice the similarity between the "draw" and "fill" methods. In Java, graphical methods that begin with "draw" are used for drawing outlines. "fill" methods are used to draw and fill shapes with a solid color. For more information about drawing and filling with Java's Graphics class, please visit their official API reference.

The "Screensaver.java" framework provides the following useful methods:

  • setFrameDelay (int seconds): Sets the delay, in seconds, between frame updates of the screensaver.
  • getWidth(): Returns an int representing the screen's width in pixels.
  • getHeight(): Returns an int representing the screen's height in pixels.

Looking for interesting equations to use in our screensaver? Try these:

Figure 1: Butterfly Curve
The Butterfly Curve was discovered by Temple H. Fay[1].

Some of the above links require that you convert from Polar to Cartesian coordinates.

I recommend using a graphing program to experiment with the equations while writing our screensaver. One such program is KmPlot. It's part of the KDE software compilation, which has recently been ported from Unix-like operating systems to Windows. You can download it here.

If you choose to install KDE for KmPlot, it's simplest to select all packages when asked by the installer. Also, while installing KDE on Windows, I found that it installed to a different directory than I had selected. In case this happens to you, be sure to pay attention to where the files are being installed to! Once installed, you can run KmPlot from the "bin" folder of the installation directory.

The suggested drawing above is all well and good, but there's a catch. In COMP 1010, we haven't yet learned about global variables. In order to animate what we draw between frames, we would need global variables to keep track of object positions. Butterflies.java gets around this by using "Math.random()", which returns a double from 0.0 to 1.0, inclusively. If we can't remember where a drawn object was on the last frame, we can always place it randomly on this one!

Lastly, you may also wish to create a settings dialog for our screensaver. While outside the scope of this tutorial, you could present a series of questions on the command line and save the user's answers in a configuration file. When the screensaver is executed normally, its output could rely on the loaded configuration.

The settings dialog could be substituted with a simple about message. Butterflies.java accomplishes this with the following code:

final String TITLE = "The Title";
final String MESSAGE = "A message.";
OptionPane.showMessageDialog (null, MESSAGE, TITLE, JOptionPane.INFORMATION_MESSAGE);

Compiling and Running

Compile our program as usual in TextPad or from the command line. If you use the command line, be sure to "cd" into the appropriate directory first.

 cd Folder\to\Butterflies
 javac Butterflies.java

Note that "Screensaver.java" is automatically compiled with and used by "Butterflies.java". There is no need to explicitly compile it separately.

Test our program in screensaver mode. Just as we pass the "/s" argument to the screensaver now, Windows will do the same when it attempts to start our screensaver later.

 java Butterflies /s

Test our program's configuration dialog. Later, Windows will tell the screensaver to show its configuration dialog with the "/c" argument.

 java Butterflies /c

Now that we can execute our screensaver manually, it would be nice to help automate the process for Windows to use as a regular screensaver. There's just one problem. Windows expects its screensavers to have the SCR file extension. SCR files are simply EXE files with a different extension that happen to take the "/s" and "/c" arguments mentioned earlier. We need a way of getting a native Windows executable to run our Java screensaver.

To create the SCR file, start by downloading Dev-C++. Create Butterflies.c with the source code on the linked page. Don't worry about understanding the contents of this C program. The important thing to remember is that it executes a Java program with the same name, excluding the file extension. This program even passes arguments, such as "/c" and "/s", along to the Java program. Load "Butterflies.c" in Dev-C++ and compile it by clicking the "Execute" menu and choosing "Compile". A program named "Butterflies.exe" will be created. Rename it to "Butterflies.scr" and ensure that it's in the same folder as our Java screensaver. Verify that executing "Butterflies.scr" starts our screensaver. If your main source file isn't named "Butterflies.java", be sure to rename "Butterflies.scr" accordingly.

Copy all the compiled "class" files and "Butterflies.scr" into "C:\Windows\System32". Our screensaver will now show up in Windows' screensaver dialog!

Congratulations! You have created a screensaver using only basic Java skills. While computer science certainly has its share of complexities, there are times when asking simpler questions yields simpler answers. This screensaver could have been created in a much more complicated fashion. We skipped this needless complexity by using an existing framework and elegant curve equations found elsewhere on the Internet.

Just as you required a Java Runtime Environment to run the screensaver, so too will your friends if you distribute it to them.

Further Reading


References

  1. Fay, T. H. The Butterfly Curve. The American Mathematical Monthly, 96 (5), 442-443.


Copyright (C) 2009 Samuel Pauls. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".