【问题标题】:java.lang.StringIndexOutOfBoundsException and showInputDialogjava.lang.StringIndexOutOfBoundsException 和 showInputDialog
【发布时间】:2012-01-12 20:05:46
【问题描述】:

这是一个家庭作业问题。我正在开发一个程序,该程序使用JOptionPane 来计算选票,直到输入 Q 或 q 并且计票停止。然后它会启动一个showConfirmDialog,询问用户是否真的想退出。程序的主要任务已经完成,但是其中一条指令指出,在 showInputDialog 上,任何不是 Y、y、N、n、Q 或 q 的条目都将被忽略。

我遇到了这个问题,因为出于某种原因,无论何时单击对话框上的任何按钮,程序都会关闭。该程序的其余部分工作正常,但是当我运行它时,它会给出一个编译错误通知,我最终遇到了这个问题。

这是我的代码。知道这里发生了什么吗?感谢您的任何帮助。

编辑 - 你知道,System.out.println("HI"); 行就在那里,所以我可以确定问题是否出在该位置的 continue 语句的整个 if 语句上。

编辑 #2 - 我使用您的建议(至少我如何解释它)在第一个程序(现在是 VoteCount2)下方发布了我对代码的编辑。

编辑 #3 - 我重新格式化并尝试听从您的建议。如果我做错了什么,我很抱歉,但我不知道该怎么办。

编辑 #4 - 这是我的工作方式..

Do { String voteString = ""; 
voteString = JOptionPane.showInputDialog(null, "Enter 'Y' to vote yes, 'N' to vote no, or 'Q' to quit voting", "Vote Now!", JOptionPane.OK_CANCEL_OPTION);
 if (voteString == null || voteString.length() == 0) continue;
 else if(voteString.toLowerCase().equals("y")) 
yesVotes++;
 else if (voteString.toLowerCase().equals("n")) 
noVotes++;

旧程序的其余部分

           package javaapplication16;

           import javax.swing.JOptionPane;

           public class VoteCount {

           public static void main(String[] args) {

           int yesVotes = 0, noVotes = 0, totalVotes = 0;
           totalVotes = yesVotes + noVotes;
           char vote;
           int reply = 1;
           int option = 0;
           {
           do {
           String voteString = JOptionPane.showInputDialog(null, "Enter 'Y' to vote yes, 'N'  to vote no, or 'Q' to quit voting", "Vote Now!", JOptionPane.OK_CANCEL_OPTION);
           vote = voteString.charAt(0);
           if (vote == 'Y' || vote == 'y')
           yesVotes++;
           if (vote == 'N' || vote == 'n')
           noVotes++;
           if (option == JOptionPane.OK_OPTION)
           System.out.println("HI");
           if (option == JOptionPane.CANCEL_OPTION)
           continue;
           if (option == JOptionPane.CLOSED_OPTION)
           continue;
             {
            }

           if (vote == 'Q' || vote == 'q')
           {
           reply = JOptionPane.showConfirmDialog(null, "Quit?", "Warning!", JOptionPane.YES_NO_OPTION);
           if (reply == JOptionPane.YES_OPTION)
              JOptionPane.showMessageDialog(null, "yes " + yesVotes + " no " + noVotes + " total " + totalVotes);
           else if (reply != JOptionPane.YES_OPTION);
    continue;
            }
           } while (reply != JOptionPane.YES_OPTION);

           }
        }
    }


package javaapplication16;

import javax.swing.JOptionPane;

public class VoteCount {

public static void main(String[] args) {

int yesVotes = 0, noVotes = 0, totalVotes = 0;
totalVotes = yesVotes + noVotes;
char vote;
    int reply = 1;
{
    do {
 String voteString = JOptionPane.showInputDialog(null, "Enter 'Y' to vote yes, 'N' to vote no, or 'Q' to quit voting", "Vote Now!", JOptionPane.OK_CANCEL_OPTION);
 vote = voteString.charAt(0);
 if (voteString == null || voteString.length() == 0)
vote = 'q';
if (voteString.toLowerCase().equals("y"))
     yesVotes++;
if (voteString.toLowerCase().equals("n"))
        noVotes++;

        {
    }

if (voteString.toLowerCase().equals("q"))
{
    reply = JOptionPane.showConfirmDialog(null, "Quit?", "Warning!", JOptionPane.YES_NO_OPTION);
    if (reply == JOptionPane.YES_OPTION)
        JOptionPane.showMessageDialog(null, "yes " + yesVotes + " no " + noVotes + " total " + totalVotes);
    else if (reply != JOptionPane.YES_OPTION);
continue;
        }
    } while (reply != JOptionPane.YES_OPTION);

    }
    }
}

【问题讨论】:

  • 作业标签,如果是作业问题
  • 除了开头之外,你在哪里设置选项?
  • 你的意思是JOptionPane?在 while 循环的开头有一个 showINputDialog 框,在 while 循环的结尾有一个 showConfirmDialog 后跟一个 showMessageDialog。你指的是这个吗?

标签: java string while-loop joptionpane


【解决方案1】:

无论字符串中是否有任何内容(例如单击按钮时),您都尝试从字符串中获取一个字符。一种选择是先检查按钮是否按下。

另一种方法是对照"y""n" 检查小写字符串,例如:

if (voteString.toLowerCase().equals("y")) {
    // etc.

当用户退出对话框时,您仍然需要处理null 返回值。如果他们选择“确定”,则它不会是null,但它为空,从而导致越界异常。

【讨论】:

  • 谢谢,我该如何纠正这个问题?我是否尝试为按钮设置值?
  • 再次感谢。 netBeans 刚刚冻结,所以我在电脑上等待,但我将尝试将我的 if 语句更改为你的方式。
  • 我编辑了程序,我还没有完全解决问题,但这看起来更接近你的建议吗?
  • @JonW 你还是得到了这个角色。此外,进行小写并与之进行比较的目的是,您只需为每个命令进行一次比较。如果用户输入“y”或“Y”,那么toLowerCase().equals('y') 将为真。你在没有任何好处的情况下加倍工作。
  • 谢谢!我刚刚更正了,抱歉我第一次误解了。
【解决方案2】:

我在这里看到的唯一问题是,如果您按“取消”,则会出现 NullPointerException,因为在这种情况下对话框将返回 null 作为输入,但您仍然尝试获取第一个字符。否则它应该(并且确实——我编译并运行它)工作得很好。

看看这两行:

String voteString = JOptionPane.showInputDialog(null, "Enter 'Y' to vote yes, 'N'  to vote no, or 'Q' to quit voting", "Vote Now!", JOptionPane.OK_CANCEL_OPTION);
vote = voteString.charAt(0);

有两个可能的问题。首先,假设用户按下“取消”。在这种情况下,showInputDialog() 返回null,所以voteStringnull。这意味着只要调用voteString.charAt(0) 就会抛出NullPointerException。您必须首先检查null - 即,

String voteString = JOptionPane.showInputDialog(null, "Enter 'Y' to vote yes, 'N'  to vote no, or 'Q' to quit voting", "Vote Now!", JOptionPane.OK_CANCEL_OPTION);
if (voteString == null) {
    // User has cancelled; let's quit
    System.exit(0);
}

第二个问题是如果您不输入任何内容就按“确定”会发生什么。在这种情况下,voteString 的长度为零,调用charAt(0) 将抛出IndexOutOfBoundsException,因为索引 0 处没有字符。同样,您需要检查这一点。添加到前面的示例:

String voteString = JOptionPane.showInputDialog(null, "Enter 'Y' to vote yes, 'N'  to vote no, or 'Q' to quit voting", "Vote Now!", JOptionPane.OK_CANCEL_OPTION);
if (voteString == null) {
    // User has cancelled; let's quit
    System.exit(0);
} else if (voteString.length() == 0) {
    // This will just skip to the next go-round of the do/while loop, and prompt again
    continue;
}

【讨论】:

  • 谢谢。是的,每个按钮都应该被​​忽略,因为 q 是唯一可以导致循环其余部分的按钮。
  • "OK" 返回一个空字符串,而不是 null :/
  • 我确实编辑了程序以尝试 Dave N 的方式,但我仍然遇到错误。男孩有很多括号。当我点击取消时,除了 NullPointerException 之外没有任何错误,感谢您的检查。
  • 嗨,我仍然有错误,我真的很困惑。在纠正了我在尝试实施您的建议时所犯的错误后,我再次重新发布了代码,但我仍然遇到同样的错误。对不起,我只是被难住了。在这种情况下,我做错了什么?
  • 我编辑了我的帖子——希望对您有所帮助。您对代码所做的更改没有帮助,因为您仍在对 voteString 的原始值而不是更改后的值进行有问题的 charAt 调用。
【解决方案3】:

一些事情:

正如其他人所提到的,您没有正确处理没有输入文本的情况。具体来说,如果您单击“确定”,则 voteString 将是该字段中的任何内容(即空字符串)。如果单击取消,则 voteString 将为空。

如果检测到以下任一情况,您可以通过将 voteString 设置为默认值来处理此问题:

if (voteString == null || voteString .equals("")) voteString = "q";

其他一些事情:您永远不会更新 totalVotes。

你可以使用

vote = Character.toLowerCase(voteString.charAt(0))

获取输入的字符。您甚至可以使用不同类型的对话框(允许选择是/否/取消按钮),而不是输入文本。

如果您可以使用 switch(vote) 块在输入的文本之间进行选择。

【讨论】:

  • 感谢您的建议。我应该补充一点,我使用的对话框是作业所必需的,并且默认情况下将 voteString 设置为“q”可能不是我的教授想要的。不过为了做到这一点,我把它放到了我的程序中,它并没有解决问题(我在那里做错了吗?)。
  • 另外,你能解释一下我不更新总投票数是什么意思吗?我还需要做什么?它在最后增加了选票。谢谢。
  • 我不相信您理解我建议的更改。首先,您的第二版在右大括号的位置方面存在严重问题。例如,您仅在确定字符为“y”后才检查该字符是否为“n”。其次,为空/空字符串提供处理程序的想法是在对字符串进行任何其他检查之前使用它。第三,将字符转换为小写的想法是,您只需检查 y、n、q:您不必再检查 Y、N、Q。最后,给有用的答案投票,即使它们不能解决问题
  • 感谢您的建议,我会编辑它。另外,我以为我已经对您的答案进行了评分。没有必要对此保持简洁。投出你的一票。
猜你喜欢
  • 1970-01-01
  • 2015-08-15
  • 1970-01-01
  • 2012-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-07
  • 2013-04-06
相关资源
最近更新 更多