Java: Roller-Programm - Debug - Variablen nicht von JTextField und Number Aktualisierung unabhängig von gültigen Informationen geworfen
-
19-09-2019 - |
Frage
Probleme: Ich bin nicht in der Lage die Werte der JTextFields oder rollResultTotal zu aktualisieren zu erhalten. Auch wenn die Daten in dem JTextFields gültig sind, wird eine Number noch geworfen.
Fragen: Warum nicht die Variablen bleiben? Ist dies aufgrund Deklaration in der Klasse selbst? Ist es möglich, eine JLabel Panel zu aktualisieren ein aktualisiertes Ergebnis zu zeigen? (Versuchte dies, epischer Ausfall)
Vielen Dank im Voraus für jede Eingabe und Beispiele.
/*
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) + "!");
}
;}
;}
}
Lösung
Sie initialisieren diese Membervariable, aber Sie dieses Feld nie auf die UI hinzufügen:
JTextField inputSides = new JTextField(" ");
Hier lesen Sie aus diesem Textfeld, das immer noch den String " "
enthalten, die nicht eine ganze Zahl ist.
getSides = inputSides.getText();
sidesToRoll = Integer.parseInt(getSides);
Wenn Sie Ihre UI im Konstruktor bauen, erklären Sie, eine anderen, lokalen Variable mit dem gleichen Namen, deuten auf ein neues Objekt:
JTextField inputSides = new JTextField("6");
Dies ist das Objekt, das in der Benutzeroberfläche angezeigt wird. Die lokale Variable inputSides
Häute der Membervariable mit dem gleichen Namen.
Als beiseite, das ist nicht der richtige Weg Strings vergleichen:
arg == "ROLL"
Das funktioniert nur, weil arg
auf die gleiche, internierten Objektinstanz zeigt. Der richtige Weg, um diese Werte zu vergleichen wäre:
"ROLL".equals(arg)
EDIT:
Der Trick Sie fehlen im Denken über die Objekte, die Sie erstellen ist und welche Ihre Referenzvariablen zeigen auf.
Betrachten Sie diese vereinfachte Version des Codes:
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();
}
}
Zwei-Label-Objekte werden erstellt, aber nur eine ist mit dem Rahmen hinzugefügt. label 1 wird durch die Membervariable referenziert und das ist die eine sichtbar für das onclick()
Verfahren. Im Konstruktor label 2 wird durch eine lokale Variable namens label
verwiesen, dass Haut der Membervariable namens label
.
Ihre Absicht ist es, etwas schreiben wie diese statt:
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();
}
}