过去几天我一直在研究一个java项目,虽然事情进展顺利,但我遇到了一些障碍。
项目的目的是创建一个排序查询,用户使用GUI界面搜索报告,并且应用程序会吐出所有相关数据。
Ex:报告所有质量> 3
我使用StringTokenizer对象来断开String并评估每个标记。第一个令牌必须是报告,第二个令牌必须全部,第三个令牌必须其中,第四个令牌必须是质量, basePrice 或 numInStock ,第五个标记必须是关系运算符(>< < = > = == )。如果任何令牌与它们应该匹配,我们被指示抛出自定义检查的异常。到目前为止,我已经评估了每个令牌,并throw
Exception
,如果预期的令牌不是它应该的那样。
现在,当我到达关系运算符后,我应该将其转储到名为String
的新optok
中。问题是,我似乎无法让我的程序执行此操作,并且我很难搞清楚如何执行此操作。我尝试过很多不同的东西,似乎没什么用。
最终目标是,一旦评估并检查了所有令牌,就调用方法来打印正确的查询以及与所述查询一起的所有数据。如果其中一个令牌不匹配,则Exception
为thrown
。
以下是我评估每个令牌的代码,以检查它是否格式正确:
public void detectUserInput(String input) throws MissingInputException
{
if (input.equals(""))
{
System.out.println("Null input");
throw new MissingInputException();
}
else
{
System.out.println("Input is not null");
}
}//end detectUserInput
public void countTokens(String input) throws IncorrectFormatException
{
StringTokenizer tokenLength = new StringTokenizer(input, " ,");
if (tokenLength.countTokens() < 6)
{
throw new IncorrectFormatException();
}
}//end countTokens
public void evaluateTokens(String input) throws IllegalStartOfQueryException,
InvalidSelectorException,
InvalidQualifierException,
InvalidLValueException,
InvalidOperatorException
{
StringTokenizer testTokens = new StringTokenizer(input, " ,");
if (!testTokens.nextToken().equalsIgnoreCase("report"))
{
throw new IllegalStartOfQueryException();
}
else if (!testTokens.nextToken().equalsIgnoreCase("all"))
{
throw new InvalidSelectorException();
}
else if (!testTokens.nextToken().equalsIgnoreCase("where"))
{
throw new InvalidQualifierException();
}
else if (!testTokens.nextToken().matches("quality|numInStock|basePrice"))
{
throw new InvalidLValueException();
}
else if (!testTokens.nextToken().matches(">|<|>=|<=|=="))
{
throw new InvalidOperatorException();
}
//here is where I try to take the relational operator
//and dump it into optok, after all the previous input
//has been validated, but it doesnt work :(
while (testTokens.hasMoreTokens())
{
tok = testTokens.nextToken();
if (tok.matches("<|>|>=|<=|=="))
{
optok = tok;
}
}
}//end evaluateTokens
以下是我的计划的actionPerformed()
,当用户将其查询输入TextField
并按 GO!
JButton
时,会对此做出反应:
private class ButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent ev)
{
if (ev.getSource() == goBtn)
{
input = queryFld.getText();
try
{
detectUserInput(input);
countTokens(input);
evaluateTokens(input);
}
catch (MissingInputException mie)
{
errorFld.setText("Enter an expression");
queryFld.setText("");
System.err.println(mie);
mie.printStackTrace();
}
catch (IncorrectFormatException ife)
{
errorFld.setText("Too few terms");
queryFld.setText("");
System.err.println(ife);
ife.printStackTrace();
}
catch (IllegalStartOfQueryException isqe)
{
errorFld.setText("Word REPORT expected");
queryFld.setText("");
System.err.println(isqe);
isqe.printStackTrace();
}
catch (InvalidSelectorException ise)
{
errorFld.setText("Selector must be ALL");
queryFld.setText("");
System.err.println(ise);
ise.printStackTrace();
}
catch (InvalidQualifierException iqe)
{
errorFld.setText("Qualifier error - keyword WHERE missing");
queryFld.setText("");
System.err.println(iqe);
iqe.printStackTrace();
}
catch (InvalidLValueException ilve)
{
errorFld.setText("Invalid query. quality, numInStock, "
+ "or basePrice expected");
queryFld.setText("");
System.err.println(ilve);
ilve.printStackTrace();
}
catch (InvalidOperatorException ioe)
{
errorFld.setText("InvalidOperatorException. < <= > >= == expected");
queryFld.setText("");
System.err.println(ioe);
ioe.printStackTrace();
}
}
}//end actionPerformed
}//end ButtonHandler
如果这看似微不足道,我道歉,但由于某种原因,我很难搞清楚。我感谢任何意见或建议。如果我错过任何需要的信息,请告诉我,我会尽快添加。此外,以下是此细分的说明:
11)现在,重点关注evaluateAll方法。获取下一个令牌。它应该是3个单词中的任何一个: “basePrice”或“quality”或“numInStock”。如果不是,请将消息“无效的查询,质量,numInStock或basePrice预期。如果是这3个单词中的一个,你期望一个关系运算符,所以得到下一个标记,但将其保存在一个新的String中,称之为optok。如果它不是正确的运算符,请将消息“无效查询, 你现在有两个字符串:令牌,它是“basePrice”或“quality”或“numInStock”,以及一个optok,它是上面列出的5个关系运算符之一。
提前致谢:)
答案 0 :(得分:1)
您没有发布堆栈跟踪,所以我猜测您没有例外,并且从您的代码中读取我试图了解可能发生的事情......所以我可能错了。
在我看来,你正在使用一个标记器。令牌化器就像一个流,一旦你调用nextToken()它就会返回令牌,除非你将它保存在某个地方,否则下一次调用nextToken()会使前一个令牌无法访问。
所以,你在哪里:
else if (!testTokens.nextToken().matches("quality|numInStock|basePrice"))
{
throw new InvalidLValueException();
}
else if (!testTokens.nextToken().matches(">|<|>=|<=|=="))
{
throw new InvalidOperatorException();
}
您正在使用令牌。结果,当你到达时:
while (testTokens.hasMoreTokens()) {
所有令牌都被消耗掉了,所以它不会在这里迭代。
您应该将您的令牌保存在变量中,以便您可以检查并使用它们:
StringTokenizer testTokens = new StringTokenizer(input, " ,");
if (!testTokens.nextToken().equalsIgnoreCase("report"))
{
throw new IllegalStartOfQueryException();
}
else if (!testTokens.nextToken().equalsIgnoreCase("all"))
{
throw new InvalidSelectorException();
}
else if (!testTokens.nextToken().equalsIgnoreCase("where"))
{
throw new InvalidQualifierException();
}
// TODO here i use local variables, since you need to use these outside this method,
// maybe use class fields or whatever else
String subject = testTokens.nextToken();
String opttok = testTokens.nextToken();
if (!subject.matches("quality|numInStock|basePrice"))
{
throw new InvalidLValueException();
}
else if (!opttok.matches(">|<|>=|<=|=="))
{
throw new InvalidOperatorException();
}
// done, now you have opttok and subject