GUI Программирование (продолжение) - исключение NullPointer как выход для игры с угадыванием чисел - PullRequest
0 голосов
/ 18 апреля 2020

Я недавно начал программировать GUI и работаю над этой игрой в догадки. Вот мой код:

package experiment10;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.InputMismatchException;

public class mainFrame extends JFrame implements ActionListener
{
    public static int MAX = 500;    // maximum number to guess
    private JButton submitBtn;      // Submit button
    private JButton clearBtn;  // Clear Input button
    private JTextField inputNumber;  //input guessed number
    private int magicNumber;  //randomly generated number

    public static void main(String[] arg)    {
        //Displays frame
        mainFrame frame = new mainFrame();
        frame.setVisible(true);
    }

    public mainFrame()  {
        setSize(400, 400);
        setResizable (true);
        setTitle("Let's Play Hi Lo");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        magicNumber = (int)(Math.random()*MAX);

        Container gameView  = getContentPane();
        gameView.setLayout(new FlowLayout());

        JLabel imageLabel = new JLabel(new ImageIcon("cat.gif")); //creates image
        gameView.add(imageLabel); //adds image

        JLabel textLabel = new JLabel("Please enter your guess"); //creates JLabel
        gameView.add(textLabel); //adds JLabel

        JTextField inputNumber = new JTextField(); //creates JTextField
        gameView.add(inputNumber); //adds JTextField
        inputNumber.setColumns(30); //sets JTextField's length

        submitBtn = new JButton("Submit"); //create submit button
        clearBtn = new JButton("Clear"); //create clear button
        gameView.add(submitBtn); //adds submit button
        gameView.add(clearBtn); //adds clear button

        submitBtn.addActionListener(this); //registers this as ActionListener of Submit button
        clearBtn.addActionListener(this); //registers this as ActionListener of Clear button

    }

    @Override
    public void actionPerformed(ActionEvent e) {
        JButton clickedBtn = (JButton)e.getSource();

        try {
        switch(clickedBtn.getText()) {

        case "Submit" : inputNumber.getText(); //if user selects "Submit" button
        int guess = Integer.parseInt(inputNumber.getText()); //converts guess to integer
        if(guess<magicNumber) {
            JOptionPane.showMessageDialog(null,"Your number is too small");
        }
        if(guess>magicNumber) {
            JOptionPane.showMessageDialog(null,"Your number is too big");
        }
        if(guess==magicNumber) {
            JOptionPane.showMessageDialog(null,"Congratulations, you got it!");
        }
        break;

        case "Clear" : inputNumber.setText(" "); //if user selects "Clear" button
        break;
        }
    }
        catch(InputMismatchException ime) {
            JOptionPane.showMessageDialog(null,"You didn't enter an integer. Please try again.");
        }


}
}

Я думал, что близок к завершению, но когда я ввел число и нажал кнопку отправки, я получил исключение NullPointerException (наряду с некоторыми другими строками). Аналогично, когда я нажимал кнопку очистки, происходит то же самое. Любая помощь / советы с благодарностью. Вот вывод после того, как я нажал обе кнопки:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at experiment10.mainFrame.actionPerformed(mainFrame.java:56)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6636)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
    at java.desktop/java.awt.Component.processEvent(Component.java:6401)
    at java.desktop/java.awt.Container.processEvent(Container.java:2263)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5012)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2762)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at experiment10.mainFrame.actionPerformed(mainFrame.java:68)
    at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1967)
    at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2308)
    at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405)
    at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262)
    at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279)
    at java.desktop/java.awt.Component.processMouseEvent(Component.java:6636)
    at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3342)
    at java.desktop/java.awt.Component.processEvent(Component.java:6401)
    at java.desktop/java.awt.Container.processEvent(Container.java:2263)
    at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:5012)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2321)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
    at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4918)
    at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4547)
    at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4488)
    at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2307)
    at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2762)
    at java.desktop/java.awt.Component.dispatchEvent(Component.java:4844)
    at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:772)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
    at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:95)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
    at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:743)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
    at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:742)
    at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

Ответы [ 2 ]

1 голос
/ 18 апреля 2020

Исходя из того, что я могу сказать, основная проблема заключается в том, что вы сначала объявляете JTextField numberInput как переменную класса, а затем объявляете ее снова в методе mainFrame, по сути создавая новую локальную ссылку.

Когда вы ссылаетесь на переменную в методе actionPerformed, она просматривает переменную класса, которая не назначена, поэтому она выдает исключение нулевого указателя.

Простое решение - удалить второе объявление, когда вы присваиваете numberInput:

numberInput = new JTextField();

вместо

JTextField numberInput = new JTextField();
0 голосов
/ 18 апреля 2020

Это потому, что вы вызываете getText() в inputNumber, который не реализован в области видимости класса, а ваши входные данные сохраняются в inputNumber, который является локальной переменной метода, которая не может получить доступ к actionPerformed. Просто удалите локальную переменную метода и укажите ее на глобальную переменную.

public mainFrame()
{
    setSize( 400, 400 );
    setResizable( true );
    setTitle( "Let's Play Hi Lo" );
    setDefaultCloseOperation( EXIT_ON_CLOSE );
    magicNumber = ( int ) ( Math.random() * MAX );

    Container gameView = getContentPane();
    gameView.setLayout( new FlowLayout() );

    JLabel imageLabel = new JLabel( new ImageIcon( "cat.gif" ) ); //creates image
    gameView.add( imageLabel ); //adds image

    JLabel textLabel = new JLabel( "Please enter your guess" ); //creates JLabel
    gameView.add( textLabel ); //adds JLabel

    inputNumber = new JTextField(); //creates JTextField
    gameView.add( inputNumber ); //adds JTextField
    inputNumber.setColumns( 30 ); //sets JTextField's length

    submitBtn = new JButton( "Submit" ); //create submit button
    clearBtn = new JButton( "Clear" ); //create clear button
    gameView.add( submitBtn ); //adds submit button
    gameView.add( clearBtn ); //adds clear button

    submitBtn.addActionListener( this ); //registers this as ActionListener of Submit button
    clearBtn.addActionListener( this ); //registers this as ActionListener of Clear button

}
...