Skip to main content

JXLayer 3.0 - Getting started

Posted by alexfromsun on June 5, 2008 at 9:49 AM PDT

It is my pleasure to announce a major update of JXLayer component.
The new version is hosted on its own java.net project jxlayer.dev.java.net, where I will also provide links to all my blogs about this component.

So, why I encourage everybody to try out the new JXLayer?

Actually to answer this question I am going to write several more blogs, here is a short answer:

  1. more consistent and efficient API
  2. easier to use
  3. new functionality

The JXLayer 3.0 API is a bit different from the previous version and I had good reasons to make it this way. The good news is that I am very happy with the current API and I am not gonna introduce incompatible changes in the future. So, if you are using the previous JXLayer, it won't take much time to adjust your code for the new one, if you haven't tried it yet, it's high time to have a look.

JXLayer is the universal decorator for Swing components, it means that you have a flexible way to enrich the visual appearance of your components and control the input events for the whole component's hierarchy.

Just wrap your component with JXLayer and set a LayerUI which implements the required functionality.
On jxlayer.dev.java.net you'll find demos of several carefully tested and ready to use LayerUI's implementations. In this entry we are going to see how to create your own ones.

Here is a simple example how to create and use LayerUI which paints translucent foreground over the layer:

// wrap your component
        JXLayer layer = new JXLayer(myComponent);

        // create custom LayerUI
        AbstractLayerUI layerUI = new AbstractLayerUI() {

            @Override 
            protected void paintLayer(Graphics2D g2, JXLayer l) {
                // this paints layer as is
                super.paintLayer(g2, l);
                // custom painting:
                // here we paint translucent foreground
                // over the whole layer
                g2.setColor(new Color(0, 128, 0, 128));
                g2.fillRect(0, 0, l.getWidth(), l.getHeight());
            }
        };

        // set our LayerUI
        layer.setUI(layerUI);

        // add the layer as a usual component
        frame.add(layer);

BufferedLayerUI provides more functionality,
since it paints the layer to the double buffer image, it allows filtering the image with the BufferedImageOp subclasses. With it you can invert colors of a layer, blur it apply any other fancy effects.

For the Rainbow project I used BufferedLayerUI to implement the image editor dialog.

(Here are some more Rainbow screenshots)

Let's see how to apply the grayScale effect to a layer:

 // wrap you component
        JXLayer layer = new JXLayer(myComponent);

        // here we use BufferedLayerUI which can work with BufferedImageOps 
        BufferedLayerUI bufferedLayerUI = new BufferedLayerUI();
       
        // create a ColorConvertOp to apply grayScale effect
        BufferedImageOp grayScaleOp =
                new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_GRAY), null);

        // create a BufferedImageOpEffect with the provided BufferedImageOp
        BufferedImageOpEffect imageOpEffect = new BufferedImageOpEffect(grayScaleOp);
       
        // set BufferedImageOpEffect to the bufferedLayerUI
        bufferedLayerUI.setLayerEffects(imageOpEffect);
       
        // set the bufferedLayerUI to the layer
        layer.setUI(bufferedLayerUI);

        // add the layer as a usual component
        frame.add(layer);

And now is the very important news: with JXLayer 3.0 you can catch layer's input events as easy as implement a custom painting. AbstractLayerUI introduces several methods: processFocusEvent, processMouseEvent, processMouseMotionEvent, etc...

The names of the methods speak for themselves. If you'd like to catch all mouseEvents for all components inside your layer - just override processMouseEvent in your custom AbstractLayerUI subclass.

MouseDrawingDemo combines painting and mouse events processing together.


src="http://java.sun.com/products/jfc/tsc/sightings/images/webstart.small.jpg">

In this demo you can paint over the layer with your mouse, just like you do in any other image editor.

Note that components are alive when you paint over them.

I hope this short overview will help you to invent your own ways of using JXLayer in your projects.

See you one the JXLayer forum

With best wishes

alexp

Related Topics >>

Comments

Is JXLayer the replacement for JXPanel from the SwingX jar? Or is this an entirely different project? I am confused :) If they are different projects, what is the difference between JXLayer and JXPanel? Rob

Hello Dave

There is no need to reanimate JXTransformer, because SceneGraph is available
It uses some code from JXTransformer, by the way

Thanks
alexp

Alex, Any chance JXTransform will get the same treatment? Thanks, Dave

Hi Alex, I haven't used your component before, but I have a quick question: Can I use JavaFX classes to decorate my Swing components through your JXLayer component. As you know, with the compiler version, JavaFX classes now gets compiled into .class files, so at least I should be able to instantiate them from the JXLayer side of things.

Well, Scenegraph is not an option at this time. It is released under *pure* GPL, so it is illegal to link it to any non-GPL app. Right now the JavaFX code itself is violating the GPL...it is not released under GPL but uses code (Scenegraph) released under GPL. Someone at Sun needs to take a basic course in OSS licenses. :-)

@jacek, I suppose, however that given that Sun is the copyright holder of Scenegraph, they can use it as they wish, and release it under as many different licenses as they want. A license isn't attached to a particular project as a whole, but to a specific distributed bundle of code. I may have two bundles of code, that are in fact identical, except for the license file that stipulates the conditions of use for that distributed bundle, but that is sufficient to ensure that those bundles are handled different by the recipients.

Hello Steve

I would suggest going to jxlayer.dev.java.net,
downloading jxlayer-all.zip and playing with demos from jxlayer.demo package
please send your comments to the JXLayer forum

Thanks
alexp

Hello Sozonovsky

Swing doesn't provide a way to change components hierarchy this way, at run time
e.g. you also can't wrap your existing components with JScrollPane on the fly
or just remove a component and add it back, because layout constraints will be lost

JXLayer is not a magic component which can change the existing hierarchy at run time
treat it as ordinary Swing components which you use when write your GUI and not after it

Thanks for your support
alexp

Hi Alex the JXLayer looks really interesting and it maybe of use for a project I am looking at. Are the more example uses of it anywhere and any other documentation other than the API docs. It difficult trying to grasp what its capable of just looking at the links from this page. Thanks Steve

Hello Mikeazzi

I've never hear about using JavaFx classes in Swing application.
Using Swing components in JavaFx is more common.

I made a quick javaFx test - I could create and use JXLayer and existing LayerUIs from JavaFx script

Thanks
alexp

Hello Jim BlendComposite is from SwingX library, isn't it? It's great to hear that it works well together with JXLayer Actually I haven't used it and not sure about modes you mentioned, I think it a good question for the SwingLabs forum href="http://forums.java.net/jive/forum.jspa?forumID=73&start=0 Thanks alexp

Hi Alex I have been playing around with your SimpleDemo - thanks for this, I always learn more quickly with simple examples. I find I get much more pleasing effects using: BlendComposite.BlendingMode.MULTIPLY for setComposite. This preserves the text colour unlike AlphaComposite.SRC_OVER which lightens it too much The BlendComposite modes are quite confusing; I find I get the same results with the DARKEN and SUBTRACT modes - which one would be better in most cases? Jim

Hello Alex, Maybe a little not relevant question, nevertheless. Do you know a way how to wrap components into JXLayer at runtime? Problem is layout constrains are lost, for example. It seems Swing API doesn't support that, but if there was a trick to get that, it would be extremely useful, at least for projects with separated GUI and business logic development. Any idea? Thanks in advance and good luck with JXLayer!