Resize Request Possible Issue

Hi Beni!
I have recreated what seems to be a problem with how consecutive resize requests are processed. I wrote a sample code that demonstrates what I mean: two threads submit resize requests one by one and you can see the issue on the second request. All you need to do is run the sample code. I have posted it here: http://javaforge.com/issue/10562

I’d be happy to try to fix it myself, but first want to make sure I’m using the APIs correctly so I don’t try to fix something that is not broken. :slight_smile:

Please let me know what you think.

Thanks,
Eduardo Born

I actually have reproduced different behaviors by inverting the resize calls, making in different ways. For example: submit both then request the control to process resize requests, submit and request it to be processed one by one, etc. They result in different layouts. I believe they should all result in the same layout since the request was the same, just expressed in a slight different way.

I think this is a bug, and looking deeper into the code that executes the layout I think it would be a very hard one to fix. Not sure I can do it since I don’t know the internals of the framework, but I’m trying to understand what is happening.

PS: while debugging I got the correct behavior once: both left dockables 100 pixels of width and bottom one with 100 pixels of height, and the centered area dockable using the remaining space. This should be the result all the time with the example above, I believe.

Since I got different results simply by being within the debugger this could be a timing issue, not sure.

  1. Boy… this is a graphical user interface library based on Swing: multi threading = very very bad idea. Every access to the framework must be made through the EDT (EventDispatcherThread).

  2. That is the intended behavior: once a resize request has been handled it is forgotten forever. But you can advice the framework to process multiple requests at the same time:

  • call “setResizeRequest” with the second argument set to “false”.
  • once all requests are set, call CControl.handleResizeRequest. Assuming there is enough space for all the requests, each CDockable gets its preferred size.

[edit: see also Guide to Common, chapter “7.3.2 Request a size” (page 24)]

Hi!
Yeah I realized my threading issue after I posted. Actually that is just in the example, and the threads run one after another with 3 seconds of sleep in between so this is not a concurrency issue. This also happens in the real code (where I saw the problem) which runs in the EDT and where I process requests the way you have indicated: sending the all and them requesting it to be processed at once.

I build the example in a different way so you can see the effect of each request one at a time, but the result when you request all of them not to be processed and then request them to be processed at once is the same.

Is this a bug? Or I’m using the API in an incorrect way? Now That I have looked deeper into the code trying to see where the issue could be I see that the method setDivider from the SplitNode class gets called many times during the layout process and it starts getting called with what seems correct, but later a new value is passed to it (0.554…) instead of the one where it should be (much smaller since it should have 100 pixels of width).

Please give the example a try and let me know, you can also change it to process them all at once and see that the result is the same as the one where I process them one by one.

Actually in the example I posted in the bug track I also included the option as you suggested, but left commented so you can see the requests step by step. If you commend the thread calls and uncomment the resize requests as follows it results in the same layout.

		// adding and processing resize requests
		leftColumnDockable.setResizeRequest(new Dimension(200, 200), false);
		bottomLineDockable.setResizeRequest(new Dimension(200, 200), false);
		dockControl.handleResizeRequests();
		
		
		// INVERT THESE TWO BLOCKS TO GET THE PROBLEM IN A DIFFERENT WAY
/*
		int interval = 3000;
		{
			new Thread(new ResizeThread(interval, leftColumnDockable, 100, 100)).start();
			interval = interval + 3000;
		}
		{
			new Thread(new ResizeThread(interval, bottomLineDockable, 100, 100)).start();
			interval = interval + 3000;
		}
*/

Please let me know what you think.

Thanks,
Eduardo

Hi Beni!
I tried one more way, I think now the correct way according to the Commons Guide:

leftColumnDockable.setResizeRequest(new RequestDimension(200, true), false);
bottomLineDockable.setResizeRequest(new RequestDimension(200, false), false);
dockControl.handleResizeRequests();

This way I get a different result. Instead of getting the left panel on the right size, with width 200 pixels, but the bottom one always gets the minimum size possible regardless of the value I post in the ResizeDimension object that I submit.

You can see this by replacing the thread calls I did in the example posted in the bug track by the calls above.

I also tried calling them one by one (since one sets the width and the other the height they should not undo each others work) and having them processed one by one:

leftColumnDockable.setResizeRequest(new RequestDimension(200, true), true);
bottomLineDockable.setResizeRequest(new RequestDimension(200, false), true);

But that results in the same layout: the bottom panel gets a minimum height instead of the one I requested.

Processing them slowly (sleeping in between) shows that the first request works fine, and the second doesn’t.

I’m I doing something wrong?

Thanks man,
Eduardo Born

I have to admit, it is not as simple as I thought. I have to check what is happening, I’ll write again in the evening (that is in a few hours).

Uffff, it is such a cheap bug. I really have to apologise for all the trouble you’ve gone through.

The bug is: the constructor “RequestDimension( int, boolean )” is faulty, it does not set the height property. Seems I never used this constructor in my tests… Use “setHeight” for a workaround:

		leftColumnDockable.setResizeRequest(new RequestDimension(400, true), false);
		
		RequestDimension d = new RequestDimension();
		d.setHeight( 200 ); // workaround
		
		bottomLineDockable.setResizeRequest( d, false);
		dockControl.handleResizeRequests();		
	}```

On the bright side: repairing the bug is really easy.

(I'm now going to do severe penance...)

Man thank you so much!
I wish I could contribute more to the project. I tried to investigate more when I saw the first side effect of my wrong API calls and it rapidly became very complex (I was messing around with the setBounds of nodes and dock stations, etc), so when I saw the second thing (with the ResizeDimension) it was already late and I didn’t try to debug it. You did an amazing job filling an existing gap in the Java swing components. I should have actually fixed this one for you.

If I see anything else I’ll make an honest effort to have it fixed before writing up and will contribute the patch.

Thanks again!
Eduardo

Thanks. But most times 4 eyes see more than 2, so don’t wait too long before reporting the next bug :wink: