开发者

Pass a block to a method in Java

开发者 https://www.devze.com 2023-02-21 02:53 出处:网络
I have a GUI element which is used across several different points in a swing application. When the \'OK\' button is pushed I need to run different code in each instance.

I have a GUI element which is used across several different points in a swing application. When the 'OK' button is pushed I need to run different code in each instance.

I have gotten around this by passing an action listener in each case but as I continue this开发者_高级运维 is getting messy. It would be preferable to pass a block to a method as is possible in Ruby. I am wondering if something similar but clean exists in Java.

Messy code: Mostly due to needing to call methods on elements of the GUI object. If I pass the ActionListener in the constructor the object doesn't exist yet. I can call a second method in each instance but it isn't preferable.


You have the right idea already. The usual solution for passing arbitrary blocks of code into methods is a Command pattern. If you can show an example of the "messy" code you have now, it might be possible to help you clean it up.

Update Re: Messy Code

If I pass the ActionListener in the constructor the object doesn't exist yet.

An actual code sample would help a lot in giving a good response. At a guess, I would say perhaps you want to look at a Factory pattern? In this case, I'm thinking more of the encapsulation benefits than the polymorphic benefits. Again, just guessing. Seeing code helps.


Passing an ActionListener implementation is probably the best you can do right now.

Java 8 will provide support for "closures", which will greatly streamline the implementation of interfaces with a single, one-argument methods. But, with Java 7 barely coming out, it will be a few years for Java 8.


Java does not support the idea of code-blocks (or functions, for that matter) as first-class citizens. That's why events are done via classes that implement particular interfaces. You seem to be doing something similar already, so perhaps you just need to create your own interface that supports the particular events you want to support.


The solution I have gone with doesn't really address the title of the question properly but suited my needs perfectly. Because:

  • In my case it is always the same functionality being parsed (ie, the onConfirm functionality) and this functionality is required in each instance.
  • Each instance requiring unique functionality did not really suit a factory pattern.

I have made my GUI element abstract:

abstract class Element extends JPanel {

    ...
    private final JButton button = new JButton("OK");

    protected abstract void onConfirm();

    public Element(){
        this.button.addActionListener(new ActionListener(){
            @Override public void actionPerformed(ActionEvent e) {
                onConfirm();
            }
        });
        ...
    }
}

With several anonymous inner class implementations which each allow me to access the internals of the GUI Element.

this.getContentPane().add(new Element(){
    @Override public void onConfirm() {
        doStuffWithCommand();
    }
});
0

精彩评论

暂无评论...
验证码 换一张
取 消