Optimizing "simplifier"
Algorithm
The algorithm works well enough. You have captured the essence of the problem in your code, and reading your code it is apparent what it does, and why.
This is a good thing. It is not very often that the intent of the code is so easy to discern.
The draw-back of your algorithm is that it is not going to be able to support the more esoteric operations like parenthesis e.g. ( 123 - 45 ) ^ 2 .... That sort of support will require a preprocessing step.
Keeping the equation as a string is convenient for some things, but i would have preferred to see the process broken down in to components, for example, a parse step could break the input down to List&lt;String&gt; eqnParts = parse(eqn). at the same time, it could be trimming the white-space. Then, you just need to scan the List&lt;String&gt; and find 3 items separated by the highest precedence operator, and swap all three with the resulting value.
Code Style
You should read through the Code Style Guidelines for Java.
This code, for example, has a number of faults:

        for( i = left.length() - 1; i &gt;= 0; i--)
            if(!isPONumber(left.charAt(i)))
                break;
        for( j = 0; j &lt; right.length(); j++)
            if(!isPONumber(right.charAt(j)))
                break;


It should rather look something like:
        for (int i = left.length() - 1; i &gt;= 0; i--) {
            if(!isPONumber(left.charAt(i))) {
                break;
            }
        }
        for (int j = 0; j &lt; right.length(); j++) {
            if(!isPONumber(right.charAt(j))) {
                break;
            }
        }

Notes:

declare int i and int j inside the loop.
space after the keyword for.
braces even for '1-liner' conditional statements.

Double.parseDouble
Double.parseDouble() throws the unchecked exception NumberFormatException.
The exception thrown does not give great deals of information about why the number is not valid.
I always recommend wrapping Double.parseDouble (and Integer.parseInteger(), etc.) in a try-catch that reports what value was parsed, as well as the exception that was thrown. Otherwise debugging is a pain.
I often have a helper function like:
public static final double parseDouble(String value) {
    try {
        return Double.parseDouble(value);
    } catch (NumberFormatException nfe) {
        throw new IllegalArgumentException(&quot;Unable to Double.parseDouble(&quot; + value + &quot;)&quot;, nfe);
    }
}