Search code examples
javanullpointerexception

Easy Program throws NullPointerException when multiple Action Listeners


I have tried using multiple action listeners in 3 seperate files but it throws NullPointer exception when I want to display a "3-rd file" but it throws this error.I am just a begginer and maybe I failed with connecting class to another.That may be the main problem.Thanks for helping in advance.

Source :

Start.java

    package com.raising.darkness;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    public class Start {
    
        JFrame frame;
        Container container;
        JPanel startTitle;
        JLabel startText;
        Font startTitleFont= new Font("Dialog", Font.BOLD, 60);
        Font startTitleButton = new Font("Dialog", Font.PLAIN, 40);
        Font chooseTitleFont = new Font("Dialog", Font.PLAIN, 59);
        JPanel startButtonPanel;
        JButton startButton;
    
    
        Color backgroundFrame = new Color(180,180,180);
        Color buttonColor = new Color(144,144,144);
    
    
    
        StartHandler startHandler = new StartHandler();
    
    
        AveragePanel averagePanel = new AveragePanel(this);
        HeroClasses heroClasses = new HeroClasses(this);
    
    
        public static void main(String[] args) { new Start(); }
        public Start(){
            frame=new JFrame();
            frame.setSize(1024,800);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setTitle("Raising Darkness");
            frame.getContentPane().setBackground(backgroundFrame);
            frame.setLayout(null);
    
            container=frame.getContentPane();
    
             //Title Text
            startTitle = new JPanel();
            startTitle.setBounds(162,100,700,150);
            startTitle.setBackground(backgroundFrame);
    
            startText = new JLabel("RAISING DARKNESS");
    
            startText.setFont(startTitleFont);
    
            startTitle.add(startText);
            container.add(startTitle);
    
    
            startButtonPanel = new JPanel();
            startButtonPanel.setBounds(387,600,200,70);
            startButtonPanel.setBackground(backgroundFrame);
            startButton = new JButton();
            startButton.setText("START");
            startButton.setBackground(buttonColor);
    
            startButton.setFont(startTitleButton);
            startButton.setFocusPainted(false);
            startButton.addActionListener(startHandler);
    
            startButtonPanel.add(startButton);
            container.add(startButtonPanel);
    
    
            frame.setVisible(true);
    
        }
    
    
        public class StartHandler implements ActionListener{
    
            @Override
            public void actionPerformed(ActionEvent ex) {
    
                heroClasses.createClassChoose();
            }
        }
    
    
    }

HeroClasses.java

    package com.raising.darkness;
    
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    public class HeroClasses{
        Start start;
        Color normalChooseColor = new Color(144,144,144);
        JPanel chooseTitlePanel, chooseButtonsPanel;
        JLabel chooseTitleLabel;
        JButton chooseMageButton, chooseWarriorButton, chooseArcherButton;
        String choosenClass;
    
        Color chooseClassColor = new Color(100,100,100);
    
        ClassHandler classHandler = new ClassHandler();
    
        AveragePanel averagePanel = new AveragePanel(this);
    
    
        public HeroClasses(Start start){
                this.start = start;
            }
    
        public void createClassChoose(){
            start.startButtonPanel.setVisible(false);
            start.startTitle.setVisible(false);
            start.frame.getContentPane().setBackground(normalChooseColor);
    
    
            chooseTitlePanel = new JPanel();
            chooseTitlePanel.setBounds(162,200,700,100);
            chooseTitlePanel.setBackground(normalChooseColor);
    
            chooseTitleLabel= new JLabel();
            chooseTitleLabel.setText("Choose Class!");
            chooseTitleLabel.setFont(start.chooseTitleFont);
            chooseTitlePanel.add(chooseTitleLabel);
            start.container.add(chooseTitlePanel);
    
            chooseButtonsPanel = new JPanel();
            chooseButtonsPanel.setBounds(162,500,700,100);
            chooseButtonsPanel.setLayout(new GridLayout(1,3,50,0));
            chooseButtonsPanel.setBackground(normalChooseColor);
    
            //CLASSES
    
            chooseMageButton = new JButton("Mage");
            chooseMageButton.setBackground(chooseClassColor);
            chooseMageButton.setFont(start.startTitleButton);
            chooseMageButton.addActionListener(classHandler);
            chooseMageButton.setActionCommand("Mage");
            chooseMageButton.setFocusPainted(false);
            chooseButtonsPanel.add(chooseMageButton);
    
            chooseWarriorButton = new JButton("Warrior");
            chooseWarriorButton.setBackground(chooseClassColor);
            chooseWarriorButton.setFont(start.startTitleButton);
            chooseWarriorButton.addActionListener(classHandler);
            chooseWarriorButton.setActionCommand("Warrior");
            chooseWarriorButton.setFocusPainted(false);
            chooseButtonsPanel.add(chooseWarriorButton);
    
            chooseArcherButton = new JButton("Archer");
            chooseArcherButton.setBackground(chooseClassColor);
            chooseArcherButton.setFont(start.startTitleButton);
            chooseArcherButton.addActionListener(classHandler);
            chooseArcherButton.setActionCommand("Archer");
            chooseArcherButton.setFocusPainted(false);
            chooseButtonsPanel.add(chooseArcherButton);
    
    
            start.container.add(chooseButtonsPanel);
    
    
    
    
        }
    
    
    
    public class ClassHandler implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent ex) {
            choosenClass = ex.getActionCommand();
            averagePanel.mainPanel();
    
    
        }
    }
    
    }

AveragePanel.java

    package com.raising.darkness;
    
    import javax.swing.*;
    import java.awt.*;
    
    public class AveragePanel {
    
        Start start;
        HeroClasses heroClasses;
        String actualClass;
        JPanel picturePanel, statsPanel, storyPanel, choicesPanel;
        JLabel pictureLabel;
        ImageIcon imageIcon;
    
    
        public AveragePanel(HeroClasses heroClasses){this.heroClasses = heroClasses;}
        public AveragePanel(Start start){this.start = start;}
    
    
    
    
        public void mainPanel(){
            heroClasses.chooseButtonsPanel.setVisible(false);
            heroClasses.chooseTitlePanel.setVisible(false);
    
             actualClass = heroClasses.choosenClass ;
            System.out.println("Current Class is :" +actualClass);
    
            picturePanel  = new JPanel();
            picturePanel.setBounds(50,50,500,350);
            picturePanel.setBackground(Color.WHITE);
                start.container.add(picturePanel);
    
    
    
        }
    
    
    }

Solution

  • You have 2 constructors in AveragePanel class. You use public AveragePanel(HeroClasses heroClasses){this.heroClasses = heroClasses;}, so your field start is null, you have two options.

    1. Change method main panel, and get start panel from heroClasses: heroClasses.start.container.add(picturePanel); Method will be looks like:

           public void mainPanel(){
           heroClasses.chooseButtonsPanel.setVisible(false);
           heroClasses.chooseTitlePanel.setVisible(false);
      
            actualClass = heroClasses.choosenClass ;
           System.out.println("Current Class is :" +actualClass);
      
           picturePanel  = new JPanel();
           picturePanel.setBounds(50,50,500,350);
           picturePanel.setBackground(Color.WHITE);
           heroClasses.start.container.add(picturePanel);
      
       }
      
    2. Better solution is change constructor, and set start panel using heroClasses. Then you can use both constructors and method mainPanel() will works this same. Below constructors:

           public AveragePanel(HeroClasses heroClasses){
               this.heroClasses = heroClasses;
               this.start = heroClasses.start;
           }
           public AveragePanel(Start start){this.start = start;}
      

    method mainPanel() with no changes.

    The best practice is initializion field in constructor. In your case, you have to change that in your HeroClasses class. Initialize field averagePanel by contructor:

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    public class HeroClasses{
        Start start;
        Color normalChooseColor = new Color(144,144,144);
        JPanel chooseTitlePanel, chooseButtonsPanel;
        JLabel chooseTitleLabel;
        JButton chooseMageButton, chooseWarriorButton, chooseArcherButton;
        String choosenClass;
    
        Color chooseClassColor = new Color(100,100,100);
    
        ClassHandler classHandler = new ClassHandler();
    
        AveragePanel averagePanel;
    
    
        public HeroClasses(Start start){
                this.start = start;
                this.averagePanel = new AveragePanel(this);
            }
    
        public void createClassChoose(){
            start.startButtonPanel.setVisible(false);
            start.startTitle.setVisible(false);
            start.frame.getContentPane().setBackground(normalChooseColor);
    
    
            chooseTitlePanel = new JPanel();
            chooseTitlePanel.setBounds(162,200,700,100);
            chooseTitlePanel.setBackground(normalChooseColor);
    
            chooseTitleLabel= new JLabel();
            chooseTitleLabel.setText("Choose Class!");
            chooseTitleLabel.setFont(start.chooseTitleFont);
            chooseTitlePanel.add(chooseTitleLabel);
            start.container.add(chooseTitlePanel);
    
            chooseButtonsPanel = new JPanel();
            chooseButtonsPanel.setBounds(162,500,700,100);
            chooseButtonsPanel.setLayout(new GridLayout(1,3,50,0));
            chooseButtonsPanel.setBackground(normalChooseColor);
    
            //CLASSES
    
            chooseMageButton = new JButton("Mage");
            chooseMageButton.setBackground(chooseClassColor);
            chooseMageButton.setFont(start.startTitleButton);
            chooseMageButton.addActionListener(classHandler);
            chooseMageButton.setActionCommand("Mage");
            chooseMageButton.setFocusPainted(false);
            chooseButtonsPanel.add(chooseMageButton);
    
            chooseWarriorButton = new JButton("Warrior");
            chooseWarriorButton.setBackground(chooseClassColor);
            chooseWarriorButton.setFont(start.startTitleButton);
            chooseWarriorButton.addActionListener(classHandler);
            chooseWarriorButton.setActionCommand("Warrior");
            chooseWarriorButton.setFocusPainted(false);
            chooseButtonsPanel.add(chooseWarriorButton);
    
            chooseArcherButton = new JButton("Archer");
            chooseArcherButton.setBackground(chooseClassColor);
            chooseArcherButton.setFont(start.startTitleButton);
            chooseArcherButton.addActionListener(classHandler);
            chooseArcherButton.setActionCommand("Archer");
            chooseArcherButton.setFocusPainted(false);
            chooseButtonsPanel.add(chooseArcherButton);
    
    
            start.container.add(chooseButtonsPanel);
    
    
    
    
        }
    
    
    
    public class ClassHandler implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent ex) {
            choosenClass = ex.getActionCommand();
            averagePanel.mainPanel();
    
    
        }
    }
    
    }