User Tools

Site Tools


Sidebar

Dave Orme muses about data-first development.

My current work emphasizes data engineering and analysis using Kubernetes, Clojure, Scala, Eclipse, and Google Cloud Platform or AWS.


Blog

The Cloud

Scala, Clojure, and FP

Data-First Development

Agile

Older work

Coconut Palm Software home


Donate Bitcoin:

1Ecnr9vtkC8b9FvmQjQaJ9ZsHB127UzVD6

Keywords:

Kubernetes, Docker, Streaming Data, Spark, Scala, Clojure, OSGi, Karaf, GCP, AWS, SQL

Disclaimer:

Everything I say here is my own opinion and not necessarily that of my employer.

blog:duck_typing_helps_automatically_dispose_swt_images

Duck Typing helps automatically dispose SWT Images

Let's look at a really practical example of why Duck Typing is important in Java. This example will use Java reflection to hack duck typing but will provide a basis for future discussion of how to really implement the technique in Java.

If you need to make SWT automatically dispose Image objects, here's a simple class that gets the job done quite painlessly:

    public class ImageMgr implements DisposeListener {
 
        private Image image;
 
        public ImageMgr(Image image) {
            this.image = image;
        }
 
        public ImageMgr(Control receiver, Image image) {
            this.image = image;
            try {
                // Use duck typing--any class with setImage() will work
                Method setImage = receiver.getClass().getDeclaredMethod("setImage",
                                       new Class[] {Image.class});
                setImage.invoke(receiver, new Object[] {image});
            } catch (Exception e) {
                // Programmer error: throw a RuntimeException
                Logger.log().error(e, "Unable to setImage()");
                throw new RuntimeException(e);
            }
            receiver.addDisposeListener(this);
        }
 
        public void widgetDisposed(DisposeEvent e) {
            if (!image.isDisposed())
                image.dispose();
        }
 
        public Image get() {
            return image;
        }
 
    }

Notice that if the control you're putting the Image on uses the setImage() method name (most do), you can just use the convenience constructor as follows:

    CLabel label = new CLabel(parent, SWT.NULL);  // Class with setImage() method
    new ImageMgr(label, new Image(Display.getCurrent(),
                 getClass().getResourceAsStream("icons/etool16/image.gif")));

This will automatically add the image to the control with the setImage() method (we're using a CLabel as an example here) and automatically set the ImageMgr object as a dispose listener on the control. Now when the SWT control is disposed (automatically by its parent), the Image will automatically be disposed too.

But what does all of this have to do with duck typing?

Naming Conventions create Duck Types

In Java, a Duck Type is an interface that is implemented consistently throughout a framework but is never declared anywhere.

For example, nearly every SWT class that accepts an Image does so via a setImage() method call. However, there is no SettableImage interface anywhere in SWT that is implemented by all of these classes. Furthermore, there are so many of these naming conventions, or Duck Interfaces, in SWT that it would be absurd for SWT to actually declare all of these interfaces and implement them consistently everywhere. Nearly every SWT class would be implementing a ton of interfaces!

However, this class illustrates the convenience of being able to use Duck Typing in Java to be able to treat all classes with a similar behavior the same way.

In a future article, we will look at how to get our interfaces back and fully implement Duck Typing and Duck Interfaces in Java.

~~LINKBACK~~ ~~DISCUSSION:closed~~

blog/duck_typing_helps_automatically_dispose_swt_images.txt · Last modified: 2014/10/17 22:08 (external edit)