mhashem6 mhashem6 - 3 months ago 18
Java Question

trouble in overriding JFrame.setBackground()

I have a class called MainUI that extends JFrame, it has this code :

//Constructor
public MainUI(){

// components/panels are already defined and initialized here.

setBackground(Color.decode("#EFF4E4"));
}

@Override
public void setBackground(Color colorbg){ //a method to set the same background color for all the components I ave

getContentPane().setBackground(colorbg);

decisionPanel.setBackground(colorbg);

adbRadio.setBackground(colorbg);
fastbootRadio.setBackground(colorbg);
commandRadio.setBackground(colorbg);

pushPanel.setBackground(colorbg);
uninstallPanel.setBackground(colorbg);
pcPanel.setBackground(colorbg);
phonePanel.setBackground(colorbg);
}


however, when I compile, it gives a NullPointerException at the line [ decisionPanel.setBackground(colorbg); ]

I tried not overriding the setBackground method and renamed it and the code worked fine, I don't know why overriding setBackground method causes a problem?

I'm sure all the panels/components are initialized before the call to the method, it's obvious since the code did work just ater I've renamed the method.

Answer

This is a snip of code from JFrame class it is really doing the unrecommended call of overridable method from constructor what happens is that your overridden version is executed before your class has been created "and before your fields are initialized and their is no way to initialize your fields before the super's constructor finishes its work" so you have few options either avoid referring to your subclass fields in the overridden method/s or do what you did by making new method to do the stuff you want

public JFrame(String title, GraphicsConfiguration gc) {
        super(title, gc);
        frameInit();
    }

    /** Called by the constructors to init the <code>JFrame</code> properly. */
    protected void frameInit() {
        enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK);
        setLocale( JComponent.getDefaultLocale() );
        setRootPane(createRootPane());
        setBackground(UIManager.getColor("control"));
        setRootPaneCheckingEnabled(true);
        if (JFrame.isDefaultLookAndFeelDecorated()) {
            boolean supportsWindowDecorations =
            UIManager.getLookAndFeel().getSupportsWindowDecorations();
            if (supportsWindowDecorations) {
                setUndecorated(true);
                getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
            }
        }
        sun.awt.SunToolkit.checkAndSetPolicy(this);
    }

or you can override the frameInit()

@Override
    protected void frameInit() {
        //initialize your fields here 
        super.frameInit();
    }
Comments