Reputation: 1593
Is it possible to define manual ratios for columns in a grid layout which all grab excess horizontal space?
When using a Grid Layout with multiple items that have the grab excessive horizontal space option - particularly Tables, Trees, and the like - the layout automatically determines how to split the space between the multiple items based on various factors, such as how many columns each item has. This leads to the space being split unevenly between them, and this is intentional by design and usually a good thing.
If one were to want the space to be split perfectly even, there is a make columns the same size option for that, as well.
However, is it possible to define a different, non-automatic, non-equal-space percentage for columns? Would it be possible to, for instance, have the items in my examples have a 80/20 split with the larger amount going to the item with fewer columns, or which would otherwise be considered smaller through the automatic method?
Upvotes: 4
Views: 2464
Reputation: 18813
Instead of listening to resize, you could also use a GridLayout with a higher number of columns that lets you distribute the space as desired by letting the contents span multiple columns.
For instance, for a 70:30 distribution, create a 10 column grid layout. Let the first child span 7 columns and the 2nd child span 3 columns.
Depending on your use case, a disadvantage of using GridLayout might be that it doesn't force the children down to the parent size if they want to be larger (a problem I frequently run into with long labels that could just wrap).
An option avoiding this problem is to implement a simple layout manager that supports percentages:
public class ColumnLayout extends Layout {
int[] percentages;
public ColumnLayout(int... percentages) {
this.percentages = percentages;
}
@Override
protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) {
Control[] children = composite.getChildren();
int height = hHint;
int width = wHint;
int consumedPercent = 0;
for (int i = 0; i < children.length; i++) {
int percent;
if (i >= percentages.length) {
percent = (100 - consumedPercent) / (children.length - percentages.length);
} else {
percent = percentages[i];
consumedPercent += percent;
}
Point childSize = children[i].computeSize(wHint == -1 ? -1 : wHint * percent / 100, hHint);
if (wHint == -1) {
width = Math.max(width, childSize.x * (100 - percent) / 100);
}
if (hHint == -1) {
height = Math.max(height, childSize.y);
}
}
return new Point(width, Math.max(height, 0));
}
@Override
protected void layout(Composite composite, boolean flushCache) {
Control[] children = composite.getChildren();
Rectangle available = composite.getClientArea();
int x = available.x;
int consumedPercent = 0;
for (int i = 0; i < children.length - 1; i++) {
int percent;
if (i >= percentages.length) {
percent = (100 - consumedPercent) / (children.length - percentages.length);
} else {
percent = percentages[i];
consumedPercent += percent;
}
int w = available.width * percent / 100;
children[i].setBounds(x, available.y, w, available.height);
x += w;
}
if (children.length > 0) {
children[children.length - 1].setBounds(x, available.y,
available.width - (x - available.x), available.height);
}
}
}
That said, I am now usually just putting Labels I want to wrap just in a extra "cage" composite that limits their horizontal size request.
Upvotes: 1
Reputation: 731
Yes, you would do this programmatically like this:
Get the size of the screen
Edit the GridView
's size based on the screen( ei. set the size to 1/2 of the screen for 50%)
Refresh the page by calling view.invalidate()
Upvotes: -1
Reputation: 36904
Very related to this answer:
Yes, it's possible, but it's not as easy as GridLayout#setWeight(col, weight)
. Unfortunately, you have to listen to Resize
events of the Shell
(or the container that holds your GridLayout
) and then setting the GridData
of the contained components. The code below will set the percentages to 75% and 25%:
public static void main(String[] args)
{
Display display = Display.getDefault();
final Shell shell = new Shell(display);
shell.setLayout(new GridLayout(2, false));
Composite left = new Composite(shell, SWT.BORDER);
Composite right = new Composite(shell, SWT.BORDER);
final GridData leftData = new GridData(SWT.FILL, SWT.FILL, true, true);
final GridData rightData = new GridData(SWT.FILL, SWT.FILL, true, true);
left.setLayoutData(leftData);
right.setLayoutData(rightData);
shell.addListener(SWT.Resize, new Listener()
{
@Override
public void handleEvent(Event arg0)
{
Point size = shell.getSize();
leftData.widthHint = (int) (size.x * 0.75);
rightData.widthHint = size.x - leftData.widthHint;
System.out.println(leftData.widthHint + " + " + rightData.widthHint + " = " + size.x);
}
});
shell.pack();
shell.open();
shell.layout();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
After starting:
After resizing:
Upvotes: 3