Zalx
Zalx

Reputation: 49

NullPointerException when passing JPanel to CardLayout

I asked a similar question not too long ago about using multiple classes for JPanels within a JFrame, after much improving my code I've now come across an obstacle with CardLayout.

I get a NullPointerException when tring to show my "2" screen which is just a BaseScreen that I will later use other classes to inherit its properties. After changing this code,

final CardLayout cardL = new CardLayout();

from

CardLayout cardL;

outside of my contructor I now get no JPanels appearing!

Here's my code:

Login Class:

/*Login Screen class for allowing
multiple levels of access and security*/

//Imports library files
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.io.*;
import java.util.*;

//Creates a LoginScreen class that extends the JFrame library class
class LoginScreen extends JFrame {

    //Creates a swing components and CardLayout for organising JPanels
JFrame container = this;
JPanel cardScreen;
JPanel screen = new JPanel();
Image ProgramIcon = Toolkit.getDefaultToolkit().getImage("imageIco.png");
ImageIcon logo = new ImageIcon ("Logo.png");
JLabel icon = new JLabel(logo);
JLabel username = new JLabel("Username");
JLabel password = new JLabel("Password");
JTextField user = new JTextField(18);
JPasswordField pass = new JPasswordField(18);
JButton login = new JButton("Login");
JLabel errorInfo = new JLabel("");
int WIDTH = 800;
int HEIGHT = 500;
int currentPanel = 1;

public static void main(String[] args){
//Sets the GUI (Look and Feel) to the NimROD theme
    try {UIManager.setLookAndFeel("com.nilo.plaf.nimrod.NimRODLookAndFeel");}
    catch (UnsupportedLookAndFeelException e){ JOptionPane.showMessageDialog(null, "GUI Load Error: Unsupported");}
    catch (ClassNotFoundException e) { JOptionPane.showMessageDialog(null, "GUI Load Error: NimROD Missing");} 
    catch (InstantiationException e) { JOptionPane.showMessageDialog(null, "GUI Load Error: Instantiation Missing");} 
    catch (IllegalAccessException e) { JOptionPane.showMessageDialog(null, "GUI Load Error: Illegal Access"); } 

//Creates a new LoginScreen via the LoginScreen method
    LoginScreen LS = new LoginScreen();
}

public LoginScreen(){
//Adds the JPanel to the JFrame and set the JFrame's properties
//Sets the main JPanel to CardLayout platform and adds other JPanels it
    final CardLayout cardL = new CardLayout();
    cardScreen = new JPanel();
    cardScreen.setLayout(cardL);
    cardScreen.add(screen, "1");;
    BaseScreen base = new BaseScreen();
    cardScreen.add(base, "2");
    container.setIconImage(ProgramIcon);
    container.setTitle("Login");
    container.setSize(WIDTH,HEIGHT);
    container.setResizable(false);
    container.setVisible(true);
    container.add(screen);
    container.setDefaultCloseOperation(EXIT_ON_CLOSE);

//Place the components on the JPanel and set there absolute posistions
    screen.setLayout(null);
    screen.add(username);
    screen.add(password);
    screen.add(user);
    screen.add(pass);
    screen.add(login);
    screen.add(icon);
    Dimension iconSize = icon.getPreferredSize();
    Dimension usernameSize = username.getPreferredSize();
    Dimension passwordSize = password.getPreferredSize();
    Dimension loginSize = login.getPreferredSize();
    Dimension userSize = user.getPreferredSize();
    Dimension passSize = pass.getPreferredSize();
    username.setBounds(252,170,usernameSize.width,usernameSize.height);
    password.setBounds(495,170,passwordSize.width,passwordSize.height);
    user.setBounds(180,200,userSize.width,userSize.height);
    pass.setBounds(420,200,passSize.width,passSize.height);
    login.setBounds(375,250,loginSize.width,loginSize.height);
    icon.setBounds(250,50,iconSize.width,iconSize.height);

    login.addActionListener(new ActionListener() { 
        public void actionPerformed(ActionEvent ae) { 
            cardL.show(cardScreen,"2");
            }
        }); 
}

BaseScreen Class:

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


class BaseScreen extends JPanel{

JPanel screen = this;
JButton logout = new JButton("Logout");
ImageIcon title = new ImageIcon("title.png");
JLabel header = new JLabel(title);

public BaseScreen(){

    screen.setVisible(true);
    screen.setLayout(null);
    screen.add(logout);
    screen.add(header);
    Dimension headerSize = header.getPreferredSize();
    Dimension logoutSize = logout.getPreferredSize();
    logout.setBounds(720,440,logoutSize.width,logoutSize.height);
    header.setBounds(0,0,headerSize.width,headerSize.height);

    ButtonHandler handle = new ButtonHandler();
    logout.addActionListener(handle);
}

    public class ButtonHandler implements ActionListener{

    public void actionPerformed(ActionEvent event){

        if (event.getSource() == logout){

        }
    }
  }

}

Thanks in advance for any help/tips.

Here's the old thread: Using multiple classes with the same JFrame

EDIT:

Here's the error:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at LoginScreen$1.actionPerformed(LoginScreen.java:84)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:272)
at java.awt.Component.processMouseEvent(Component.java:6288)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6053)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4651)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4481)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:643)
at java.awt.EventQueue.access$000(EventQueue.java:84)
at java.awt.EventQueue$1.run(EventQueue.java:602)
at java.awt.EventQueue$1.run(EventQueue.java:600)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98)
at java.awt.EventQueue$2.run(EventQueue.java:616)
at java.awt.EventQueue$2.run(EventQueue.java:614)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:613)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Upvotes: 2

Views: 668

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347314

I don't know about your NullPointerException, but your example doesn't work.

class LoginScreen extends JFrame

It's very rare to need to ever extend from a top level container, like JFrame, it's unnecessary and just complicates matters, use something like JPanel instead and add it to a frame you created...

JFrame container = this;

IMHO, this is a bad idea. It just confuses the issue. If you really need some way to reference the parent object, use this directly...

You call container.setVisible(true) before you've finished adding components to the frame, this is never a good idea. In fact, when I loaded your program correctly (starting from within the EDT), nothing appeared on the frame - but that was probably due to the next problem...

You create cardScreen, you create screen, you add screen to cardScreen then you add screen directly to the frame...This has effectivly removed screen from the cardScreen container...this might explain you NPE.

screen.setLayout(null) this is NEVER a good idea. Personally, I can't stand non-resizable frames, I know there are times to use them, but that doesn't mean I need to like them. I think I might stop answering questions that use null layouts without good reason :P

Take the time to learn and understand layout managers, they are one of the most powerful features of Swing

Upvotes: 2

Related Questions