Hi everybody,
I'm working a program assignment for school. I thought my code was
good but it won't run. It compiles successfully but gives me this
error during runtime:
Exception in thread "main" java.lang.NoSuchMethodError
Do you have any advice? My code is below.
Thanks in advance,
Don
<-------------------------------------------------------------------------------------------------------------------------------------------------------
/*
Title: Mortgage Payment Calculator
Programmer: Don
Date: May 14, 2007
Filename: MortPayCalc.java
Purpose: This program calculates mortgage payment amounts.
*/
import java.text.DecimalFormat;
import javax.swing.JOptionPane;
class MortPayCalc2
{
private boolean end = false;
private DecimalFormat newFormat = new DecimalFormat ("$#,###.00");
private double dPrincipal, dAPR, dPayment, dCurrMonthInterest,
dCurrMonthPrincipal, dLoanBalance;
private double dLoanPrincipal = dPrincipal;
private int iTerm, iPayments, iOption;
private String Principal;
private String Table = "";
public void GetPrincipal()
{
Principal = JOptionPane.showInputDialog(null, "Enter Loan
Principal (ex. 20000): ", "Mortgage Payment
Calculator",JOptionPane.QUESTION_MESSAGE);
dPrincipal = Double.parseDouble(Principal);
}
public void GetLoanTerms()
{
Object[] possibilities = {"Loan A", "Loan B", "Loan C"};
String s = (String)JOptionPane.showInputDialog(null,"Please choose
your loan terms:\n",
"Mortgage Payment
Calculator",JOptionPane.PLAIN_MESSAGE,null,possibilities,"Loan A");
int [] Terms = {7, 15, 30};
double [] Rates = {5.35, 5.5, 5.75};
if (s == "Loan A")
{
iTerm = Terms[0];
dAPR = Rates[0];
}
else if (s == "Loan B")
{
iTerm = Terms[1];
dAPR = Rates[1];
}
else
{
iTerm = Terms[2];
dAPR = Rates[2];
}
}
public void CalculatePayment()
{
iPayments = iTerm * 12;
dAPR = dAPR/100/12;
dPayment = (dPrincipal*Math.pow((1+dAPR),iPayments)*dAPR)/
(Math.pow((1+dAPR),iPayments)-1);
}
public void CalculateAmortization()
{
for (int i = 0; i < iPayments; i++)
{
dCurrMonthInterest = dLoanPrincipal * dAPR;
dCurrMonthPrincipal = dPayment - dCurrMonthInterest;
dLoanBalance = dLoanPrincipal - dCurrMonthPrincipal;
dLoanPrincipal = dLoanBalance;
String Row = String.format(newFormat.format(dCurrMonthPrincipal) +
" " + newFormat.format(dCurrMonthInterest) + " " +
newFormat.format(dLoanBalance) + "\n");
Table = Table + Row;
}
}
public void DisplayResults()
{
iOption = JOptionPane.showConfirmDialog(null,
"Loan Principal: " + newFormat.format(dPrincipal) + "\n" +
"Loan Annual Percentage Rate: " + dAPR + "%" + "\n" +
"Loan Term In Years: " + iTerm + " years" + "\n" +
"Monthly Loan Payment Amount: " + newFormat.format(dPayment) +
"\n" +
Table + "\n\n" +
"Recalculate?",
"Mortgage Payment Calculator", JOptionPane.YES_NO_OPTION);
}
public void main(String[] args)
{
while (end == false)
{
GetPrincipal();
GetLoanTerms();
CalculatePayment();
CalculateAmortization();
DisplayResults();
if (iOption == JOptionPane.YES_OPTION)
{
end = false;
}
else
{
System.exit(0);
}
}
}
}
Daniel Pitts - 17 May 2007 19:35 GMT
> Hi everybody,
>
[quoted text clipped - 9 lines]
>
> Don
[snip]
> public void main(String[] args)
[snip]
This should be public static void main(String[] args)
Note the "static"
In the future, it might also help if you show us how you execute the
program.
Anyway, the main methods have to be static in order for the JVM to
find and execute it before the object itself is created.
Don - 17 May 2007 19:57 GMT
> > Hi everybody,
>
[quoted text clipped - 22 lines]
> Anyway, the main methods have to be static in order for the JVM to
> find and execute it before the object itself is created.
Sorry about that. I'm compiling and running the program using Textpad.
When run, the program is supposed to create an input dialog box so the
user can enter the principal amount of the loan and click an OK
button. Then, the another dialog box allows the user to choose Loan A,
Loan B or Loan C from a menu. Each loan plan has a different rate and
loan term in an array. Then, after clicking that OK button, another
dialog box is supposed to open with the payment and amortization
information. The user can then choose to recalculate or quit.
I made the main method static. Now, when compiling, I get this error
message for each of of the method references in the main method:
non-static method cannot be referenced from a static context
Any more advice? :-)
Lew - 17 May 2007 22:27 GMT
> I made the main method static. Now, when compiling, I get this error
> message for each of of the method references in the main method:
>
> non-static method cannot be referenced from a static context
>
> Any more advice? :-)
You can't use non-static methods from a static context. Such methods need an
instance of the class (usually created via a constructor) through which to
invoke them.
Basic rule of Java.
<http://java.sun.com/docs/books/tutorial/java/javaOO/usingobject.html>
"Calling an Object's Methods"

Signature
Lew
Mike Schilling - 17 May 2007 22:38 GMT
>> I made the main method static. Now, when compiling, I get this error
>> message for each of of the method references in the main method:
[quoted text clipped - 10 lines]
> <http://java.sun.com/docs/books/tutorial/java/javaOO/usingobject.html>
> "Calling an Object's Methods"
If that's not explicit enough advice, a common pattenr for a main() method
is:
class Foo
{
public static void main(String[] args)
{
Foo foo = new Foo();
foo.doSomething();
}
}
Mark Space - 17 May 2007 23:10 GMT
> If that's not explicit enough advice, a common pattenr for a main() method
> is:
[quoted text clipped - 7 lines]
> }
> }
And even more explicitly:
public static void main(String[] args)
{
while (end == false)
{
GetPrincipal();
GetLoanTerms();
CalculatePayment();
CalculateAmortization();
DisplayResults();
None of those last five lines call a static method. You need to
MortPayCalc2 morty = new MortPayCalc2();
morty.GetPrincipal();
// etc...
not invoke those methods "bare."
Mark Space - 17 May 2007 23:06 GMT
> Sorry about that. I'm compiling and running the program using Textpad.
I don't want to sound snarky, but I don't think you're running your
program with Textpad. Textpad isn't a JVM ;-) He means we need to see
the command line you execute because you might not be using defaults.
java MortPayCalc2
or whatever
Andrew Thompson - 18 May 2007 03:53 GMT
>> Sorry about that. I'm compiling and running the program using Textpad.
>
>I don't want to sound snarky, but I don't think you're running your
>program with Textpad. Textpad isn't a JVM ;-) He means we need to see
>the command line you execute because you might not be using defaults.
TextPad has menu items and hotkeys to (invoke the
J2SE tools to) compile source and run classes. There
is also a 'configuration' dialog for the launch parameters
of either.
That being said, I recommend the OP learn how to compile
and run from the command line, so they ..
a) have control over the process
b) understand what is possible
c) can answer questions like the one that prompted
the TextPad strand of the thread.
c) also ties into a).

Signature
Andrew Thompson
http://www.athompson.info/andrew/
Mark Space - 18 May 2007 04:31 GMT
> TextPad has menu items and hotkeys to (invoke the
> J2SE tools to) compile source and run classes. There
> is also a 'configuration' dialog for the launch parameters
> of either.
Does it really? I had no idea. Mea culpa. Still, we could have used
the command being invoked to run the class.
Thinking about this some more, the class is not public (it's default
package-private, I think.) And it's not in any package either. So
without testing to see if two classes at in the default package can
reference each other, and with out any changes (no static main) to the
original, this would work:
public class Runner {
public static main( String [] args ) {
MortPayCalc2 morty = new MortPayCalc2();
morty.main( args );
}
}
Certainly, if you put both these classes in the same file, it would
work. (Well, and the file was called Runner.java.)
Which may explain how your class was expecting to be used. It's a
slightly different idiom than the ones we were giving you.
Andrew Thompson - 18 May 2007 05:33 GMT
>> TextPad has menu items and hotkeys to (invoke the
>> J2SE tools to) compile source and run classes. There
[quoted text clipped - 3 lines]
>Does it really? I had no idea. Mea culpa. Still, we could have used
>the command being invoked to run the class.
I suspect they are the same as it comes 'out of the box'.
The command config. is broken into three fields, and
contains values like '$BaseName' & '$FileDir'.
..when it came to that point, I felt it was better to
ignore what TextPad was doing (right, wrong or
otherwise), and organise this from the command
line. ;-)

Signature
Andrew Thompson
http://www.athompson.info/andrew/
Richard Reynolds - 17 May 2007 21:33 GMT
> Hi everybody,
>
[quoted text clipped - 142 lines]
>
> }
All your methods are instance methods hence you need an "instance" object to
execute them against.
at the start of you main method try creating an instance (or object) of your
MortPayCalc2 class:
MortPayCalc2 mortgageCalculator = new MortPayCalc2();
then when you're executing any of your methods, execute them on this object
e.g.
mortgageCalculator.GetPrincipal();
mortgageCalculator.GetLoanTerms(); etc.
also, it's usual convention to name your methods like this: getPrincipal
i.e. starting with a lowercase letter, and classes with an uppercase letter
(as you have done)
Check out the difference between instance and class (or static) methods,
it's an important concept.