Java:滚轮程序 - 调试 - 无论有效信息如何,变量都不会从 JTextField 更新并抛出 NumberFormatException

标签 java debugging variables jtextfield actionlistener

问题: 我无法获取要更新的 JTextFields 或 rollResultTotal 的值。 即使 JTextField 中的数据有效,仍然会引发 NumberFormatException。

问题:为什么变量不保留?这是由于类本身的声明造成的吗?是否可以更新 JLabel 面板以显示更新的结果? (尝试过这个,史诗般的失败)

提前感谢您提供任何意见和示例。

/*
   ITP-120:     Final Project
   Programmer:  S. Schnoor
   Date:        November 7th, 2009
   Filename:    SchnoorProject.java
   Purpose:     To generate "dice rolls" - a tally of random values as defined by the user,
                including a final calculation modifier.
*/

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import java.lang.*;
import java.math.*;

public class SchnoorProject extends JFrame implements ActionListener, EventListener
{
    // Declare Class Variables
    int sidesToRoll, diceToRoll, diceLeft, modifier, rollResult, rollResultTotal;
    String getSides, getDice, getModifier;
    JTextField inputSides       = new JTextField();
    JTextField inputDice        = new JTextField();
    JTextField inputModifier    = new JTextField();
    Random roll;

    // Panels and Buttons
    JPanel rollPanel;
    JButton newRollButton, helpButton, exitButton;

    // Create Colors
    Color darkPurple        = new Color ( 80,   0,  80);
    Color darkGold          = new Color (255, 215,   0);
    Color darkCoal          = new Color ( 24,  24,  24);
    Color crimson           = new Color (127,  12,  12);
    Color ltSilver          = new Color (140, 140, 180);

    public static void main(String args[])
    {
        JFrame frame = new SchnoorProject();

        WindowListener l = new WindowAdapter()
            {
                public void windowClosing(WindowEvent e)
                {
                    System.exit(0);
                }
            };

    frame.addWindowListener(l);
    frame.pack();
    frame.setVisible(true);

    }

    public SchnoorProject()
    {
        // Construction of Components
        rollPanel                           = new JPanel();
        getContentPane().add(rollPanel);


        JLabel      sidesLabel              = new JLabel ("Enter the number of sides on each die below.  (1 to 99)");
                    sidesLabel.setForeground(darkGold);
                    sidesLabel.setHorizontalAlignment(sidesLabel.CENTER);

        JTextField  inputSides              = new JTextField("6");
                    inputSides.setBackground(darkCoal);
                    inputSides.setForeground(darkGold);
                    inputSides.setHorizontalAlignment(inputSides.CENTER);

        JLabel      diceLabel               = new JLabel ("Enter the number of dice to roll below.  (1 to 99)");
                    diceLabel.setForeground(darkGold);
                    diceLabel.setHorizontalAlignment(diceLabel.CENTER);

        JTextField  inputDice               = new JTextField("3");
                    inputDice.setBackground(darkCoal);
                    inputDice.setForeground(darkGold);
                    inputDice.setHorizontalAlignment(inputDice.CENTER);

        JLabel      modifierLabel           = new JLabel ("Enter the final modifier  below.  (-99 to 99)");
                    modifierLabel.setForeground(darkGold);
                    modifierLabel.setHorizontalAlignment(modifierLabel.CENTER);

        JTextField  inputModifier           = new JTextField("2");
                    inputModifier.setBackground(darkCoal);
                    inputModifier.setForeground(darkGold);
                    inputModifier.setHorizontalAlignment(inputModifier.CENTER);

        JButton     newRollButton           = new JButton("ROLL");
                    newRollButton.setBackground(darkCoal);
                    newRollButton.setForeground(darkGold);
                    newRollButton.addActionListener(this);

        JButton     helpButton              = new JButton("Help/About");
                    helpButton.setBackground(darkCoal);
                    helpButton.setForeground(ltSilver);
                    helpButton.addActionListener(this);

        JButton     exitButton              = new JButton("Exit");
                    exitButton.setBackground(darkCoal);
                    exitButton.setForeground(crimson);
                    exitButton.addActionListener(this);

        //Conversions
                    getSides                = inputSides.getText();
                    getDice                 = inputDice.getText();
                    getModifier             = inputModifier.getText();
                    sidesToRoll             = Integer.parseInt(getSides);
                    diceToRoll              = Integer.parseInt(getDice);
                    modifier                = Integer.parseInt(getModifier);
                    diceLeft                = diceToRoll;
                    //rollResultTotal       = rollResultTotal;

        // Paneling
        rollPanel.setLayout(new GridLayout (3,3));
        rollPanel.setBackground(darkPurple);
        rollPanel.setForeground(darkGold);
        rollPanel.add(sidesLabel);
        rollPanel.add(diceLabel);
        rollPanel.add(modifierLabel);
        rollPanel.add(inputSides);
        rollPanel.add(inputDice);
        rollPanel.add(inputModifier);
        rollPanel.add(newRollButton);
        rollPanel.add(helpButton);
        rollPanel.add(exitButton);
    }

    // Implement ActionListener for multiple JButtons
    public void actionPerformed(ActionEvent e)
    {
        String arg = e.getActionCommand();
        if ("Help/About".equals(arg))
            {
                JOptionPane.showMessageDialog(null,"This application generates random values, based on the parameters input by the user.\nPlease choose number of dice, sides on each die, and a +/- roll modifier.\nIf no roll modifier is needed, enter 0 (numeric zero) in the modifier field.\n(The starting numbers tell the program to roll 3 six-sided dice and add 2 or '3d6+2'.)","Help/About",JOptionPane.INFORMATION_MESSAGE);
            }

        if ("Exit".equals(arg))
            {
                System.exit(0);
            }

        if ("ROLL".equals(arg))

                {
                    try
                    {
                        while (diceLeft>0)
                        {
                            getSides                    = inputSides.getText();
                            sidesToRoll                 = Integer.parseInt(getSides);
                            if(sidesToRoll<1 || sidesToRoll>99)     throw new NumberFormatException();
                            else

                            getDice                     = inputDice.getText();
                            diceToRoll                  = Integer.parseInt(getDice);
                            if(diceToRoll<1 || diceToRoll>99)       throw new NumberFormatException();
                            else

                            getModifier                 = inputModifier.getText();
                            modifier                    = Integer.parseInt(getModifier);
                            if(modifier<-99 || modifier>99)         throw new NumberFormatException();
                            else

                        rollResult                  = roll.nextInt(sidesToRoll)+1;
                        rollResultTotal             = rollResultTotal + rollResult;
                        diceLeft--;
                        }

                    }


                    catch(NumberFormatException ex)
                    {
                        JOptionPane.showMessageDialog(null,"You must enter an integer within the given range of each field.","ROLL",JOptionPane.INFORMATION_MESSAGE);
                        diceLeft = 0;
                    }


                    {   //Display the Roll Formula and Result
                    JOptionPane.showMessageDialog(null,"You entered a roll of " + (diceToRoll) + "d" + (sidesToRoll) + "+(" + (modifier) + ").\nYou rolled " + (rollResultTotal) + "!");
                    }
        ;}
    ;}
}

最佳答案

您初始化了此成员变量,但从未将此字段添加到 UI:

JTextField inputSides = new JTextField(" ");

您在此文本字段中读取的内容仍然包含字符串 "",它不是整数。

getSides = inputSides.getText();
sidesToRoll = Integer.parseInt(getSides);

当您在构造函数中构建 UI 时,您可以声明另一个同名的局部变量,指向一个新对象:

JTextField inputSides = new JTextField("6");

这是出现在 UI 中的对象。局部变量inputSides隐藏了同名的成员变量。

<小时/>

顺便说一句,这不是比较字符串的正确方法:

arg == "ROLL"

这只有效,因为arg指向同一个内部对象实例。比较这些值的正确方法是:

"ROLL".equals(arg)
<小时/>

编辑:

您缺少的技巧是考虑您正在创建的对象以及您的引用变量指向哪些对象。

考虑一下代码的简化版本:

public class ObjectReferences {
  private final JLabel label = new JLabel("I am FOO"); // label 1

  public ObjectReferences() {
    JLabel label = new JLabel("I am BAR"); // label 2

    JButton button = new JButton("Click me");
    button.addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        onclick();
      }
    });

    // will display "I am BAR"
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(600, 400);
    frame.setLayout(new FlowLayout());
    frame.add(label); // label 2
    frame.add(button);
    frame.setVisible(true);
  }

  public void onclick() {
    // will display "I am FOO"
    JOptionPane.showMessageDialog(null, label.getText()); // label 1
  }

  public static void main(String[] args) {
    new ObjectReferences();
  }
}

创建了两个标签对象,但只将一个添加到框架中。 标签 1 由成员变量引用,这是 onclick() 方法可见的标签。在构造函数中,label 2 由名为 label 的局部变量引用,该变量隐藏名为 label 的成员变量。

你的意图是写这样的东西:

public class ObjectReferences {
  private final JLabel label = new JLabel("I am FOO");

  public ObjectReferences() {
    JButton button = new JButton("Click me");
    button.addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        onclick();
      }
    });

    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(600, 400);
    frame.setLayout(new FlowLayout());
    frame.add(label);
    frame.add(button);
    frame.setVisible(true);
  }

  public void onclick() {
    JOptionPane.showMessageDialog(null, label.getText());
  }

  public static void main(String[] args) {
    new ObjectReferences();
  }
}

关于Java:滚轮程序 - 调试 - 无论有效信息如何,变量都不会从 JTextField 更新并抛出 NumberFormatException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1899648/

相关文章:

java - 自定义格式字符串 : arguments in double brackets java

Java TCP - 服务器和客户端工作,但无法得到答案

asp.net-mvc - ASP.NET MVC 2 发行版的实际调试符号

带 if-else 语句的 Bash 脚本 for 循环

java.sql.SQLNonTransientConnectionException :Keyspace names must be composed of alphanumerics and underscores (parsed: '' )

java - 使用 Maven 2 API 获取 WAR Artifact 的依赖项

c++ - 使用 SFML 库在 Xcode 中调试期间不显示变量值

c++ - 如何在 C++ 中创建 DEBUG 函数,例如 C# 中的 ConditionalAttribute

javascript - 通过内部函数改变变量

linux - 通过 ssh 导入远程变量