Skip to main content

Bug in MultiSplitLayout

6 replies [Last post]
sbozian
Offline
Joined: 2010-08-30
Points: 0

Hello,

I think there's a bug in MultiSplitLayout once it starts doing layoutContainer with floatingDividers FALSE, i.e. typically after the MultiSplitPane user has dragged a DIVIDER.

To illustrate the bug, consider a ROW layout with two LEAF nodes separated by a DIVIDER. The nodes have weights of 0.3 and 0.7 respectively.
Let us assume the total available WIDTH for the LEAF nodes is 100px, that’s why we get: 30px and 70px.
Now, if I maximize the frame such that the total available WIDTH for the LEAF nodes becomes 1000px, we get: 300px and 700px.
So far, there was no problem because given that no DIVIDER was dragged yet, layoutContainer will call doLayoutByWeight, and layout2 will properly allocate the extra space.

Now let us assume I minimize my frame back to the 100px above, and I drag the DIVIDER such that to get a 50-50 layout.
Now, if I maximize the frame such that the total available WIDTH for the LEAF nodes becomes 1000px, I won’t get: 500px and 500px.
Basically, because:
1. floatingDividers is set to FALSE and hence we will no longer doLayoutByWeight
2. when layout2 calls layoutGrow, it will attempt to allocate the extra space as follows: newWidth = currentWidth + (extraWidth * splitChild.getWeight())

The problem is in the call getWeight() since it will return a non-updated weight (either 0.3 or 0.7 in this case), instead of the updated 0.5.
When I update the layout to 50-50 and I maximize, I expect the currently showing weights to be preserved, not the ones the layout had initially started with!

I propose the following solution to this:
Every time a divider is dragged, weights must be recalculated, and floatingDividers must be set back to TRUE to resume layoutByWeight.

I copied the code of MultiSplitLayout and added a method called updateWeigths() (along with another helper method). I call this method from within the finishDrag method of JXMultiSplitPane.

Please check the attached source code.
I’m waiting for your feedback, specially from the authors of those classes Hans Muller and Luan O’Carroll.

Thanks in advance,
Shant

AttachmentSize
addedMethods.txt2.8 KB

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
kschaefe
Offline
Joined: 2006-06-08
Points: 0

Let's file a bug for this please.

Karl

sbozian
Offline
Joined: 2010-08-30
Points: 0

I inserted SWINGX-1490: http://java.net/jira/browse/SWINGX-1490

Thanks
Shant

martinm1000
Offline
Joined: 2003-06-12
Points: 0

Hi, I'm not 100% sure of the problem you are describing... But I do know that Multisplit can have bizarre results depending on the way you initialize it.

Here is code that I use and that work really well. Can you modify it and reproduce the problem ?

Code :
http://pastebin.com/kZwSvNGY

Edited:

Is it the problem that happen if I divide the UI 50%/50% and then after maximizing I'm not 50%/50% ?
I can't believe I didn't saw that one !

sbozian
Offline
Joined: 2010-08-30
Points: 0

Hi again,

I just ran your test, and yes, it does reproduce the problem of invalid weights!

You can also try the following scenario which also clearly reproduces the problem:
- set the initial weights as follows: LEFT 0 / RIGHT 1.0
- run and drag the divider, e.g. to achieve 50/50
- now maximize

As opposed to the expected 50/50 layout, you'll see that the width of the LEFT node won't change, because as I already explained, extra space is allocated as follows:

newWidth = currentWidth + (extraWidth * splitChild.getWeight())

And since the LEFT node has an initial weight of 0, it will get nothing of the extra space, and its newWidth = currentWidth.

martinm1000
Offline
Joined: 2003-06-12
Points: 0

Well if your code can correct that problem, I'll vote for it. Its just sad that we
cannot modify MultiSplit in runtime because of private finals in the code...

sbozian
Offline
Joined: 2010-08-30
Points: 0

Hey,

Thank you for your reply. I didn't run your test yet, but yeah, that's exactlybthe problem I was talking about.

The bug can be summarized as follows: after a divider is dragged, the weighrs of the layout are not updated, which means that once a divider is dragged, the weight values are no longer valid, and methods such as layoutGrow would be using invalid values to compute the layout.