Community
Participate
Working Groups
Broken from 3.0.2 to 3.1. ScrolledForm will not scroll anymore. I will attach source code for a simple EditPart which will not scroll on 3.1, but will scroll on 3.0.2.
Created attachment 24580 [details] EditPart with a ScrolledForm which will not scroll around a Large Label.
It is UI Forms.
This bug blocks me from migrating to eclipse 3.1 for my company's RCP application. I really need to migrate for some of the features we need, but these unscrolled forms are not going to work.
I can see the scrollbars flash in the UI while I resize the editor. When the resize is finished the scrollbars disappear. So, it seems like they are trying to render but are finally cancelled.
After some investigation I found a couple interesting things: 1. If you set the form's layout to TableWrapLayout the scrollbars work. Set the layout to GridLayout and the scrollbars disappear. 2. To get scrollbars to work with a GridLayout you need to tell the ScrolledForm to reflow() when it's resized like this: final Runnable reflow = new Runnable() { public void run() { form.reflow(true); } }; parent.addControlListener(new ControlAdapter() { public void controlResized(ControlEvent e) { form.getDisplay().asyncExec(reflow); } }); This causes quite a bit of flashing because the ControlListener is updated many times during a drag resize. You can alter the Runnable a bit to only call reflow() if it wasn't called in the last 100 ms to prevent some of the flashing. Obviously this is quite a piece of strategery just to get something as simple as scrollbars to work.
In my case, neither solution works: a) using TableWrapLayout results in a *tiny* scrollbar (about 4 pixels high); b) using the Runnable does nothing at all (the scroll-bar just slides up and down without causing an effect on the contained control at all)
There seems to be a bug somewhere with the cached value of preferred size being used before the label has been added to the body composite. A single call to 'form.reflow(true)' at the end of the attached editor's method 'createPartControl(Composite)' worked in case of GridLayout with no flashing. Leaving the defect in to further trace the caching bug but reducing severity since workaround has been provided.
Dejan, I assumed there is no impact of me leaving that 'form.reflow(true)' after this defect gets fixed correct?
Dejan, I assumed there is no impact of me leaving that 'form.reflow(true)' after this defect gets fixed correct? (In reply to comment #7) > There seems to be a bug somewhere with the cached value of preferred size being > used before the label has been added to the body composite. > A single call to 'form.reflow(true)' at the end of the attached editor's method > 'createPartControl(Composite)' worked in case of GridLayout with no flashing. > Leaving the defect in to further trace the caching bug but reducing severity > since workaround has been provided. Dejan, I assumed there is no impact of me leaving that 'form.reflow(true)' after this defect gets fixed correct?
(Dejan on vacation) I believe that's a safe assumption to make.
Anything on when this is going to be fixed ? I'm having issues with the following code snippet not working: As mentioned in comment #4, the scrollbars seem to flicker when the shell is resized but they do not show up. public static void main(String[] args) { Display display = new Display(); Shell parent = new Shell(display, SWT.DIALOG_TRIM | SWT.RESIZE); parent.setLayout(new FillLayout()); FormToolkit formToolkit = new FormToolkit(parent.getDisplay()); final ScrolledForm form = new ScrolledForm(parent, SWT.V_SCROLL); form.setBackground(formToolkit.getColors().getBackground()); form.setForeground(formToolkit.getColors().getColor(IFormColors.TITLE)); form.setExpandHorizontal(true); form.setExpandVertical(true); form.setFont(JFaceResources.getHeaderFont()); form.getBody().setLayout(new RowLayout()); form.setText("Hello, Eclipse Forms"); for (int i = 0; i < 200; i++) formToolkit.createHyperlink(form.getBody(), "hyperlink-" + i, SWT.NONE); parent.open(); while (!parent.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); }
Adam, here is some post-M4 fun :-).
I'm experiencing the same problem here (Eclipse Europa, Linux-GTK). Resizing causes a short and transient appearance of scrollbars, but they are usually gone except when I reduce the window to a size where even the title text would be only partially visible. The essence of my program is: ScrolledForm form; form.setText("Titledeedoo"); // remove this to fix scrollbar problem Composite body = form.getBody(); body.setLayout(new GridLayout()); // then add widgets to body. The form.reflow(true) trick fixed the scrollbar problem. Alternatively, so did removing the call to setText.
After investigating a potential caching bug as mentioned in comment 7 I have determined that no such bug exists. The SizeCache gets a reflow call on resizes and it correctly checks if the control has changed. If it has not, then it correctly assumes that its cache is still valid. The reason that this appears to be broken to so many people is that there is no way for the cache to know when children of the form's control have changed. It is up to the client to tell the form that the cache is no longer valid with a call to reflow(true). The boolean parameter indicates that something has changed and the cache is invalid. The reason that removing calls to setText seems to make everything work is actually a total fluke. ScrolledForm#setText() is calling reflow(true) at the end, as it should, to tell the form that the cache is invalid and should be recomputed. In all of the cases discussed in this bug, the call to setText is actually resulting in the first reflow the form receives and is therefore causing the cache to be populated for the first time. This means that after the body of the form is populated, there is already a cache sitting there ready to be reused. If the client does not tell the form that its children have changed and that its cache is invalid then it will gladly use the cache that it computed in the setText call. You will find that with all example in this bug, the scrollbar issue can be corrected by: a) removing the call to setText b) placing the call to setText at the end of the code that populates the form c) calling reflow(true) after populating the form (a) and (b) are both incorrect solutions as they rely on somebody else to invalidate the cache. It is up to clients to call reflow(true) any time they change the content of the form as this is the only way for the form to know that its cache is no longer valid. Thus, (c) is the correct approach here. Closing the bug as INVALID. I realize that this explanation is very complicated, so feel free to ask questions if I have not made the reasoning clear.