Andrew
Andrew

Reputation: 17

Multi-Class GUI

I have been taking the basic 'guess my number' game in Java utilizing the Random class, but I was attempting to make my first GUI to have more than one window. I was having some issues that I can't see, to figure out on my own, so I have come here for help.

Here is he main class:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;

public class GuessMyNumber extends JFrame
{
    private JLabel lblIntro;
    private JLabel lblPrompt;
    private JTextField txtInput;
    private JButton btnSend;
    private JButton btnCustomize;
    private JTextField txtMin;
    private JTextField txtMax;
    private JButton btnSet;
    private ButtonListener btnListener;
    private boolean customize;
    private boolean game;
    private int min;
    private int max;
    private int dif;
    private int magicNum;
    private int num;
    private int guesses = 1;

    public GuessMyNumber()
    {
        super("Guess My Number");
        Container cp = getContentPane();
        setLayout(new FlowLayout());

        lblIntro = new JLabel("Welcome to Guess My Number");
        lblPrompt = new JLabel("Please enter your guess:");
        txtInput = new JTextField(15);
        btnSend = new JButton("Send");
        btnSend.addActionListener(new ButtonListener());

        btnCustomize = new JButton("Customize Range");
        btnCustomize.addActionListener(new ButtonListener());

        cp.add(lblIntro);
        cp.add(lblPrompt);
        cp.add(txtInput);
        cp.add(btnSend);
        cp.add(btnCustomize);


        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(500, 100);
        setVisible(true);
    }
    public static void main(String[]args)
    {
        GuessMyNumber foo = new GuessMyNumber();
    }
    public int getMagicNum(int min, int max)
    {
        Random g = new Random();
        if(customize)
        {
            dif = max - min;
            magicNum = g.nextInt(dif) + min + 1;
        }
        else
        {
            magicNum = g.nextInt(100) + 1;
        }
        return magicNum;
    }
    public String getFeedback(int guesses)
    {
        String feedback;
        if(guesses < 4 && guesses > 0)
            feedback = "Superstar";
        else if(guesses < 7 && guesses > 3)
            feedback = "Pretty Good";
        else if(guesses < 10 && guesses > 6)
            feedback = "Mediocre";
        else
            feedback = "Pathetic";
        return feedback;
    }
    private class ButtonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            Object clicked = e.getSource();
            if(clicked == btnCustomize)
            {
                customize = true;
                game = false;
                GUIUtil gui = new GUIUtil();
                min = gui.getMin();
                max = gui.getMax();
            }
            if(clicked == btnSend)
            {
                String feedback;
                if(!(customize))
                {
                    min = 1;
                    max = 100;
                    if(!(game))
                        magicNum = getMagicNum(min, max);
                    game = true;
                    num = Integer.parseInt(txtInput.getText());
                    if(num < magicNum)
                        JOptionPane.showMessageDialog(null, "Too low!");
                    else if(num > magicNum)
                        JOptionPane.showMessageDialog(null, "Too high!");
                    else
                    {
                        feedback = getFeedback(guesses);
                        JOptionPane.showMessageDialog(null, "Correct!!!\nYou guessed my number in " + guesses + " guesses!\n" + feedback);
                        guesses = 0;
                        game = false;
                    }
                    guesses++;
                }
                else
                {
                    if(!(game))
                        magicNum = getMagicNum(min, max);
                    game = true;
                    num = Integer.parseInt(txtInput.getText());;
                    if(num < magicNum)
                        JOptionPane.showMessageDialog(null, "Too low!");
                    else if(num > magicNum)
                        JOptionPane.showMessageDialog(null, "Too high!");
                    else
                    {
                        feedback = getFeedback(guesses);
                        JOptionPane.showMessageDialog(null, "Correct!!!\nYou guessed my number in " + guesses + " guesses!\n" + feedback);
                        guesses = 0;
                        game = false;
                    }
                    guesses++;
                }
            }

        }
    }
}

And here is the second class:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class GUIUtil extends JFrame
{
    private JTextField txtMin;
    private JTextField txtMax;
    private JButton btnSet;
    private ButtonListener btnListener;
    private int min;
    private int max;
    private boolean set = false;

    public GUIUtil()
    {
        super("Customization");
        Container cp = getContentPane();
        setLayout(new FlowLayout());

        txtMin = new JTextField("Min", 15);
        txtMax = new JTextField("Max", 15);
        btnSet = new JButton("Set");
        btnSet.addActionListener(new ButtonListener());
        cp.add(txtMin);
        cp.add(txtMax);
        cp.add(btnSet);
        setSize(190,125);
        setVisible(true);
    }
    public int getMin()
    {
        if(set = true)
        {
            set = false;
            return min;
        }
        else
        {
            min = 0;
            return min;
        }
    }
    public int getMax()
    {
        if(set = true)
        {
            set = false;
            return max;
        }
        else
        {
            max = 100;
            return max;
        }
    }
    private class ButtonListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            min = Integer.parseInt(txtMin.getText());
            max = Integer.parseInt(txtMax.getText());
            set = true;
        }
    }
}

Errors when I attempt to customize range and then guess while leaving the second window open so the object remains active are as follows:

Exception in thread "AWT-EventQueue-0" java.lang.IllegalArgumentException: n mus
t be positive
        at java.util.Random.nextInt(Unknown Source)
        at GuessMyNumber.getMagicNum(GuessMyNumber.java:66)
        at GuessMyNumber$ButtonListener.actionPerformed(GuessMyNumber.java:127)
        at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
        at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
        at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
        at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
        at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Sour
ce)
        at java.awt.Component.processMouseEvent(Unknown Source)
        at javax.swing.JComponent.processMouseEvent(Unknown Source)
        at java.awt.Component.processEvent(Unknown Source)
        at java.awt.Container.processEvent(Unknown Source)
        at java.awt.Component.dispatchEventImpl(Unknown Source)
        at java.awt.Container.dispatchEventImpl(Unknown Source)
        at java.awt.Component.dispatchEvent(Unknown Source)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
        at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
        at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
        at java.awt.Container.dispatchEventImpl(Unknown Source)
        at java.awt.Window.dispatchEventImpl(Unknown Source)
        at java.awt.Component.dispatchEvent(Unknown Source)
        at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
        at java.awt.EventQueue.access$200(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.awt.EventQueue$3.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Sour
ce)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Sour
ce)
        at java.awt.EventQueue$4.run(Unknown Source)
        at java.awt.EventQueue$4.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Sour
ce)
        at java.awt.EventQueue.dispatchEvent(Unknown Source)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
        at java.awt.EventDispatchThread.run(Unknown Source)

Upvotes: 1

Views: 188

Answers (1)

Paul Samsotha
Paul Samsotha

Reputation: 208994

Try declaring GUIUtils as a class member of the GuessNumber class. and instantiate it in the constructor

public class GuessNumber {
    GUIUtil utils;

    public GuessNumber(){
        utils = new GUIUtils();
    }
}

And delete it from your actionPerformed(). I think what's happening is that when you create the GUIUtilsobject in the actionPerformed(), there is no initial data in the text fields. Right after the GUIUtil object is created, the program immediately tries to get the input from the textFields which has no value.

Upvotes: 1

Related Questions