I did some searching in the forum and didn’t find anything similar yet. Here’s my problem:
I have a component with a lot of sub-components (all on the same hierarchy level) that can overlap each other. The sub-components are supposed to react on mouse events in case they are activated. A click activates a group of sub-component, all other actions do other stuff to the subcomponent. So I want the sub-component on mouseDown to decide if it wants the event and then handle it or if it doesn’t want the event pass it on so that a sub-component that might be underneath it receives the event. Is there a simple way to do that, or do I have to implement all the mouseListener logic myself.
There’s no support for passing on events, because it’s actually quite a dangerous thing to do (e.g. some comps might be unstable if you call their mouse-drag without having sent a mouse-down, so if you had a component above it that sometimes consumed the mouse-downs, then that’s the sort of thing that can happen).
Usually there are neater tricks to do things like this anyway - e.g. using a transparent overlay comps or the hitTest() method.
Hm, could you elaborate a bit? To give you a better idea of what I’m doing: imagine a piano roll that displays several MIDI tracks at the same time - so some note-comps may overlap. To worsen the problem: my note objects have a vertical size of 3 semitones although they display only one semitone (this has a reason ). So if two notes are at exactly the same position and have the same size but only one semitone away, only one note (the last drawn one I suppose) gets the mouseDown.
Sounds to me like you’re trying to put too much of your logic into the UI. If you have a proper object model to represent these notes, you should be able to make any component manipulate the model, with the UI following those changes, rather than trying to make the UI components interact with each other (hope I explained that well enough…)
Hm, I’m not really getting it :? But maybe that’s due to my inferior OOP knowledge.
I have a data object representing the MIDI track that holds the single note data objects and an UI object that is the piano roll that is linked to the MIDI track objects and holds note UI objects that in turn are linked to the corresponding note data objects. Seems like a proper way to do it to me, and I don’t see how changing that would solve the problem that a specific UI note object doesn’t receive a mouseDown???
You could have one transparent layer per midi track and several NoteComponent objects per layer. The layers shouldn’t intercept mouse clicks, they’re just component holders.
you could call toFront() on the active layer to make sure the active layer notes are always on top of other notes. that way you can also easily show/hide/enable groups of notes using setVisible() setEnabled()… etc
yeah, that’s what I thought. It also works when I set all the notes that belong to the active track toFront() - but maybe the transparent layer is more elegant.
However, still another problem is that the bounds of my note objects are bigger than they are drawn. so the note has a height of one semitone and a tranparent part of a semitone each above and below. If now there is a note from a different track right beneath one of these transparent parts, it will not get the click (that it needs to activate the track) - which is logical from the programmers perspective but probably not from the users : Well, if there is no solution for this, I’ll probably have to re-consider my note objects.