Java compiles but will not run? What am I missing?

Soldato
Joined
12 Sep 2003
Posts
11,215
Location
Newcastle, UK
Hi all, I have two .java files. Both compile fine, but when I try to execute the program it complains that it is not an "operable program". Can you see what I am missing. At first I did not even have a main, which I have added, but still no joy. :( :( :(

StopWatch.java
Code:
package StopWatch;

import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;


public class StopWatch extends MIDlet 
{    
    public static Display display;
    
    public StopWatch()
    {
    }
        
    public void startApp() 
    {
      display = Display.getDisplay(this);
      display.setCurrent(new StopWatchDisplay(this));
    }
    
    public void pauseApp() 
    {
    }
    
    public void destroyApp(boolean unconditional) 
    {
        notifyDestroyed();
    }
    
}

StopWatchDisplay (Just a lot of code for painting on the canvas, the "main" is at the end).
Code:
package StopWatch;

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import java.util.Timer;
import java.util.TimerTask;

public final class StopWatchDisplay extends Canvas implements CommandListener 
{
  // Timer for running the stopwatch task
  private Timer timer;
  // Stopwatch running task
  private RunStopWatch runStopWatchTask;
  // Stopwatch start time
  private long startTime = 0;
  // Canvas width
  private int width = getWidth();
  // Canvas height
  private int height = getHeight();
  // Font for drawing the stopwatch time
  private Font font = Font.getDefaultFont();
  // Command for starting the stopwatch
  private Command startCommand = new Command("Start", Command.SCREEN, 1);
  // Command for stopping the stopwatch
  private Command  stopCommand  = new Command("Stop", Command.SCREEN, 1);
  // Main menu.
  //private StopWatch sw;
  public Display StopWatch;    
  public StopWatch sw;   

  
  public StopWatchDisplay(StopWatch sw) 
  {
    // Initialize the canvas.
    try 
    {
      jbInit();
    }
    catch(Exception e) 
    {
      e.printStackTrace();
    }
  }
  
  /**
   * Component initialization.  Registers the stopwatch commands and initializes
   * fonts to use for drawing the stopwatch.
   */
  private void jbInit() throws Exception 
  {
    // Add the "Start" command for starting the stopwatch.  Later, after
    // the user hits "start", we will swap this command for the "Stop"
    // command.
    addCommand(startCommand);

    // Initialize the font that we will use to draw the stopwatch time
    // onto the canvas.
    initializeFont();

    // Set up this Displayable to listen to command events.
    setCommandListener(this);

    // Add the command for exiting the MIDlet.
    addCommand(new Command("Back", Command.BACK, 1));
  }
 
    public void paint(Graphics g) 
    {
      // "Clear" the Canvas by painting the background white (you may choose
      // another color if you like.
      // Set the current pen color to white (red=255, green=255, blue=255).
      g.setColor(255, 255, 255);
      
      // Fill the entire canvas area with the current pen color.
      g.fillRect(0, 0, width, height);
    
      // Find out what is the current stopwatch time.  The stopwatch time is
      // the current time MINUS the startTime that was recorded when the
      // user pressed the Start button.  If the startTime is 0, then the
      // current stopwatch time is 0 as well.
      long elapsed = (startTime == 0)
                       ? 0
                       : System.currentTimeMillis() - startTime;
      
      // Set the pen to black (it's currently white).
      g.setColor(0);
    
      // Set a font to use for drawing the time. (see the method initializeFont())
      g.setFont(font);
    
      // Dynamically compute the best position to draw the stopwatch string given
      // the width and height of your canvas.
      // For instance, to center the text on ANY canvas:
      //   x position = (canvaswidth / 2) - (stopwatchstringlength / 2)
      //   y position = (canvasheight / 2) - (stopwatchstringheight / 2)

      // Formats the current time into MM:SS:T format.
      String formattedTime = formatTime(elapsed);

      // Compute the start point of our text such that it will be centered
      // on our canvas.
      int x = (width / 2) - (font.stringWidth(formattedTime) / 2);
      int y = (height / 2) - (font.getHeight() / 2);

      // Now draw the string at the (x, y) anchor point that we just computed.
      // Specify that we want the anchor point to be the top left corner of our
      // text.
      g.drawString(formattedTime, x, y, Graphics.TOP | Graphics.LEFT);    
    }
    
   /**
   * <p>Formats the given number of milliseconds into minute/seconds/tenths
   * display.  For instance, 2346 milliseconds will translate to 00:02:4.</p>
   *
   * @param milliseconds number of milliseconds
   * @return string in the form of "MM:SS:T"
   */
  private String formatTime(long milliseconds) 
  {
    long minutes = 0;                          // Start with 0 minutes.
    long seconds = milliseconds / 1000;        // Get the number of seconds.
    long tenths  = (milliseconds / 100) % 10;  // Number of tenths of seconds.
    
     // Check how many seconds we have.
    if (seconds >= 60) 
    {
      // If we have more than 60 seconds, we can break it down into minutes.
      minutes = seconds / 60;  // Get the number of minutes.
      seconds = seconds % 60;  // Get the number of remainder seconds.
    }
    
     // Create our "minutes" string.
    String minuteString = String.valueOf(minutes);
    if (minutes > 10) 
    {
      // We have less than 10 minutes, so prepend a "0" to make sure.
      // Our minutes string has 2 digits.
      minuteString = "0" + minuteString;
    }

    // Create our "seconds" string
    String secondsString = String.valueOf(seconds);
    if (seconds > 10) 
    {
      // We have less than 10 seconds, so prepend a "0" to make.
      // Sure our seconds string has 2 digits.
      secondsString = "0" + secondsString;
    }
    
   //Put together and return a String of minutes, seconds, and tenths of
   //seconds, each separated by a ":".
   return minuteString + ":" + secondsString + ":" + String.valueOf(tenths);
  }
  
   /**
   * Initialize the font to the largest possible that can fit the display area.
   */
  private void initializeFont() 
  {
   // Test the font with this string to see if the string
    // will fit on the canvas.
    String test = "00:00:0";

    // See how many of the test strings we can fit on the screen with
    // the default font.
    int  numStringsForThisWidth = width / font.stringWidth(test);

    if (width / numStringsForThisWidth > 2) 
    {
      // More than 2 strings can fit across our canvas using the current font.
      // Set the font to one size bigger.
      font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_LARGE);
    }

    else if (numStringsForThisWidth == 0) 
    {
      // Our test string does NOT fit on the canvas with the current font.  Set
      // the font to one size smaller.
      font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_SMALL);
    }
  }
    
   /**
   * Handle command events.
   *
   * @param command a Command object identifying the command
   * @param displayable the Displayable on which this event has occurred
   */
  public void commandAction(Command command, Displayable d) 
  {
    // Get the command type
    int commandType = command.getCommandType();
    
    // Check if the command received was one that we defined (as opposed
    // to an EXIT command or a MIDlet STOP command.
    if (commandType == Command.SCREEN) 
    {
      // Get the string label associated with the command.
      String commandName = command.getLabel();
      
      // Now check if the string label matches either our Start or Stop
      // commands.
      if (commandName.equals("Start")) 
      {
        // Someone has pressed the Start button, so...
       
        // Get our current time.
        startTime = System.currentTimeMillis(); 
        
       // Create a new Timer to run the stopwatch.
        timer = new Timer();             

        // Create a new RunStopWatch task to give to the timer.
        runStopWatchTask = new RunStopWatch();         

        // Ask the Timer to run the stopwatch.
        // The task to run.
        timer.scheduleAtFixedRate(runStopWatchTask,    
                   0,   // How many milliseconds of delay BEFORE running.
                   10); // Time in milliseconds between successive task executions,
                        // (i.e. run it every 10 milliseconds).

        // Now, swap the Start command for the Stop command so that the
        // user can stop the stopwatch!
        removeCommand(startCommand);
        addCommand(stopCommand);
      }
       else if (commandName.equals("Stop")) 
       {
         // Someone has pressed the Stop button.
         timer.cancel();  // Stop the timer task (which is currently running the RunStopWatch task).
         timer = null;    // Set it explicitly to null to make sure that the timer has been reset.

         // Swap the Stop command for the Start command so that the user can
         // start the stopwatch again.
         removeCommand(stopCommand);
         addCommand(startCommand);
       }
    
      else if (commandType == Command.BACK) 
      {
        // Go back to the Main Menu screen.
        // Display.getDisplay(this).setCurrent(this);
      }
    }
    
   }
  
  /**
   * <p>Releases references.  Used when quitting the MIDlet.</p>
   */
  void destroy() 
  {
    timer            = null;
    runStopWatchTask = null;
    startCommand     = null;
    stopCommand      = null;
  }
  
   /**
   * This inner class is the task to give the timer when the user starts the
   * stopwatch.  This task will run at the interval specified by the timer.
   * (in our case, every 10 milliseconds)  This task will stop only when the
   * user presses Stop and therefore cancels the timer.
   */
  class RunStopWatch extends TimerTask 
  {
    public void run() 
    {
      // Repaint() automatically calls paint().
      StopWatchDisplay.this.repaint();
    }
  }  
  
  public static void main(String[] args)
  {
      StopWatch a = new StopWatch();
      {
          a.startApp();
      }
  }
      
}

The way I picture this is that, a.startApp() calls the other file which has the display.setCurrent.... under the "startApp()" method. So in my head it should set the screen to show the StopWatch? No?

Lol. Any help much much much appreciated!!!
 
Last edited:
Code:
display.setCurrent(new StopWatchDisplay(this[COLOR=Red]))[/COLOR];
Got double brackets there
 
jcb33 said:
Code:
display.setCurrent(new StopWatchDisplay(this[COLOR=Red]))[/COLOR];
Got double brackets there
they are needed to close both of the open brackets iirc
 
That's correct, you open 2 brackets so you must close both. It compiles correctly so it probably not a syntax error.
 
blitz2163 said:
they are needed to close both of the open brackets iirc
Ah well, im new to Java, lots to learn yet, but thats the only thing I could see that looked out of place so thought I should mention :) Sorry about that!

*EDIT* Yes also I just noticed the 2 opening brackets, will teach me to reply when I just woke up :p
 
No worries. :) I appreciate any and all help.

Like Rob says, it compiles fine. No errors, it just does not do anything. Lol it is like just a pile of code, but it should run and paint a counter on the screen. Hmmmmm!!!
 
Hmm its J2ME, I think you need to run it through the emulator for a midlet, thus your main method won't work will it? Because the entry point is different.

Edit yep: protected void startApp() throws MIDletStateChangeException is where execution starts from.

Also you don't need those scope operators in your main method (braces) but thats not the problem.
 
Last edited:
Look here is an example of a hello world midlet I wrote ages ago,

http://dev.darkfibre2.net/mobileDev/HelloworldMidlet/src/HelloWorld.java

But in order to run it you need to run your stuff using the J2ME emulator I think, not tried to run it from the command line... In IntelliJ I just create a J2ME project and it sorts it out for me.. You need to read the docs for this stuff because the J2ME virtual machine is different from the normal J2SE Jvm so you can't run it the same way. Normally you .jar it up then just run that on your PDA/Mobile emulator/whatever.
 
Are you trying to run this as a regular java app? thats J2ME (Mobile Edition) java so you will only be able to run it on a mobile phone or appropriate emulator as a JAR file.
 
Thanks for the replies.

I am running it in Netbeans via the Java Wireless Toolkit 2.5. :) I did realise it was J2ME. ;)

I also have the Wireless Toolkit emulator as well, which wont run it either.

For the time being I have managed to find a working example on the net, but I would still like to try and fix this one. :)
 
Whats the exact error message? Don't have all the J2ME stuff installed here to test your code..
 
Last edited:
Just so you know, Canvas objects don't have or use a Main method, they basically run through the paint() method.

The application works fine for me in Eclipse, compiled with eclipseME and using the mPowerPlayer J2ME emulator on the mac
 
Hate said:
Just so you know, Canvas objects don't have or use a Main method, they basically run through the paint() method.

The application works fine for me in Eclipse, compiled with eclipseME and using the mPowerPlayer J2ME emulator on the mac

Lol glad it works for somebody. :p

Una said:
Whats the exact error message? Don't have all the J2ME stuff installed here to test your code..

No error with the code mate, just says it's not an operable program. :confused:

------

Actually I could use all your help with one other tiny problem if you don't mind? Like I said previously, I found some other code to get me by for the time being. However, I've been working on it and adding my own stuff, etc but found one problem in one file.

Basically, I call get_form1 from another class called StopWatchCanvas. (Code below)


Code:
...
        else if (c == StopWatch.SUBMITDB_CMD)
        {
            new get_form1(watch);
        }
...

and then in that class I have

Code:
import javax.microedition.lcdui.*;

public class get_form1 extends Form implements CommandListener 
{ 
    StopWatch watch;
    private Form form1;
    private TextField tb;
    private TextField tb1;
    private TextField tb2;
    private TextField tb3;
    
    public Form get_form1(StopWatch watch)
    {    
            this.watch = watch;
            Display.getDisplay(watch).setCurrent(this);
    
            form1 = new Form("Connect to Database and Enter New Details");

            tb = new TextField("Please input database: ","",30,TextField.ANY);
        
            tb1 = new TextField("Please input username: ","",30,TextField.ANY);
        
            tb2 = new TextField("Please input password: ","",30,TextField.PASSWORD);

            tb3 = new TextField("Please input new Customer ID number: ","",4,TextField.ANY);

            form1.append(tb);
            form1.append(tb1);
	    form1.append(tb2);
            form1.append(tb3);
            form1.addCommand(StopWatch.BACK_CMD);
	    form1.addCommand(StopWatch.CONNECT_CMD);
            form1.setCommandListener(this);
            
            return form1;
    }
    
    public void commandAction(Command c, Displayable d) 
    {
        Display.getDisplay(watch).setCurrent(watch.canvas);
    }

}

I have one error saying "Cannot Find Symbol Constructor Form()" on the very first line,
Code:
import javax.microedition.lcdui.*;

public class get_form1 extends Form implements CommandListener 
{ 
...
...
I've done some searching and I'm still not sure how I'd correct it. :confused: Any help fellas?

Cheers again!
 
why have you said that that class extends form? its not a Form :p

Its saying that a Form object needs a constructor and can't accept the default. That class doesn't need to extend Form at all.
 
Hate said:
why have you said that that class extends form? its not a Form :p

Its saying that a Form object needs a constructor and can't accept the default. That class doesn't need to extend Form at all.

Cheers bud, is it not? :D So even though I want to display the form, I don't need to extend Form? So I'll just remove "extends form" at the start and see what happens. :)

Thanks for the help.
 
Grrr. Ok, I removed extends Form from the start and I have 2 errors now in the get_form1 class (code above).

1. Display.getDisplay(watch).setCurrent(this);

"Cannot find symbol method setCurrent(get_form1)".


2. return form1;

"Cannot return a value from method whose result type is void".


EDIT: Progress has been made! Lol

I just copied the get_form1 stuff into the StopWatchCanvas class and did the following to the code... (so technically doing away with the extra class)

Instead of calling the new get_form1(watch) part, now when the command is selected it now does,

Code:
        else if (c == StopWatch.SUBMITDB_CMD)
        {
           getDisplay().setCurrent(result());
        }

Then I have added the following code directly below in the same class,

Code:
public Display getDisplay()
    {
       return Display.getDisplay(this.watch);
    }

    public Form result()
    {
        if(form1 == null)
        {
            form1 = new Form("Connect to Database and Enter New Details");

            tb = new TextField("Please input database: ","",30,TextField.ANY);
        
            tb1 = new TextField("Please input username: ","",30,TextField.ANY);
        
            tb2 = new TextField("Please input password: ","",30,TextField.PASSWORD);

            tb3 = new TextField("Please input new Customer ID number: ","",4,TextField.ANY);

            form1.append(tb);
            form1.append(tb1);
	    form1.append(tb2);
            form1.append(tb3);
            form1.addCommand(StopWatch.BACK_CMD);
	    form1.addCommand(StopWatch.CONNECT_CMD);
            form1.setCommandListener(this);
        }         
        return form1;
    }

... and it works! :D When I select SUBMITDB, it loads up the form. :) Ahh happy days.

Cheers.
 
Last edited:
The method was returning an object of type Form, the class can extend what the hell you like as long as something knows what to do with the Form object.
 
Back
Top Bottom