views:

78

answers:

3

Hi,

How would I go about writing a constructor for an inner class which is implementing an interface? I know I could make a whole new class, but I figure there's got to be a way to do something along the line of this:

JButton b = new JButton(new AbstractAction() {

    public AbstractAction() {
        super("This is a button");                        
    }


    public void actionPerformed(ActionEvent e) {
        System.out.println("button clicked");
    }
}); 

When I enter this it doesn't recognize the AbstractAction method as a constructor (compiler asks for return type). Anyone have an idea?

Thanks

+6  A: 

Just insert the parameters after the name of the extended class:

JButton b = new JButton(new AbstractAction("This is a button") {

    public void actionPerformed(ActionEvent e) {
        System.out.println("button clicked");
    }
}); 

Also, you can use an initialization block:

JButton b = new JButton(new AbstractAction() {

    {
       // Write initialization code here (as if it is inside a no-arg constructor)
       setLabel("This is a button")
    }

    public void actionPerformed(ActionEvent e) {
        System.out.println("button clicked");
    }
}); 
Itay
answers my question perfectly, thanks!
thepandaatemyface
A: 

The resulting class is not of type AbstractAction but of some (unnamed, anonymous) type that extends/implements AbstractAction. Therefore a constructor for this anonymous class would need to have this 'unknown' name, but not AbstractAction.

It's like normal extension/implementation: if you define a class House extends Building and construct a House you name the constructor House and not Building (or AbstractAction just to com back to the original question).

Andreas_D
+2  A: 

If you really need a contructor for whatever reason, then you can use an initialization block:

JButton b = new JButton(new AbstractAction() {

    {
        // Do whatever initialisation you want here.
    }

    public void actionPerformed(ActionEvent e) {
        System.out.println("button clicked");
    }
}); 

But you can't call a super-class constructor from there. As Itay said though, you can just pass the argument you want into the call to new.

Personally though, I would create a new inner class for this:

private class MyAction extends AbstractAction {

    public MyAction() {
        super("This is a button.");
    }

    public void actionPerformed(ActionEvent e) {
        System.out.println("button clicked");
    }
}

then:

JButton b = new JButton(new MyClass());
DaveJohnston