Reputation: 13824
I do apologize in advance for creating this question, I do .NET so I know "how it feel" to ask this question, but I did search and tried to debug my program in Eclipse and still could not figure-out how to fix it, since I am totally new to Java GUI and first time using Eclipse, so ...
I have small program Java swing GUI program, where you have 2 buttons, one of them is hidden (visible set to false) when click on a button, it will shows the hidden button (set Visible to true):
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class TestButton extends JPanel {
private JFrame mainFrame;
private JButton btnShow ;
private JButton btnNew;
public TestButton() {
mainFrame = new JFrame("Test Button");
JButton btnShow = new JButton("Show New Button");
JButton btnNew = new JButton("This is New Button");
Container c = mainFrame.getContentPane();
c.setLayout(new FlowLayout());
c.add(btnShow);
c.add(btnNew);
btnNew.setVisible(false);
btnShow.setMnemonic('G');
btnNew.setMnemonic('N');
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
ShowButtonHandler ghandler = new ShowButtonHandler();
btnShow.addActionListener(ghandler);
mainFrame.setSize(250, 150);
mainFrame.setLocationRelativeTo(null);
mainFrame.setResizable(false);
mainFrame.setVisible(true);
}
class ShowButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
btnNew.setVisible(true);
}
}
public static void main(String args[]) {
TestButton app = new TestButton();
}
}
But when I click that button, it shows Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
The error was at this line: btnNew.setVisible(true);
Here is the full trace:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at TestButton$ShowButtonHandler.actionPerformed(TestButton.java:51)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$400(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
So normally Null Exception happens when object was not initialized, but I did initialized the btnNew when declaring it, didn't I? Where is the problem here?
Also, I want to add 1 more button called "Run again" where you click on it, it closes current windows and open the new one (Basically I want re run program again) , is it possible that way or how to I archive it?
Upvotes: 1
Views: 8329
Reputation: 51353
Your local variable is hiding the instance variable
Change
JButton btnNew = new JButton("This is New Button");
to
btnNew = new JButton("This is New Button");
EDIT
According to your question as a comment... but it would be better to ask a new question or post your code at https://codereview.stackexchange.com/.
What I mean is that your inner class ShowButtonHandler
depends on the outer class TestButton
, because it uses the outer class's field btnNew
.
class ShowButtonHandler implements ActionListener {
public void actionPerformed(ActionEvent e) {
btnNew.setVisible(true);
}
}
But this dependency is not necessary. The ShowButtonHandler
only needs a reference to a JButton
that it must set visible when an action is performed.
So in a first step you can break the dependency to the outer class by simply pass the button as a constructor argument.
class ShowButtonHandler implements ActionListener {
private JButton btnNew;
public ShowButtonHandler(JButton btnNew){
this.btnNew = btnNew;
}
public void actionPerformed(ActionEvent e) {
btnNew.setVisible(true);
}
}
Now you realize that the ShowButtonHandler
could be more flexible to allow reuse. You take a look at the class hierarchy and you see that setVisible
can be done for any JComponent
. So you can make the class more general.
class ShowComponentHandler implements ActionListener {
private JComponent component;
public ShowComponentHandler(JComponent component){
this.component = component;
}
public void actionPerformed(ActionEvent e) {
component.setVisible(true);
}
}
Since the ShowButtonHandler
is now independent and has a more general API it can be placed in an own compilation unit (java file) and be re-used.
In your TestButton
class you can still use it
ActionListener showComponentAction = new ShowComponentHandler(btnNew);
btnShow.addActionListener(showComponentAction);
Upvotes: 6