Skip to main content

JXLayer and JLayeredPane

5 replies [Last post]
ronslow
Offline
Joined: 2009-05-12
Points: 0

Fantastic tool - I'm really impressed

I need to send AWTEvents from the top layer in a JLayeredPane to the bottom layer.

I have implemented AbstractLayerUI, overriding eventDispatched(AWTEvent, JXLayer) so as to intercept events on the top layer

I have wrapped all of the layers in the JLayeredPane in a JXLayer, and called jxLayer.setUI(abstractLayerUI) for each

Events are successfully being intercepted.

What should I call on the (wrapped) bottom layer?

I have tried the following:

AbstractLayerUI ui = new AbstractLayerUI() {
@Override
public void eventDispatched(AWTEvent e, JXLayer<? extends JComponent> layer) {

super.eventDispatched(e, layer);
if (layer != root)
root.dispatchEvent(e);
}
};

but I think this is looping.

Any ideas?

Thanks

Robert

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
alexfromsun
Offline
Joined: 2005-09-05
Points: 0

Hello Robert

I don't recommend using Component.dispatch() method,
wrapping every layer in JLayeredPane also looks fishy for me

Could you give more details about what you are trying to achieve?

Thansk
alexp

ronslow
Offline
Joined: 2009-05-12
Points: 0

Alex.

I have a class called LayeredPane. It extends JLayeredPane and allows users to add named transparent layers over a root layer:

LayeredPane.add(JComponent c, String name);

One layer is designated as a non-transparent root layer:

LayeredPane.setAsRoot(String name);

The user can set any layer as the top layer to receive events:

LayeredPane.setAsTop(String name);

I now have a requirement to intercept events received on the top layer and pass them to the root layer. That is when I turned to JXLayer.

In LayeredPane.add(JComponent c, String name), instead of adding the component directly, I wrapped the component c in a JXLayer before adding it to the JLayeredPane:

JXLayer jxLayer = new JXLayer(c);

I implemented an AbstractJXLayerUI to intercept the events

AbstractJXLayerUI ui = new AbstractJXLayerUI() {

@Override
public void eventDisptached(AWTEvent e, JXLayer layer) {

//intercepted events arrive here;

}

};

and called, for each layer being added, I called:

jxLayer.setUI(ui);

Events on the top layer are arriving in eventDispatched(AWTEvent e, JXLayer layer). So far so good.

Now I want to pass these events to the root layer (which is now an opaque JComponent wrapped in a JXLayer)

The obvious solution seemed to be

((JXLayer) root).getView().dispatchEvent(e) but this is causing the exception.

Give your experience of relaying events between components, what is the best way of passing the events to the root layer?

Robert

alexfromsun
Offline
Joined: 2005-09-05
Points: 0

Hello Robert

Actually one of the reason to create JXLayer was the fact
that I didn't like using and extending the JLayeredPane component in the custom code

JXLayer is not designed for the case you described

If you don't set your LayeredPane as a JFrame's rootPane,
you should wrap it with JXLayer once and get all the events

Redispatching events with Component.dispatchEvent(e) method
is not really supported in Swing and cause lots of problems when you try it

Thanks
alexp

ronslow
Offline
Joined: 2009-05-12
Points: 0

Alex
Can I ask you this.

I have a requirement as follows:

I need to build up a layered JComponent:

LayeredPane extends JPanel

Different vendors contribute different layers. They call:

add(JComponent comp, String name);

on LayeredPane

One layer is designated as root by calling:
setRoot(String name);

on LayeredPane.

Non-root layers are transparent.

Each vendor may attach a mouse listener to their own layer.

But all mouse events must also go through to the root layer to be picked up by the mouse listener attached to that component.

How would I do that using JXLayer?

Robert

alexfromsun
Offline
Joined: 2005-09-05
Points: 0

Hello Robert

I am sorry to say that, but this Swing is not designed to support scenarios like you described,
if mouseEvent is caught by a particular component
it is not supposed to be redispatched to another one

With JXLayer you can do the following:

wrap your LayeredPane with JXLayer
and catch all mouseEvents for all its subcomponents in the LayerUI.eventDispatched() method

Thanks
alexp