Java: programa de Roller - depuración - variables no actualización de JTextField y NumberFormatException lanzado independientemente de información válida

StackOverflow https://stackoverflow.com/questions/1899648

Pregunta

Problemas: Soy incapaz de obtener los valores de la JTextFields o la rollResultTotal para actualizar. Incluso si los datos en los JTextFields son válidas, una NumberFormatException está siendo lanzada.

Las preguntas: ¿Por qué no se quedan las variables? ¿Se debe esto a la declaración de la clase en sí? ¿Es posible actualizar un panel JLabel para mostrar un resultado actualizado? (Probado esto, insuficiencia EPIC)

Gracias de antemano por cualquier entrada y ejemplos.

/*
   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) + "!");
                    }
        ;}
    ;}
}
¿Fue útil?

Solución

inicializar esta variable miembro, pero nunca se agregue este campo a la interfaz de usuario:

JTextField inputSides = new JTextField(" ");

A continuación se lee de este campo de texto que aún contiene el " " cadena, que no es un entero.

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

Cuando se construye la interfaz de usuario en el constructor, se declara otra, variable local con el mismo nombre, que apunta a un objeto nuevo:

JTextField inputSides = new JTextField("6");

Este es el objeto que aparece en la interfaz de usuario. El inputSides variable local oculta la variable miembro del mismo nombre.


Como acotación al margen, este no es el camino correcto para comparar cadenas:

arg == "ROLL"

Esto sólo funciona porque arg está apuntando a la misma instancia de objeto, internados. La forma correcta de comparar estos valores sería:

"ROLL".equals(arg)

EDIT:

El truco se echa en falta es en la reflexión sobre los objetos que está creando y que las variables de referencia estén alineados.

Considere esta versión simplificada de su código:

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();
  }
}

Dos objetos de etiqueta se crean, pero sólo una se añade a la trama. etiqueta 1 es referenciado por la variable de miembro y este es el uno visible para el método onclick(). Dentro del constructor, etiqueta 2 hace referencia una llamada label variable local que oculta la variable miembro llamada label.

Su intención es la de escribir algo como esto en su lugar:

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();
  }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top