Java: programme Roller - debug - variables non mise à jour de JTextField et NumberFormatException jeté peu importe l'information valide

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

Question

Problèmes: Je suis incapable d'obtenir les valeurs de la JTextFields ou rollResultTotal mettre à jour. Même si les données contenues dans les JTextFields sont valides, un NumberFormatException est encore jeté.

Questions: Pourquoi ne pas les variables restent? Est-ce en raison de la déclaration de la classe elle-même? Est-il possible de mettre à jour un panneau de JLabel pour afficher un résultat mis à jour? (Ce essayé, échec épique)

Merci d'avance pour toute entrée et des exemples.

/*
   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) + "!");
                    }
        ;}
    ;}
}
Était-ce utile?

La solution

Vous initialisez cette variable membre, mais vous n'ajoutez ce champ à l'interface utilisateur:

JTextField inputSides = new JTextField(" ");

Ici, vous lisez ce champ de texte qui contient encore le " " String, ce qui est un entier.

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

Lorsque vous construisez votre interface utilisateur dans le constructeur, vous déclarez une autre, variable locale avec le même nom, pointant vers un nouvel objet:

JTextField inputSides = new JTextField("6");

Ceci est l'objet qui apparaît dans l'interface utilisateur. La inputSides variable locale cache la variable membre du même nom.


En aparté, ce n'est pas la bonne façon de comparer des chaînes:

arg == "ROLL"

Cela ne fonctionne que parce arg pointe vers la même instance d'objet interné. La bonne façon de comparer ces valeurs serait:

"ROLL".equals(arg)

EDIT:

L'astuce vous manque est dans la réflexion sur les objets que vous créez et ceux de vos variables de référence pointent à.

Considérez cette version simplifiée de votre code:

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

Deux objets de l'étiquette sont créés, mais un seul est ajouté au cadre. étiquette 1 est référencé par la variable membre et ceci est la seule visible par le procédé de onclick(). Dans le constructeur, étiquette 2 est référencé par une variable locale appelée label qui cache la variable membre appelée label.

Votre intention est d'écrire quelque chose comme ceci:

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();
  }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top