JPPF, java, parallel computing, distributed computing, grid computing, parallel, distributed, cluster, grid, cloud, open source, android, .net
JPPF, java, parallel computing, distributed computing, grid computing, parallel, distributed, cluster, grid, cloud, open source, android, .net
JPPF

The open source
grid computing
solution

 Home   About   Features   Download   Documentation   Forums 

JPPF node screensaver

From JPPF 4.2 Documentation

Jump to: navigation, search

Contents

Main Page > Customizing JPPF > Node screensaver

A screensaver can be associated with a running JPPF node. The screensaver is a Java Swing UI which is displayed at the time the node is launched. It can run in full screen or in windowed mode, depending on the configuration settings.

Creating a custom screensaver

A screensaver implements the interface JPPFScreenSaver, defined as follows:

public interface JPPFScreenSaver {
  // Get the Swing component for this screen saver
  JComponent getComponent();

  // Initialize this screen saver, and in particular its UI components
  void init(TypedProperties config, boolean fullscreen);

  // Destroy this screen saver and release its resources
  void destroy();
}

The screensaver lifecycle is as follows:

  • the screensaver is instantiated, based on a class name specified in the configuration (requires a no-arg constructor)
  • the init() method is called, passing in the JPPF configuration and a flag indicating whether the full screen mode is both requested and supported
  • a JFrame is created and the component obtained by calling getComponent() is added to this JFrame. In full screen, the frame is undecorated (no caption, menu bar, status bar or borders) and will cover all available space on all available monitors: the screen saver will spread over all screens in a multi-monitor setup
  • the frame is then made visible
  • finally, the destroy() method is called when the frame is closed. In full screen mode, this happens upon pressing a key or clicking or (optionally) moving the mouse

The code which handles the screensaver is implemented as a node initialization hook: this means it starts just after the configuration has been read.

Here is a sample screensaver implementation which draws a number of small circles at random locations and with a random color, around 25 times per second. Addtionally, the screen is cleared every 5 seconds and the process starts over:

public class SimpleScreenSaver extends JPanel implements JPPFScreenSaver {
  private Random rand = new Random(System.nanoTime());
  private Timer timer = null;
  private volatile boolean reset = false;

  public SimpleScreenSaver() { super(true); }

  @Override
  public JComponent getComponent() {
    return this;
  }

  @Override
  public void init(TypedProperties config, boolean fullscreen) {
    setBackground(Color.BLACK);
    timer = new Timer("JPPFScreenSaverTimer");
    timer.scheduleAtFixedRate(new TimerTask() {
      @Override public void run() { repaint(); }
    }, 40L, 40L); // draw new circles every 40 ms or 25 times/second
    timer.scheduleAtFixedRate(new TimerTask() {
      @Override public void run() { reset = true; }
    }, 5000L, 5000L); // clear the screen every 5 seconds
  }

  @Override
  public void destroy() {
    if (timer != null) timer.cancel();
  }

  @Override
  public void paintComponent(final Graphics g) {
    int w = getWidth();
    int h = getHeight();
    if (reset) { // if reset requested, clear the screen
      reset = false;
      g.setColor(Color.BLACK);
      g.fillRect(0, 0, w, h);
    } else { // draw 500 small circles
      int n = 5;
      for (int i=0; i<500; i++) {
        // random x, y coordinates
        int x = rand.nextInt(w-(n-1));
        int y = rand.nextInt(h-(n-1));
        // random color
        g.setColor(new Color(rand.nextInt(256), rand.nextInt(256), rand.nextInt(256)));
        g.fillOval(x, y, n, n);
      }
    }
  }
}

It will look like this:

SimpleScreenSaver.gif

Integrating with node events

To receive notifications of node lifce cycle events and/or individual tasks completion, you will need to implement the NodeIntegration interface or, more conveniently, extend the adapter class NodeIntegrationAdapter. NodeIntegration is defined as follows:

public interface NodeIntegration extends NodeLifeCycleListener, TaskExecutionListener {
  // Provide a reference to the screen saver
  void setScreenSaver(JPPFScreenSaver screensaver);
}

As we can see, this is just an interface which joins both NodeLifeCycleListener and TaskExecutionListener and provides a way to hook up with the screensaver.

The following example shows how to use node events to display and update the number of tasks executed by the node in the screensaver:

// displays the number of executed tasks in a JLabel
public class MyScreenSaver extends JPanel implements JPPFScreenSaver {
  private JLabel nbTasksLabel = new JLabel("number of tasks: 0");
  private int nbTasks = 0;

  @Override public JComponent getComponent() { return this; }
  @Override public void init(TypedProperties config, boolean fullscreen) {
    this.add(nbTasksLabel);
  }
  @Override public void destroy() { }

  public void updateNbTasks(int n) {
    nbTasks += n;
    nbTasksLabel.setText("number of tasks: " + nbTasks);
  }
}

// update the number of tasks on each job completion event
public class MyNodeIntegration extends NodeIntegrationAdpater {
  private MyScreenSaver screensaver = null;

  @Override public void jobEnding(NodeLifeCycleEvent event) {
    if (screensaver != null) screensaver.updateNbTasks(event.getTasks().size());
  }

  @Override public void setScreenSaver(JPPFScreenSaver screensaver) {
    this.screensaver = (MyScreenSaver) sceensaver;
  }
}

Configuration

The screensaver supports a number of configuration properties which allow a high level of customization:

# enable/disable the screen saver, defaults to false (disabled)
jppf.screensaver.enabled = true

# the screensaver implementation: fully qualified class name of an implementation of
# org.jppf.node.screensaver.JPPFScreenSaver
jppf.screensaver.class = org.jppf.node.screensaver.impl.JPPFScreenSaverImpl

# the node event listener implementation: fully qualified class name of an
# implementation of org.jppf.node.screensaver.NodeIntegration
# if left unspecified or empty, no listener will be used
jppf.screensaver.node.listener = org.jppf.node.screensaver.impl.NodeState

# title of the JFrame used in windowed mode
jppf.screensaver.title = JPPF is cool

# path to the image for the frame's icon (in windowed mode)
jppf.screensaver.icon = org/jppf/node/jppf-icon.gif

# display the screen saver in full screen mode?
# in full screen mode, the screen saver will take all available screen space on all
# available monitors, the mouse cursor is not displayed, and the node will exit on any
# key pressed, mouse click or mouse motion
jppf.screensaver.fullscreen = true

# width and height (in pixels), only apply if fullscreen = false. Default to 1000x800
jppf.screensaver.width = 1000
jppf.screensaver.height = 800

# close on mouse motion in full screen mode? default to true
jppf.screensaver.mouse.motion.close = true

JPPF built-in screensaver

A built-in screensaver is provided, which displays an number of moving small logos (images) bouncing around the screen and bouncing against each other. Additionally, it displays panel comprising a (personalizable) logo, along with a status bar indicating how long the node has been running, its connection status, execution status and the number of tasks it has executed. It looks like this:

Screensaver1.gif

The built-in screensaver proposes a number of spceific configuration options, which aim at providing a fine level of personalization and hopefully some fun!

# should collisions between moving logos be handled? defaults to true
jppf.screensaver.handle.collisions = true

# number of moving logos
jppf.screensaver.logos = 50

# speed from 1 to 100
jppf.screensaver.speed = 100

# path to the moving logo image(s). Multiple images can be specified, their paths
# must be separated with '|' (pipe) characters. They will be distributed in a
# round-robin fashion according to the number of logos
jppf.screensaver.logo.path = org/jppf/node/jppf_group_small2.gif| \
    org/jppf/node/rectagle_blue.png| \
    org/jppf/node/rectagle_orange.png| \
    org/jppf/node/rectagle_green.png| \
    org/jppf/node/rectagle_red.png
 
# path to the larger image at the center of the screen
jppf.screensaver.centerimage = org/jppf/node/jppf@home.gif
 
# horizontal alignment of the status panel (including the larger image).
# useful when using a multi-monitor setup, where a centered panel will be split on two
# screens and thus more difficult to read
# possible values: 'left' or 'l', 'center' or 'c', 'right' or 'r'; default is 'center'
jppf.screensaver.status.panel.alignment = center

To use this screensaver, you need to set the following properties:

jppf.screensaver.enabled = true
jppf.screensaver.class = org.jppf.node.screensaver.impl.JPPFScreenSaverImpl
jppf.screensaver.node.listener = org.jppf.node.screensaver.impl.NodeState
Main Page > Customizing JPPF > Node screensaver

JPPF Copyright © 2005-2017 JPPF.org Powered by MediaWiki