Community
Participate
Working Groups
It should be possible to lay the following out with a GridLayout: |----------------------------------| | Label text Label text Label text | | Label text | | ----------------------------- | | | ListBoxItem1 | | | | ListBoxItem2 | | | | | | | |___________________________| | | | | Ok Cancel | |__________________________________| However, it is not possible to the height of the label to vary as the shell resize and causes a wrap to be required. Here is a temporary workaround. However, the workaround should not be required. public static void main(String[] args) { Display display = new Display(); final Shell shell = new Shell(display); final GridLayout layout = new GridLayout(); shell.setLayout(layout); Label label = new Label(shell, SWT.WRAP); final GridData data = new GridData(); label.setLayoutData(data); shell.addControlListener(new ControlAdapter(){ public void controlResized(ControlEvent e){ data.widthHint = shell.getClientArea().width - 2*layout.marginWidth; shell.layout(true); } }); label.setText("asda sda sdasd asda sda sdada dadads asd adsad as dadsa dsad sada dsasda sd adsa sasd"); List list = new List(shell, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); list.setLayoutData(new GridData(GridData.FILL_BOTH)); for (int i = 0; i < 100; i++) { list.add("asddas "+i); } shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); }
Hi, I'm experiencing this problem as well. Currently using Eclipse 2.0.2 on Windows XP.
Use the work around for now.
I've decided to go with FormLayout instead of GridLayout. So that's my work- around. I did notice that FormLayout was a little buggy on this issue too. The text wrap works, but only if you specify aFormLayout.bottom FormAttachment. If you just leave the bottom value blank, it will not wrap either.
Just to be clear, this isn't exactly a bug. The preferred size of a label with or without wrapping as computed by computeSize(SWT.DEFAULT, SWT.DEFAULT) is always the non-wrapped size. If you think about it, this makes sense. Given infinite room, a wrapped label should never decide to wrap. When computeSize() is called with a width hint, wrapping is taken into account. The temporary work around code in this PR is doing exactly this. We may still do something about this PR because the behavior is unexpected.
*** Bug 4458 has been marked as a duplicate of this bug. ***
*** Bug 37592 has been marked as a duplicate of this bug. ***
*** Bug 45467 has been marked as a duplicate of this bug. ***
Suggestion from duplicate bug 45467: When laying out its children, GridLayout first calls computeSize(SWT.NONE, SWT.NONE) on all controls, and caches the heights. It computes the column width based on the widest control, then arranges the controls based on the cached control height. This is incorrect: once gridlayout knows the column widths, it should invoke computeSize(actualColumnWidth, SWT.NONE) on all controls to determine the actual control heights, since the height of some controls (in particular, wrapping text) may have changed.
Regarding comment 4, this bug is not suggesting that the default behavior of a Control's computeSize(...) is in error. It says that GridLayout provides no direct means for constructing layouts that contain wrapping text. If bug 45475 were fixed, it would be possible to create text that wraps after N pixels (by default) by attaching a widthHint of N to the wrapping label (without using any resize listeners). If bug 45467 were fixed, then other layout types that do not suffer from the same limitations as GridLayout would continue to work correctly when embedded in a GridLayout.
Just to add my 10c worth. I have just spent 2 days arm wrestling with this behaviour. It is not the expected result. It seems that formlayout isnt any better; since you have to specify the bottom, it is not possible to flow blocks of text down a page (like the WelcomeEditor) without using resize listeners.
BTW, I've attached a grid-like layout class that handles wrapping text nicely to bug 45833. I also have a much simpler variation in the works. GridLayout's size hints do not offer enough possibilities. There are actually three kinds of "hint"-type behaviors that are useful in gridlike layouts. 1. Override: the hint is used as the minimum column size instead of the control's computeSize(...) method. This is useful for scrollable controls (like listboxes, tree controls, and text controls) that should reserve the same amount of space regardless of their current contents. This would also work for wrapping text, although it would reserve too much space for single-line text. 2. Maximum: the hint is used as the maximum amount of space reserved for the column (the control's computeSize(...) method is used if smaller). This is useful for wrapping text, which should wrap at some point by default but should be allowed to shrink if it requires less than one line. 3. Minimum: the hint is used as the minimum amount of space reserved for the column (the control's computeSize(...) method is used if larger). This is useful for buttons, which have a standard size but are allowed to grow if they contain large labels. In all cases, it is desirable to pass in the real column size to computeSize(...) rather than the hint --- FILL-aligned controls (like wrapping text) should be allowed to expand larger than their width hint. For FILL-aligned controls, the hint should only affect the minimum column size and not the actual control size. The current behavior of GridLayout is this: 4. Use the hint directly as the argument to computeSize(...), which has the effect of computing the control's dimensions as though it had a fixed size slightly larger than the hint values (to see what I mean by "slightly larger", see bug 46112). This does not seem useful for any type of layout. From the JavaDoc on GridLayout, it seems that (1) was the intended behavior. However, to ensure compatibility I would propose the following solution: - Add a hintType field to GridData that controls how hints are interpreted. - The default hintType will select behavior 4 (above). - To create wrapping text, select hintType 2, set the text control to FILL alignment, and set the widthHint to the preferred point at which text should wrap.
Note: the workaround attached to the original report will only work if the GridLayout is attached directly to a Shell. Bug 56892 was caused by attempting to use this workaround for a GridLayout embedded within another composite. Even for Shells, this workaround should not be used if the initial size of the Shell is being computed from its controls (as described in bug 45467) -- for example, you should not use the workaround if you intend to use Shell.pack(). For whoever is working on this: the classes org.eclipse.ui.internal.layout.SizeCache and org.eclipse.ui.internal.layout.LayoutCache may be helpful here. They implement a caching strategy for computeSize that works correctly for wrapping controls (this won't solve the wrapping problem, but it help make the solution efficient).
The plan is to revisit layout issues in SWT post 3.0. There are a number of outstanding problems of which wrapping is just one.
>> Even for Shells, this workaround should not >> be used if the initial size of the Shell is >> being computed from its controls (as described >> in bug 45467) -- for example, you should not >> use the workaround if you Stefan, not sure what this means. Any control that can wrap should be given an initial size to avoid a default preferred size that is too large. The preferred size of a controls that *can* wrap is its size without wrapping.
*** Bug 45475 has been marked as a duplicate of this bug. ***
*** Bug 46112 has been marked as a duplicate of this bug. ***
Re: comment 14: In other words, the workaround does not help with calls to Shell.pack().
Fixed in 3.1 (see I20040831 or later). The following example demonstrates how to have wrapping text in GridLayout: public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); GridLayout layout = new GridLayout(); shell.setLayout(layout); Label label = new Label(shell, SWT.WRAP); final GridData data = new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1); label.setLayoutData(data); label.setText("asda sda sdasd asda sda sdada dadads asd adsad as dadsa sad sada dsasda sd adsa sasd"); List list = new List(shell, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); list.setLayoutData(new GridData(GridData.FILL_BOTH)); for (int i = 0; i < 100; i++) { list.add("asddas "+i); } shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); }
As shown in comment 19 this bug is fixed if grabExcessVerticalSpace is 'false' but as soon as I set this to 'true' the label is cut vertically. I've filed bug 194758 for that case.