1

I sometimes see code like this:

new myJFrame().setVisible(true);

I don't exactly know how it works, but it actually creates a myJFrame and sets it visible, as an alternative to setting it visible on its constructor.

What I would like to know is if there would be a way to do this on a JMenuItem or JButton to automatically assign it an ActionListener without having to explicitly declaring it first, as in:

myJMenu.add(new JMenuItem("Item").addActionListener(myActionListener));

Which, as far as I've tried, doesn't work.

I don't exactly need it to work, I would just like to know if it is possible, for it would save me some good time.

Thanks in advance.

André Leria
  • 392
  • 3
  • 17

4 Answers4

3

It's called method chaining and simply put, a class either supports it or not, depending on how it's written.

The way it is done is simple:

public class Bar {

   private Set<Foo> foos;

   public Bar addFoo( Foo foo ) {
     this.foos.add( foo );
     return this;
   }
}

From this you can also see why it isn't possible to chain methods that weren't written this way.

biziclop
  • 48,926
  • 12
  • 77
  • 104
  • You mean I can only do it with classes I've created and written this way? More specifically, can I do it with JMenuItem and / or with JButton? (For I don't know if I can see how they were created) – André Leria Jun 07 '12 at 20:17
  • @AndréLeria Yes. Or classes that someone else wrote this way. Swing classes are usually not written in this style. But if you read the javadoc of a method, it should be obvious: if the documentation says the method returns `this`, then you can chain them. If it returns `void`, you can't. – biziclop Jun 07 '12 at 20:19
3

Your proposed code won't work because JMenuItem.addActionListener() does not return anything (it's a void method), so there is nothing to pass as the argument to JMenu.add().

In the first example, there is also nothing returned, but it doesn't matter.

As mentioned by @biziclop, in some styles of coding most methods return this so that they can be chained together. For example, Builders which use a Fluent Interface tend to do this.

user949300
  • 15,364
  • 7
  • 35
  • 66
3

As an alternative, consider using the JMenuItem constructor that takes an Action:

myJMenu.add(new JMenuItem(new AbstractAction("Item") {

    @Override
    public void actionPerformed(ActionEvent e) {
        ...
    }
});
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
0

if you want nastiness you can do an anonymous extension of a non-final class and add an anonymous constructor to initialize stuff:

ArrayList ar=new ArrayList()  
    {
      {
        add(new Object());
      }
    };
Markus Mikkolainen
  • 3,397
  • 18
  • 21