The Source for Java Technology Collaboration
User: Password:



Rémi Forax

Rémi Forax's Blog

Is closure swing ?

Posted by forax on August 29, 2006 at 04:08 PM | Comments (9)

Yes, this is another entry about closure :)

In the closure proposal, the section "Closure conversion" describes how to use a closure instead of an anonymous class.
The rules are :

  • the implemented interface must have one method
  • the closure signature must be a subtype of the method signature

So let see if these rules are sufficient to use closures in order to implement AWT/Swing callbacks.

 

Implementing an ActionListener

ActionListener corresponds to a component default action, it's a one method interface, the method actionPerformed takes an ActionEvent that contains among other things the component that received the event.

  public interface ActionListener {
    void actionPerformed(ActionEvent e);
  }

So the client code can be this one :

 JButton button=new JButton("Ok");
 button.addActionListener(() {
   button.setText("Ko");
 });

Oh no !!!
This code is too optimistic, it assumes that because the event is not used, the parameter can be omit. But there is no such rule in the proposal. The correct code is the following :

 JButton button=new JButton("Ok");
 button.addActionListener((ActionEvent notUsed) {
   button.setText("Ko");
 });

The moral

It could be a good idea to add a closure conversion rule that permits parameters omission. Perhaps this rule can be extended to allow the omission of the last parameters from the right.

What do you think about that ?


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • The shorthand syntax we're working on would allow you to write

    button.addActionListener(ActionEvent notUsed) {
    button.setText("Ko");
    }

    Posted by: gafter on August 29, 2006 at 09:33 PM

  • Neal,
    You can't just change the UI-related attributes without running this logic on the EDT using SwingUtilities.invokeLater. So, will it become


    button.addActionListener(ActionEvent notUsed) {
    SwingUtilities.invokeLater() {
    button.setText("Ko");
    }
    }


    Have you considered the impact it would have on IDE debuggers, especially if you're going to use exceptions in the internal implementation?

    Posted by: kirillcool on August 30, 2006 at 12:01 AM

  • Neal,

    I'm not a big fan of the shortand syntax because it blurs the separation
    between the parameter list and the block.

    Note that even for you, this syntax is not obvious, you made a typo in your example, you forget the semicolon :)

    When i browse a code, if a function is not interresting for what i'am looking for
    i go to the next parenthesis, this is not possible with the shortand syntax.

    I greatly prefer having the posibility to omit a not used parameter but it's a matter of habit.

    Posted by: forax on August 30, 2006 at 01:03 AM

  • @kirillcool, a UI callback is always performed by the EDT,
    so i can't understand your point ?

    Perhaps by accident you have switched the two closures ?

    SwingUtilities.invokeLater({
    button.addActionListener(()(ActionEvent notUsed) {
    button.setText("Ko");
    });
    });

    Posted by: forax on August 30, 2006 at 01:10 AM

  • kirill ... don't most buttons only ever receive ActionEvents on the EDT?

    Posted by: jessewilson on August 30, 2006 at 01:57 AM

  • Thanks Remi, it's great to see some Swing examples for the whats, wheres and hows, of closures. This is what i've been waiting for :) Do you have any more examples?
    Incidently, in this example, i think i prefer the traditional anonymous class, probably because it's more familiar to me ;)

    Posted by: evanx on August 30, 2006 at 04:06 AM

  • Everybody,
    Indeed the action listener method is performed on EDT. However, if its logic involves changing some GUI-related attribute, it must be performed with SwingUtilities.invokeLater - which is scheduled as a separate event on the EDT to be performed after all pending EDT events have been processed. Otherwise you will trigger EDT events while being in the middle of processing another EDT event, which will cause other listeners to be executed while the current event is not fully processed. This may lead to some very nasty bugs which are hard to track.

    Posted by: kirillcool on August 30, 2006 at 08:31 AM


  • I've already seen this kind of bugs when trying to change the
    look and feel, but i don't think that it must be a coding practice
    because it will severly impact performance.
    (invokeLater/AndWait performs some synchronisation underneath)

    Rémi Forax

    Posted by: forax on August 30, 2006 at 09:37 AM

  • Remi,
    Unless you want an unpredictable behaviour that is almost impossible to reproduce when you need to fix it, you'd better change all UI-related properties inside SwingUtilities.invokeLater. This way you guarantee that the original event that you're currently processing will be processed by all other registered listeners before you fire a new event. This must be a coding practice for Swing application event handling and i never saw any performance-related issues with it. It's a small price to pay for not having the nightmare maintenance problems later on.

    Posted by: kirillcool on August 30, 2006 at 12:20 PM



Only logged in users may post comments. Login Here.


Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds