KiloJKilo
KiloJKilo

Reputation: 485

I have a reference to a class that is null

I'm trying to execute a method in another class but my reference is null.

I have a Main calculator class that begins like so:

public class Calculator {

public static void main( String[] args ) {

    // create new model, view and controller
    Model theModel = new Model();
    View theView = new View();
    Controller theController = new Controller( theModel, theView );

    /* start it up */
    theView.CalcView();

Inside the view class, I have buttons that I create as such registering the controller as the listener:

    btnZero = new JButton( "0" );
    btnZero.addActionListener( new Controller() );
    btnZero.setBounds( 167, 174, 86, 23 );
    frame.getContentPane().add( btnZero );

Also inside the view class I capture keys pressed:

    private void keyPressed( KeyEvent e, Controller controller ) {
    controller.keyPressed( e );
}

My current objective is to execute a method in the view class from the controller class with a keystroke view.toggleBorder( '1', true );:

    public void keyPressed( KeyEvent e ) {
    char key = e.getKeyChar();

    switch ( key ) {
    case '1':
    System.out.println( "1" );
    view.toggleBorder( '1', true );
    break;

The Controller constructor:

    public Controller( Model model, View view ) {
    this.model = model;
    this.view = view;

}

But I also have a no argument constructor that I had to make when registering the controller as the listener as you see in the button code above. The issue is, when it comes to view.toggleBorder.., the reference to view is null so it throws a null pointer exception. I think there is a problem with the harmony of my classes but I cannot find where there might be problems. This code is fragmented I apologize. You can view the source files on GitHub

Upvotes: 0

Views: 66

Answers (2)

REGAL
REGAL

Reputation: 326

In your View class when you initialize all your buttons and components, you run btnOne.addActionListener( new Controller() ); for every button. The problem with this is that you are creating a new instance of controller for every button, none of which have instances to your model or view objects.

The other problem you have here is that you have two classes, and each need a fully functional instance of the other class to become fully functional.

One way you can solve this is by making a static instance variable of Controller in your Calculator class, and add methods to Controller to give View and Model too it. Only add your listeners to your buttons with your static instance, and only add the listeners after your Controller has an instance of View.

Upvotes: 1

MadProgrammer
MadProgrammer

Reputation: 347244

Your view needs a reference to he controller which is controlling it. The instance that you register to your button has no knowledge of either the view or model.

Create a method in view called setController, which you MUST call after you construct the controller

// create new model, view and controller
Model theModel = new Model();
View theView = new View();
Controller theController = new Controller( theModel, theView );

 theView.setController(theController);

You could do thus within the controllers constructor instead if you wished

Upvotes: 0

Related Questions