Any problem with this Java

import android.content.Context;
import android.util.Log;
import com.google.appinventor.components.annotations.*;
import com.google.appinventor.components.runtime.*;
import com.google.appinventor.components.common.ComponentCategory;

@DesignerComponent(version = 1.0,  description = "This is an extension used to convert one unit to another unit<br><b>Creator: </b>Ruthenium Alpha",
        category = ComponentCategory.EXTENSION,
        nonVisible = true,   iconName = "http://appyBuilder.com/extensions/icons/extension.png")
@SimpleObject(external = true)
public class Number_formatter extends AndroidNonvisibleComponent {
  private ComponentContainer container;
  public Number_formatter(ComponentContainer container) {
      super(container.$form());
      this.container = container;
  }
  @SimpleFunction(description = "Converts a length unit to another length unit")
  public String ConvertLengthUnit(String FromUnit, String ToUnit, int Value) {
    if (FromUnit == "mm") {
      if (ToUnit == "mm") {
      return (Value*1);
      }
      else if (ToUnit == "cm") {
      return (Value/10);
      }
      else if (ToUnit == "m") {
      return (Value/1000);
      }
      else if (ToUnit == "km") {
      return (Value/1000000);
      }
    }
    else if (FromUnit == "cm") {
      if (ToUnit == "mm") {
      return (Value*10);
      }
      else if (ToUnit == "cm") {
      return (Value*1);
      }
      else if (ToUnit == "m") {
      return (Value/100);
      }
      else if (ToUnit == "km") {
      return (Value/100000);
      }
    }
    else if (FromUnit == "m") {
      if (ToUnit == "mm") {
      return (Value*1000);
      }
      else if (ToUnit == "cm") {
      return (Value*100);
      }
      else if (ToUnit == "m") {
      return (Value*1);
      }
      else if (ToUnit == "km") {
      return (Value/1000);
      }
    }
    else if (FromUnit == "km") {
      if (ToUnit == "mm") {
      return (Value/1000000);
      }
      else if (ToUnit == "cm") {
      return (Value/100000);
      }
      else if (ToUnit == "m") {
      return (Value/1000);
      }
      else if (ToUnit == "km") {
      return (Value*1);
      }
    }
  }
}

Hi, I am trying to make my first extension which is a unit converter in Code Editor AppyBuilder. When I compiled the aix it says there is an error. But I am not abled to find the problem. Can anyone help.

Thank you.....

@Alpha2020 maybe share the error

Buildfile: /projects/goldv2/appinventor-sources/appinventor/build.xml

extensions:

clean:

init:

common_CommonUtils:

init:

CommonUtils:

common_CommonVersion:

init:

CommonVersion:
     [exec] Result: 128
     [exec] Result: 128

CopyToRunLibDir:

components_AndroidRuntime:

init:

CommonConstants:
    [javac] Compiling 6 source files to /projects/goldv2/appinventor-sources/appinventor/components/build/classes/CommonConstants
    [javac] warning: [options] bootstrap class path not set in conjunction with -source 1.7
    [javac] 1 warning

HtmlEntities:
    [javac] Compiling 1 source file to /projects/goldv2/appinventor-sources/appinventor/components/build/classes/HtmlEntities
    [javac] warning: [options] bootstrap class path not set in conjunction with -source 1.7
    [javac] 1 warning

common_CommonVersion:

init:

CommonVersion:
     [exec] Result: 128
     [exec] Result: 128

AndroidRuntime:
    [javac] Compiling 332 source files to /projects/goldv2/appinventor-sources/appinventor/components/build/classes/AndroidRuntime
    [javac] warning: [options] bootstrap class path not set in conjunction with -source 1.7
    [javac] /projects/goldv2/appinventor-sources/appinventor/components/src/com/appybuilder/rutheniumalpha/UnitConverter/UnitConverter.java:12: error: class Number_formatter is public, should be declared in a file named Number_formatter.java
    [javac] public class Number_formatter extends AndroidNonvisibleComponent {
    [javac]        ^
    [javac] /projects/goldv2/appinventor-sources/appinventor/components/src/com/google/appinventor/components/runtime/Component.java:13: error: cannot access ComponentConstants
    [javac] import com.google.appinventor.components.common.ComponentConstants;
    [javac]                                                ^
    [javac]   bad class file: /projects/goldv2/appinventor-sources/appinventor/build/components/CommonConstants.jar(com/google/appinventor/components/common/ComponentConstants.class)
    [javac]     illegal start of class file
    [javac]     Please remove or make sure it appears in the correct subdirectory of the classpath.

BUILD FAILED
/projects/goldv2/appinventor-sources/appinventor/build.xml:35: The following error occurred while executing this line:
/projects/goldv2/appinventor-sources/appinventor/build-common.xml:372: The following error occurred while executing this line:
/projects/goldv2/appinventor-sources/appinventor/components/build.xml:141: The following error occurred while executing this line:
/projects/goldv2/appinventor-sources/appinventor/build-common.xml:118: Compile failed; see the compiler error output for details.

Total time: 2 seconds
s to /projects/goldv2/appinventor-sources/appinventor/components/build/classes/AndroidRuntime
    [javac] warning: [options] bootstrap class path not set in conjunction with -source 1.7
    [javac] /projects/goldv2/appinventor-sources/appinventor/components/src/com/appybuilder/rutheniumalpha/UnitConverter/UnitConverter.java:12: error: class Number_formatter is public, should be declared in a file named Number_formatter.java
    [javac] public class Number_formatter extends AndroidNonvisibleComponent {
    [javac]        ^
    [javac] /projects/goldv2/appinventor-sources/appinventor/components/src/com/google/appinventor/components/runtime/Component.java:13: error: cannot access ComponentConstants
    [javac] import com.google.appinventor.components.common.ComponentConstants;
    [javac]                                                ^
    [javac]   bad class file: /projects/goldv2/appinventor-sources/appinventor/build/components/CommonConstants.jar(com/google/appinventor/components/common/ComponentConstants.class)
    [javac]     illegal start of class file
    [javac]     Please remove or make sure it appears in the correct subdirectory of the classpath.

BUILD FAILED
/projects/goldv2/appinventor-sources/appinventor/build.xml:35: The following error occurred while executing this line:
/projects/goldv2/appinventor-sources/appinventor/build-common.xml:372: The following error occurred while executing this line:
/projects/goldv2/appinventor-sources/appinventor/components/build.xml:141: The following error occurred while executing this line:
/projects/goldv2/appinventor-sources/appinventor/build-common.xml:118: Compile failed; see the compiler error output for details.

Total time: 3 seconds

Your ans is int value or may be it float because you are using decision operation so please change your return type to float.

Ok :thinking:

How can I change?

Hello @Alpha2020,
It seems that your code returns a value in case the user has input m , cm, km for the FormatUnit and ToUnit .But what in the case the user has input something different, your code will not return anything. So you would probably get an error missing return statement,etc.. You can either try to add a return statement before the end of your method that returns an empty string, your code shouldn't get there except if the user has input a value which your if-then didn't use , or it would have break on a previousreturn statement, here is an example:

public String Test(String str) {
  if (str == "test") {
    return "it's test";
  } else if (str == "production") {
    return "we are in production";
  }
  return "unknown value"; // if we got here do the value is neither equal to test nor equal to production.
}

You could also add an else condition for all of the if-then statements.But it wouldn't be a good solution, as it would unnessecceraly make your code massive.
Lastly, you could use a local result variable initialized to "unknown value", and instead of returning just assign the result to this variable and return it at the end of your method, in case value has been assigned to it, it will remain "unknown value", example:

public String Test(String str) {
  String result = "unknown value";
  if (str == "cm") {
    result = "that's cm";
  } else if (str == "km") {
    result = "that's km";
  }
  return result;
}

Another possible error would be that you're returning an int,while you've defined the return type to String, you should change it into int.

Also as the log says your outer public class should be with the same name as your filename (in appybuilder case it would be the project name)
Also, using many if-then code isn't always useful,try to use if then return statement instead, example:

if ( FromUnit == "String") {
  return ToUnit == "cm" ? "Some value" : (ToUnit == "m" ? "Some other value" : (ToUnit == "km" ? "Some new value" : "unknown input"));
}

Note: please follow the naming conventions in your blocks, and class name, see also here:

Note2: It's java and not java script :sweat_smile: I've changed your title accordingly.

5 Likes

Ok let me check. Thank you for additional informations

2 Likes

Hi @MohamedTamer , I think you are good at extension development. If possible can you please edit the code thet I have send at first and make it correct so I can learn the problem. I am a beginner.

Thank you @MohamedTamer for your help :pray: :slightly_smiling_face:

1 Like

This is an edited code with changes I stated above that could cause errors :

import android.content.Context;
import android.util.Log;
import com.google.appinventor.components.annotations.*;
import com.google.appinventor.components.runtime.*;
import com.google.appinventor.components.common.ComponentCategory;

@DesignerComponent(version = 1, description = "This is an extension used to convert one unit to another unit<br><b>Creator: </b>Ruthenium Alpha",
            category = ComponentCategory.EXTENSION,
            nonVisible = true,
            iconName = "http://appyBuilder.com/extensions/icons/extension.png")
@SimpleObject(external = true)
public class FileName extends AndroidNonvisibleComponent { //the name of the project name.
      private ComponentContainer container;
      public FileName(ComponentContainer container) { //the Extension constructor, creates a new unit converter extension.
          super(container.$form());
          this.container = container;
      }
     @SimpleFunction(description = "Converts a length unit to another length unit")
      public int ConvertLengthUnit(String fromUnit, String toUnit, int value) { // the return type usdefined as an int , as this method is returning a number.
        if (fromUnit == "mm") {
          if (toUnit == "mm") {
          return (value * 1);
          }
          else if (toUnit == "cm") {
          return (value / 10);
          }
          else if (toUnit == "m") {
          return (value / 1000);
          }
          else if (toUnit == "km") {
          return (value / 1000000);
          }
        }
        else if (fromUnit == "cm") {
          if (toUnit == "mm") {
          return (value * 10);
          }
          else if (toUnit == "cm") {
          return (value * 1); // note: would multiplying by one change the value?
          }
          else if (toUnit == "m") {
          return (value / 100);
          }
          else if (toUnit == "km") {
          return (value / 100000);
          }
        }
        else if (fromUnit == "m") {
          if (toUnit == "mm") {
          return (value * 1000);
          }
          else if (toUnit == "cm") {
          return (value * 100);
          }
          else if (toUnit == "m") {
          return (value * 1);
          }
          else if (toUnit == "km") {
          return (value / 1000);
          }
        }
        else if (fromUnit == "km") {
          if (toUnit == "mm") {
          return (value / 1000000);
          }
          else if (toUnit == "cm") {
          return (value / 100000);
          }
          else if (toUnit == "m") {
          return (value / 1000);
          }
          else if (toUnit == "km") {
          return (value * 1);
          }
        }
       return -1; //the user has input an invalid input.
      }
    }

Note: change the class name and the constructor name The line public FileProjectName(ComponentContainer container) to your project name.

3 Likes

Thank you very much!!

1 Like

Please change your method's return type to float for more accurate answer.

It should work with integers , but of course decimal values will be rounded down ( i.e: 10.656455 would be 10 ) , I'm not sure if this is what does the original poster want or not ( as the original code was using integers ) , but if not, floats can be used in this case, this is an example:

import android.content.Context;
import android.util.Log;
import com.google.appinventor.components.annotations.*;
import com.google.appinventor.components.runtime.*;
import 
com.google.appinventor.components.common.ComponentCatego
ry;

@DesignerComponent(version = 1, description = "This is 
an extension used to convert one unit to another 
unit<br><b>Creator: </b>Ruthenium Alpha",
            category = ComponentCategory.EXTENSION,
            nonVisible = true,
            iconName = 
"http://appyBuilder.com/extensions/icons/extension.png")
@SimpleObject(external = true)
public class FileName extends AndroidNonvisibleComponent 
{ //the name of the project name.
      private ComponentContainer container;
      public FileName(ComponentContainer container) { 
//the Extension constructor, creates a new unit 
converter extension.
          super(container.$form());
          this.container = container;
      }
     @SimpleFunction(description = "Converts a length 
unit to another length unit")
      public float ConvertLengthUnit(String fromUnit, 
String toUnit, float value) { // the return type 
usdefined as an int , as this method is returning a 
number.
        if (fromUnit == "mm") {
          if (toUnit == "mm") {
          return (value * 1);
          }
          else if (toUnit == "cm") {
          return (value / 10);
          }
          else if (toUnit == "m") {
          return (value / 1000);
          }
          else if (toUnit == "km") {
          return (value / 1000000);
          }
        }
        else if (fromUnit == "cm") {
          if (toUnit == "mm") {
          return (value * 10);
          }
          else if (toUnit == "cm") {
          return (value * 1); // note: would multiplying 
by one change the value?
          }
          else if (toUnit == "m") {
          return (value / 100);
          }
          else if (toUnit == "km") {
          return (value / 100000);
          }
        }
        else if (fromUnit == "m") {
          if (toUnit == "mm") {
          return (value * 1000);
          }
          else if (toUnit == "cm") {
          return (value * 100);
          }
          else if (toUnit == "m") {
          return (value * 1);
          }
          else if (toUnit == "km") {
          return (value / 1000);
          }
        }
        else if (fromUnit == "km") {
          if (toUnit == "mm") {
          return (value / 1000000);
          }
          else if (toUnit == "cm") {
          return (value / 100000);
          }
          else if (toUnit == "m") {
          return (value / 1000);
          }
          else if (toUnit == "km") {
          return (value * 1);
          }
        }
       return -1; //the user has input an invalid input.
      }
    }
2 Likes

Hi, I also wanted to ask is there any way to add sin, tan and pi to extensions

i think you will need to use a android library i don't know which

No if you want to use mathematic function in your extension you need to import math class in your extension

How can I inport

import java.lang.Math

1 Like

Thank you.....

Math.PI

because PI is static variable of class Math so you not need to create object of the class.