2

I am a beginner java programmer, trying to implement ActionListener through an Inner class. Following is the simple code where I want to change label text on button click but instead of using getSource for more than one components I want to use Inner Class. Here is my code :

public class InnerClasses extends JPanel  { 

    static   JFrame frame ;     
    static JButton button ; 
    static  JLabel   label  ; 
    public static void main(String[] args) {    
        InnerClasses i=  new InnerClasses();    
        frame= new JFrame("Inner class");
        frame.setSize(400,400);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    
        frame.add(i);
        label = new JLabel(BorderLayout.NORTH);
        label.setText("I m label");
        i.add(label);    
        button = new JButton(BorderLayout.SOUTH);
        button.setText("Click me ");
        button.addActionListener(new  innerclass() );
        i.add(button);
        frame.setVisible(true);
    }

    class  innerclass implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent arg0) {    
            label.setText("i have been changed");
        }    
    }

now when i try to register listener to button it gives error

No enclosing instance of type InnerClasses is accessible. Must qualify the allocation with an enclosing instance of type InnerClasses (e.g. x.new A() where x is an instance of InnerClasses).

Please help me with it if i am doing something agaisnt the syntax or whats wrong here

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • Possible duplicate of [Java - No enclosing instance of type Foo is accessible](http://stackoverflow.com/questions/9560600/java-no-enclosing-instance-of-type-foo-is-accessible) – fabian Mar 04 '16 at 00:26

2 Answers2

2

Your inner class is not static, so you cannot instantiate it from a static method, and in general, it is better to define inner classes as static, otherwise a new class (not instance) will be created for each instance of the enclosing class:

static class  Innerclass implements ActionListener
MByD
  • 135,866
  • 28
  • 264
  • 277
  • yes it solved my problem , please explain what do you mean by " otherwise a new class (not instance) will be created for each instance of the enclosing class:" –  Jul 15 '13 at 13:42
  • 1
    Ejaaaactly, the case, learning C# now a days, so got confused, in which language, the inner class is static by default. This answer did refreshed my memory for that matter :-) +1, to it, though my up-vote will come in 10 hours :( – nIcE cOw Jul 15 '13 at 14:55
1
  • to create any GUI required some hierarchy, based on Oracle tutorials and good practicies, code ordering could be important

  • don't to create any Swing GUI Objects inside main methods

  • I can't found any reason to declare anything static in Java

for example

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class InnerClasses {

    private JFrame frame;
    private JPanel panel;
    private JButton button;
    private JLabel label;

    public InnerClasses() {
        label = new JLabel();
        label.setText("I m label");
        button = new JButton();
        button.setText("Click me ");
        button.addActionListener(new MyActioListener());
        panel = new JPanel();
        panel.add(label);
        panel.add(button);
        frame = new JFrame("Inner class");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(panel);
        frame.setSize(400, 400);
        frame.setVisible(true);
    }

    class MyActioListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            label.setText("i have been changed");
        }
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                InnerClasses innerClasses = new InnerClasses();
            }
        });
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • there is a problem in this way , if i put frame etc in Constructor i cant pass instance of my class ( InnerClasses innerClasses = new innerClasses();) to frame.add(innerClasses )// this gives error –  Jul 15 '13 at 13:55
  • 1
    @JavaStudent : For that matter simply use `frame.add(this)`, since your `InnerClasses` extends `JPanel`, so no need to create an object of `InnerClasses`, instead use `this` keyword for the same purpose :-) +1 to the answer, which will come in 10 hours :( – nIcE cOw Jul 15 '13 at 14:52