我尝试使用JavaFX和反向波兰表示法创建计算器。我们的想法是使用TextField读取用户的输入,然后将常用的中缀形式转换为后缀形式,按下按钮"等于"进行计算并显示输出。我希望它能够在双打上进行操作。从用户获取的示例公式是:
的((234 *(7-3))/ 2)
转换为postfix表单后,它应如下所示: 234 7 3 - * 2 /
经过一些麻烦后,我设法做到了,但只是作为使用控制台的测试。
当我将它与以前构建的JavaFX GUI连接时,它会抛出RunTime异常,我不知道它为什么会发生。所以,我将String标记存储在ArrayList中,这是我的解析方法:
public void parseExpression(String expr) {
char[] temp = expr.toCharArray();
StringBuffer stringBuffer = new StringBuffer();
List<String> list = new ArrayList<String>();
for (int i=0;i<temp.length;i++) {
if(temp[i]=='(' || temp[i]==')' || temp[i]=='+' || temp[i]=='-' || temp[i]=='*' || temp[i]=='/') {
list.add(Character.toString(temp[i]));
} else{
stringBuffer.append(temp[i]);
if ((i+1)<temp.length){
if (temp[i+1]=='(' || temp[i+1]==')' || temp[i+1]=='+' || temp[i+1]=='-' || temp[i+1]=='*' || temp[i+1]=='/'){
String number = stringBuffer.toString();
stringBuffer.setLength(0);
list.add(number);
}
}
}
}
for (String str: list){
System.out.print(str+" ");
}
}
我的后缀转换方法如下所示:
public void beginConvert(){
convertToONP(list.get(0));
}
public void convertToONP(String current) {
if (currIndex < list.size()) {
String a;
String c = current;
if (c.equals("(")) {
convertToONP(list.get(++currIndex));
a = list.get(currIndex);
convertToONP(list.get(++currIndex));
++currIndex;
System.out.print(a+" ");
} else {
System.out.print(c+" ");
++currIndex;
}
}
}
当我在Test类中运行这些方法时:
public class Test {
/*
*my methods methods
*/
public static void main(String[] args) {
Test test = new Test();
String formula = "(234+(2*3))";
test.parseExpression(formula);
System.out.println();
test.beginConvert();
}
}
这是输出:
(234 +(2 * 3))
234 2 3 * +
但是当我将这些方法放在连接到FXML文件的控制器类中的按钮的setOnAction方法中时:
@FXML
public void equalsPressed(){
calculator.parseExpression(formulaTextField.getText());
calculator.beginConvert();
}
这是输出:
(234 +(2 * 3))
线程中的异常&#34; JavaFX应用程序线程&#34; java.lang.RuntimeException:java.lang.reflect.InvocationTargetException
引起:java.lang.IndexOutOfBoundsException:索引:0,大小:0
在model.Calculator.beginConvert(Calculator.java:60)
有人可以向我解释为什么会这样吗?我非常感谢您提供的任何帮助
答案 0 :(得分:0)
我不明白为什么您的测试版本有效,但是:
从beginConvert()
方法看来,您有一个名为list
的实例字段。你可能在某处初始化(到一个空列表?)。
parseExpression()
方法不会将任何元素添加到实例字段list
:它会创建一个同名的局部变量:
List<String> list = new ArrayList<String>();
然后解析表达式并将元素添加到本地列表。实例字段list
永远不会在parseExpression().
所以(虽然没有看到完整的例子,但不可能确定无法确定),你可能打算在parseExpression()
中初始化实例变量。替换
List<String> list = new ArrayList<String>();
与
list = new ArrayList<String>();