This week's book giveaway is in the OCAJP forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide 1Z0-808 and have Jeanne Boyarsky & Scott Selikoff on-line! See this thread for details.
So here is the problem. I'm trying to move JComponents inside one JPanel and track location changes inside another one. In a nutshell, I'm trying to bind 2 properties of Java Beans. I tried to model the situation in this simple applet as accurate as possible. So the label moves and fires the property changes, but the tracking label doesn't receive the event. I guess it has something to do with the fact, that the components are inside different panels. Any help would be highly appreciated. Here is the code:
Rob, thanks for your answer. But I don't want to handle the componentMoved event. The whole reason behind using the data binding model, that the component that fired the propertyChanged event doesn't know anything about interested parties, which makes sense in this use case. So I insist on handling the propertyChanged event, just not quite sure how to implement that.
Anton Shaykin wrote:I guess it has something to do with the fact, that the components are inside different panels.
I don't see why that would have anything to do with it. And also you could test that hypothesis by putting the components into the same panel.
Joined: Jun 13, 2009
1) the component whose property has changed should fire the event:
2) you also need to add the listener to the component whose property has changed:
Once you do this you will get your event but you will notice a problem that the label doesn't move. This is because when you change the text on the label the panels are revalidated and the location of the moving label is reset to the location determined by the layout manager. A fix for this is to use:
So basically we are back to my original suggestion to just use a ComponentListener so you don't have to generate your own property change event. The ComponentListener needs to be added to the component that moves and the listener updates the label with the text.
Thank you all for your answers! First of all, it seems weird to me that the component whose property has changed, should register for the propertyChanged event. I thought that this component should just fire the event, and all the interested parties should catch it and handle in their way. It looks even more weird that the container layout prevents component movement just because we update label in another panel. So the only way to make it work with PropertyChangeListener is to set null layout?
Rob Camick wrote:So basically we are back to my original suggestion to just use a ComponentListener so you don't have to generate your own property change event.
I tried your suggestion with the same results - label ceases to move
Darryl Burke wrote:Did you think the "location" property of destLbl would change when you move testLbl?
No, I think that the destLbl is the one who needs to handle the location changes of testLbl.
Darryl Burke wrote:No response for nearly 5 hours
Sorry, that's because of the time zone difference.
Joined: Jun 13, 2009
Darryl Burke wrote:
edit No response for nearly 5 hours and Rob gets in ahead of me
I have a sixth sense
Joined: Jun 13, 2009
So the only way to make it work with PropertyChangeListener is to set null layout?
This has nothing to do with the propery change listener. This is how layout managers work.
When you update the text of the label, the label is revalidated. This can cause the all the panels to be revalidated and therefore the layout manager overrides the location you set on the component with a location determined by the rules of the layout manager.
This will happen if you use a ComponentListener or any other listener.
If you want to randomly set the location of components on a panels because you are dragging the component or whatever, then yes you need to set the location (and the size) of the component manually and you need to use a null layout manager.
Rob Camick wrote:If you want to randomly set the location of components on a panels because you are dragging the component or whatever, then yes you need to set the location (and the size) of the component manually and you need to use a null layout manager.
Thanks a lot! That really gave me great understanding of what's going on here!
After thinking more thoroughly, I realized that 2 things still remain unclear to me:
1) Why changing text of one label causes revalidation of all the panels, while moving a single component doesn't revalidate anything? If that's a normal behavior, is there any way to prevent the validation of the whole contentPane?
2) Concerning property change listener... Is there any way to fire the event, sort of, globally, so that other components can receive it? I just don't get the concept - why the component that triggered the event (moving label) should handle that event (that is to add property change listener)? The moving label might not even be aware of a label that needs to be updated.