LogCanvas Guide

Sergio Morozov


Contents

  1. Overview
  2. Description
  3. Usage
  4. GUI
  5. Configuration
    1. Declarative Configuration
    2. Programmatical Configuration

Overview

LogCanvas is a LogListener implementation. It is intended to display formatted logging events on device's or emulator's screen. LogCanvas extends GameCanvas. It's view consists of scrollable text area, that is refreshed on every logging event's arrival. Scrollbar is present only, when it is needed. Scrollbar's cursor has different color at the edge positions (top and bottom) from that at the middle, indicating first and last line. Users can scroll one line or page down or up, move to the first or to the last line, toggle fullscreen mode or reset buffer by pressing only one key. All key events are processed in separate thread, eliminating, this way, conflicts with callbacks execution thread. See GUI chapter for details.

LogCanvas is fully customizable. It provides means to completely configure it's view. It supports programmatical and declarative configuration. See Configuration chapter for details.

As with any other Displayable some programming work is required to make use of it. At least code, that makes LogCanvas instance current is needed. See Usage chapter for details. As MoMELog is intended to be used at development time and by developers, it is not considered as huge problem.


Description

LogCanvas is a LogListener implementation. It is intended to display formatted logging events on device's or emulator's screen. All logging events are converted to strings and appended to the StringBuffer. Developer can explore any logging event at any time. Key events are processed in separate thread (started when LogCanvas is shown and stopped on hide). This eliminates conflicts with callbacks processing thread and provides for better resources use.

LogCanvas class extends GameCanvas abstract class. It makes use of key events, and, of course, doesn't suppress them. It can be used like any other Displayable. Users can (or even should) add/remove commands, set CommandListener or title. LogCanvas is preset with the title of "Logging". No commands are added, and no CommandListener is set. It is initially not in fullscreen mode. fullscreen mode of LogCanvas can be changed at any time and it's view will be adjusted. Like with any other Displayable some programming work is needed to make use of it (at least to make it current ;-)).

LogCanvas view consists of scrollable text area. All formatted logging events are wrapped on character basis and displayed on text area. Scrollbar is shown only, when logging information occupies more than one page. Scrollbar's cursor has different color at the edge positions (top and bottom) from that at the middle, This indicates first and last (at that moment ;-)) line. See LogCanvas Screen Shots. Users can scroll one line or page up or down, move to the top or bottom of logging, toggle fullscreen mode or reset buffer by pressing only one key.

It's view is fully customizable. Users can set font of the text, it's background and foreground colors, scrollbar, scrollbar's cursor and scrollbar's cursor at the edge positions colors and runGCOnReset property. LogCanvas implements Configurable interface. It can be configured programmatically by invoking respective setter methods and/or declaratively from configuration file. See Configuration chapter for more details.

As mentioned above, all logging information is saved in buffer. When dealing with very detailed logging and running application on device, that restricts memory very much, there is possibility of memory shortage (I didn't encounter such situations). In such situations, users can reset buffer programmatically by invoking resetBuffer() method on LogCanvas instance or by pressing asterisk (*) key. This actually doesn't reset buffer, but frees buffer reference, sets a new one and runs garbage collector (if property runGCOnReset of LogCanvas is set to true (the default)).


Usage

LogCanvas can be instantiated using null-arg constructor LogCanvas(). MoMELog logging framework, of course, can be configured declaratively to use LogCanvas for processing logging events (see MoMELog Guide). In this case it's instance can be obtained just by calling Logger.getLogListener() static method.

LogCanvas extends GameCanvas. It can be used like any other Canvas. Users can (or even should) add/remove commands, set CommandListener or title. LogCanvas is preset with the title of "Logging". No commands are added, and no CommandListener is set. It is initially not in fullscreen mode. It's view and partly behavior can be configured programmatically by using respective setter methods and/or declaratively from initialization file. See Configuration chapter for details.

As mentioned above LogCanvas like any other Displayable requires some programming work to be done for making use of it. For example adding commands to switch from another Displayable to LogCanvas and back, setting CommandListener and providing some code for realizing this or, in the simplest case, just making it current at the beginning of the application's run.

There are two typical uses of the LogCanvas. In the first, more complex case, LogCanvas is added to the application that consists of other (mostly more than one) screen(s). This case requires addition of two extra commands say SHOW_LOG and BACK and some code to the CommandListener, that switches to the LogCanvas on SHOW_LOG command and back on BACK command. The BACK command is, of course, added to the LogCanvas instance and SHOW_LOG command to the other screen. For example in some MIDlet:


  ...

  private static final Command BACK = new Command("Back", Command.BACK, 10);

  private static final Command SHOW_LOG = new Command("Logging",
      "Show Logging", Command.SCREEN, 10);

  private LogCanvas logScr = null;

  private Displayable mainScr = null;

  ...

  protected void startApp()
  {
    if( !started)
    {
      ...

      // in a case (recommended) MoMELog is configured declaratively to use LogCanvas
      // just obtaining it's instance.
      //logScr = (LogCanvas) Logger.getLogListener();

      // instantiating LogCanvas
      logScr = new LogCanvas();


      // ordinary Canvas configuration.
      logScr.addCommand( BACK);
      logScr.setCommandListener( this);

      // LogCanvas specific configuration.
      logScr.setFont( Font.getFont( Font.MONOSPACE,FONT.PLAIN,Font.SMALL);

      // configuring MoMELog to use LogCanvas for processing logging events.
      // if MoMELog is already configured declaratively to use it, this is redundant.
      Logger.setLogListener( logScr);

      // creating some main screen
      mainScr = ... ;
      ...

      //adding command to switch to logging screen.
      mainScr.addCommand(SHOW_LOG);
      mainScr.setCommandListener(this);

      ...

      started = true;
    }

      ...
  }

  ...


  public void commandAction(Command cmd, Displayable src)
  {
    if (cmd == SHOW_LOG)
      // switching to logging screen.
      getDisplay().setCurrent(logScr);
    else if (cmd == BACK)
      // switching to main screen.
      getDisplay().setCurrent(main);
    ...

  }

  ...
}

In a cases of more simple application, LogCanvas can be the only screen. In such case, developer only need to make it current at the start of the application's run (e.g. in MIDlet.startApp() method). For example:

  ...

  protected void startApp()
  {
    if( !started)
    {
      ...

      // in a case (recommended) MoMELog is configured declaratively to use LogCanvas
      // just obtaining it's instance.
      //LogCanvas logScr = (LogCanvas) Logger.getLogListener();

      // instantiating LogCanvas
      LogCanvas logScr = new LogCanvas();

      // ordinary Canvas configuration.
      logScr.addCommand( EXIT);
      logScr.setCommandListener( this);
      ...

      // LogCanvas specific configuration.
      logScr.setFont( Font.getFont( Font.MONOSPACE,FONT.PLAIN,Font.SMALL);

      // configuring MoMELog to use LogCanvas for processing logging events.
      // if MoMELog is already configured declaratively to use it, this is redundant.
      Logger.setLogListener( logScr);

      ...

      started = true;
    }

    ...

    // making LogCanvas instance current screen.
    getDisplay().setCurrent( (LogCanvas) Logger.getLogListener());

    ...
  }

  ...
}

As mentioned in Description chapter, all logging information is saved in StringBuffer. When dealing with very detailed logging and running application on device, that restricts memory very much, there is possibility of memory shortage (I didn't encounter such situations). In such situations, users can reset buffer by invoking resetBuffer() method. This method actually doesn't reset buffer, but frees buffer reference, sets a new one and runs garbage collector (if property runGCOnReset of LogCanvas is set to true (the default)). runGCOnReset property can be set or obtained by setRunGCOnReset(boolean runGCOnReset) or isRunGCOnReset() method respectively.

As mentioned above LogCanvas is initially not in fullscreen mode. Like with any Canvas fullscreen mode can be changed at any time by invoking setFullScreenMode(boolean fullscreen) method.


GUI

GUI of LogCanvas is very simple and convenient.

Fig. 1. Logging displayed on emulator's screen. Scrollbar's cursor at the middle position.

View consists of scrollable text area. Scrollbar is, of course, shown only when logging information doesn't fit in one page. To indicate the first or the last (at that moment) line, scrollbar cursor has different color at the edge positions from that at the middle. See LogCanvas Screen Shots.

User can scroll one line down or up by pressing Down or Up key respectively. By pressing Right or Left key user can scroll one page (all fully visible lines except two) down or up respectively. User can move to the first or to the last line by pressing 7 or 9 key respectively. By pressing 0 key user can toggle fullscreen mode. User can clean all logging, freeing this way memory, by pressing asterisk (*) key.


Configuration

  1. Declarative Configuration
  2. Programmatical Configuration

As mentioned in Description chapter, LogCanvas is fully customizable. Developers can configure it's view and behavior programmatically by invoking respective setter methods and/or declaratively from initialization file. Configuration from initialization file takes place at Logger class loading time, and programmatical configuration, of course, overrides declarative.

LogCanvas provides possibilities to set font of the text, it's background and foreground colors, scrollbar, scrollbar's cursor and scrollbar's cursor at the edge positions colors and runGCOnReset property (runGCOnReset property specifies whether garbage collector is run on buffer reset).

Declarative Configuration

LogCanvas can be configured declaratively from initialization file. All configuration properties names are in lower-case. Spaces around all properties names and values are ignored. If some property is specified more than one time, the last occurrence prevails.

LogCanvas supports following properties.

Property Name

Description

Default Value

"bgcolor"

Specifies background color of text.

Since version 1.0

002F00 (dark green)

"fgcolor"

Specifies foreground color of text.

Since version 1.0

FFFFFF (white)

"font"

Specifies font to use for rendering text. The format of this property is
<Face>,<Style>,<Size>

Face = PROPRTIONAL|MONOSPACE|SYSTEM

Style = (PLAIN|BOLD|ITALIC|UNDERLINED)(;(PLAIN|BOLD|ITALIC|UNDERLINED))*

Size = LARGE|MEDIUM|SMALL

Note No spaces are allowed. Keywords are case insensitive.

Since version 1.0

proportional,plain,small

"rungconreset"

Specifies whether garbage collector is running after buffer reset. if true, on or yes garbage collector is running, not otherwise.

Since version 1.0

true (is run)

"scrollbarcolor"

Specifies color of scrollbar.

Since version 1.0

00BF00 (green)

"scrollbarcursorcolor"

Specifies color of scrollbar's cursor at the middle positions.

Since version 1.0

FFFFFF (white)

"scrollbarcursoredgecolor"

Specifies color of scrollbar's cursor at the edge (top or bottom) positions.

Since version 1.0

EF1F00 (dark red)

For example following initialization file snippet configures LogCanvas to not run garbage collector on buffer reset, sets font to proportional, bold, italic and small, background color to white, foreground - black, scrollbar - gray, scrollbar cursor at middle positions - yellow and scrollbar cursor at edge positions to white.

  #sets LogCanvas as logListener
  listener = momelog.listener.LogCanvas

  #don't run gc
  listener.rungconreset = off

  #view setting
  listener.font = proportional,bold;italic,small
  listener.bgcolor = FFFFFF
  listener.fgcolor = 0
  listener.scrollbarcolor = BFBFBF
  listener.scrollbarcursorcolor = EFEF00
  listener.scrollbarcursoredgecolor = FFFFFF

Programmatical Configuration

LogCanvas class extends GameCanvas abstract class. It can be configured like any other Canvas. Users can add/remove commands, set CommandListener, title, ticker or fullscreen mode. See JavaME API Documentation for details. LogCanvas is preset with the title of "Logging". No commands are added, and no CommandListener is set. It is initially not in fullscreen mode.

LogCanvas provides also means for it's own specific configuration. It is possible to configure LogCanvas view and behavior by invoking respective setter methods.

Font used for rendering text can be set by using setFont(Font font) method. Background or foreground colors can be configured by calling setBgColor(int color) or setFgColor(int color) respective methods. Users can set scrollbar, scrollbar's cursor at the middle positions or scrollbar's cursor at the edge positions colors by invoking setScrollbarColor(int color), setScrollbarCursorColor(int color) or setScrollbarCursorEdgeColor(int color) respective methods. By using setRunGCOnReset(boolean run) it is possible to set whether garbage collector is running after buffer reset.

All of the above methods except setRunGCOnReset(boolean run) should be called, when LogCanvas is hidden. In other case these methods throw IllegalStateException.

All of the above methods can be called at any time (when LogCanvas is hidden ;-)), but in typical use they are called at the start of the application's run (e.g. in MIDlet.startApp() method). For example in MIDlet SomeMIDlet.

    ...

    protected void startApp()
    {
      if( !started)
      {
        // in a case (recommended) MoMELog is configured declaratively to use LogCanvas
        // just obtaining it's instance.
        //LogCanvas logScr = (LogCanvas) Logger.getLogListener();

        // instantiating LogCanvas
        LogCanvas logScr = new LogCanvas();

        // ordinary Canvas configuration.
        logScr.addCommand( BACK);
        logScr.setCommandListener( this);

        // LogCanvas specific configuration.

        // font setting
        logScr.setFont( Font.getFont( Font.MONOSPACE,FONT.PLAIN,Font.SMALL);
        // background color setting
        logScr.setBgColor(0xFFFFFF);
        // foreground color setting
        logScr.setFgColor(0);
        // color of scrollbar setting
        logScr.setScrollbarColor(0xBFBFBF);
        // color of scrollbar's cursor at middle setting
        logScr.setScrollbarCursorColor(0xEFEF00);
        // color of scrollbar's cursor at edges setting
        logScr.setScrollbarCursorEdgeColor(0xFFFFFF);

        // configuring MoMELog to use LogCanvas for processing logging events.
        // if MoMELog is already configured declaratively to use it, this is redundant.
        Logger.setLogListener( logScr);

        ...

        started = true;
      }

      ...

    }

    ...

}


Sergio Morozov. 2007