SWT- equal weights to GridLayout row elements? - java

I'm trying to add 7 Text widgets to a GridLayout row.
I want them all to be of the same width, but they come out funky:
//Columns
for(int i=0;i<7;i++) {
text = new Text(shell, SWT.BORDER);
text.setEditable(true);
data = new GridData(SWT.FILL, SWT.TOP,true,false,1,1);
text.setLayoutData(data);
cols.add(text);
}
Things I've tried:
Almost any combination of FILL/TOP and true/false to the GridData constructor (I was desperate).
Setting data.minimumWidth and data.widthHint to (window width)/7.
Yet the widgets are always in varying degrees of disarray.

You specify this on the GridLayout constructor, second parameter:
GridLayout layout = new GridLayout(7, true);
specifies 7 columns of equal width.
You can also use
layout.makeColumnsEqualWidth = true;

Related

Java SWT: setSize() not working on Button control

I have an ArrayList of buttons, and I'm trying to set all the buttons the same size of the last button.
This is my code:
ArrayList <Button> buttons = new ArrayList<Button>();
Composite numbersComposite = new Composite(composite, SWT.NONE);
numbersComposite.setLayout(new GridLayout(5, true));
for (int i=0; i<=49; i++) {
Button b = new Button(numbersComposite, SWT.TOGGLE);
b.setText(""+i);
buttons.add(b);
}
for (Button b : buttons) {
b.setSize(buttons.get(buttons.size()-1).getSize());
}
Something is wrong because not all the buttons have the same size. Is there any problem with setSize method on Buttons with TOGGLE style?
Edit
I see that buttons.get(buttons.size()-1).getSize() is giving a Point with 0,0 value. Why?
Edit 2
I tried with this code but nothing happens! not all of them have the same size. Why is this?
Point point = new Point(20, 20);
for (Button b : buttons) {
b.setSize(point);
}
You are mixing layouts with absolute positioning, which doesn't work.
setSize will only work when you are not using layouts.
If you are using layouts (which is usually the best choice) then you should set the appropriate layout data to the components you want to display.
Since you are using GridLayout for the parent Composite, its children should set GridData as layout data; for example this GridData will make the buttons use all the available space in the parent Composite:
for (int i = 0; i <= 49; i++) {
Button b = new Button(numbersComposite, SWT.TOGGLE);
// set the layout data
GridData buttonLayoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
b.setLayoutData(buttonLayoutData);
b.setText("" + i);
buttons.add(b);
}
Look to the constructors of GridData to see which other options you have.
Look here to know more about layouts in SWT: http://www.eclipse.org/articles/article.php?file=Article-Understanding-Layouts/index.html

SWT GridLayout inside ScrolledComposite messing up the size of the components

I have a window that must show a list of buttons all below each other.
All buttons must be square of a specific size (size can change while running).
This simple example works as in it shows all the buttons.
public class Main
{
public static void main(String[] args)
{
Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
val scrollPanel = new ScrolledComposite(shell, SWT.V_SCROLL);
scrollPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
scrollPanel.setLayout(new FillLayout());
val gridPanel = new Composite(scrollPanel, SWT.NONE);
val gridLayout = new GridLayout(1, false);
gridPanel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
gridPanel.setLayout(gridLayout);
scrollPanel.setContent(gridPanel);
val blue = display.getSystemColor(SWT.COLOR_BLUE);
val red = display.getSystemColor(SWT.COLOR_RED);
scrollPanel.setBackground(blue);
gridPanel.setBackground(red);
val exitButton = new Button(gridPanel, SWT.PUSH);
exitButton.setText("Exit");
exitButton.addListener(SWT.Selection, touchEvent -> shell.dispose());
for (int i = 1; i <= 10; i++)
{
val button = new Button(gridPanel, SWT.PUSH);
button.setText("Item: " + i);
button.setSize(60, 60);
gridPanel.setSize(gridPanel.computeSize(SWT.DEFAULT, SWT.DEFAULT));
}
shell.setSize(100, 700);
shell.open();
while (!shell.isDisposed())
if (!display.readAndDispatch())
display.sleep();
display.dispose();
}
}
However, whenever I do the gridPanel.computeSize(), the buttons lose their size that is set by button.setSize().
When I remove the gridPanel.setSize() after adding a button, the size will be 0 and the gridPanel is never shown at all.
When I set the gridLayout on the scrollPanel and add the buttons to that, then only one button is shown.
(The last button if I use setContent() and the second (for whatever reason) if I do not use setContent() and just rely on the constructor of the buttons.)
At this moment, I am quite out of my options so if anyone can clear something up of this scenario, then please go ahead.
If you use a layout (which you should), you must not use setSize() or otherwise interfere with the layout.
Use widthHint and heightHint of GridData instead to control the size of the buttons.
For example:
GridData gridData = new GridData( SWT.BEGINNING, SWT.CENTER, false, false );
gridData.widthHint = 60;
gridData.heightHint = 60;
button.setLayoutData( gridData );
First of all, setSize is only going to work properly when you are not using layouts (absolute positioning).
If you are using a layout, it will automatically set the components size based on the layout itself and how you define the layout data of the components.
In general, it is highly recommended to use layouts over absolute positioning.
In case of GridLayout, you can specify a component size via widthHint and heightHint in its GridData, for example:
Button button = new Button(gridPanel, SWT.PUSH);
button.setText("Item: " + i);
GridData buttonLayoutData = new GridData();
buttonLayoutData.widthHint = 60;
buttonLayoutData.heightHint = 60;
button.setLayoutData(buttonLayoutData);
Other observations:
to make the ScrollComposite work properly you should add these lines:
scrollPanel.setExpandHorizontal(true);
scrollPanel.setExpandVertical(true);
scrollPanel.setMinSize(gridPanel.computeSize(SWT.DEFAULT, SWT.DEFAULT));
in particular, setMinSize will tell the ScrollComposite at what size it should make the scrollbar appear.
if the parent layout is a FillLayout you should not set layout data on its children. It won't do anything since it is not expected. So you should remove the setLayoutData from scrollPanel and gridPanel.
if you want to change the button size at a later moment, just get its layout data, modify the hints and ask the component to layout (also don't forget to notify the scrollbar of the change with setMinSize):
GridData buttonLayoutData = (GridData) button.getLayoutData();
buttonLayoutData.widthHint = 40;
buttonLayoutData.heightHint = 40;
button.requestLayout();
scrollPanel.setMinSize(gridPanel.computeSize(SWT.DEFAULT, SWT.DEFAULT));

SWT GridLayout automatic column count

I'm using a SWT GridLayout for displaying different images in, such a wonder - a Grid.
Now my problem is, that the GridLayout has always a fixed column count, lets say 5.
Is there any way to make the GridLayout flexible, so that the column count increase or decrease depending on the size of the parent component? (E.g. when the window is resizied).
I could not find an option in the GridLayoutConstructor or the GridData. A RowLayout does not fill my needs
You can change the layout at runtime.
When your parent component's size changes, change its GridLayout's numColumns property and call layout(true) on the parent component.
final Shell shell = new Shell();
final GridLayout layout = new GridLayout( 3, true );
shell.setLayout( layout );
shell.addControlListener( new ControlAdapter() {
#Override
public void controlResized( ControlEvent event ) {
int newColumnNumber = 5; // Calculate your new value here.
layout.numColumns = newColumnNumber;
shell.layout( true );
}
} );

how to fix the order of the buttons in SWT?

I have scroller with 2 buttons
How i can set that the order of the buttons will be in the same raw and not each control : button scroller and button will be in different row
fComposite= new Composite(composite, SWT.RIGHT_TO_LEFT);
GridData layoutData= new GridData(SWT.FILL, SWT.RIGHT_TO_LEFT, true, false);
fComposite.setLayoutData(layoutData);
layout= new GridLayout(1, false);
layout.marginHeight= 0;
layout.marginWidth= 0;
layout.horizontalSpacing= 0;
layout.verticalSpacing= 0;
fComposite.setLayout(layout);
Display display = parent.getDisplay();
Shell shell = parent.getShell();
Button button = new Button(fComposite, SWT.LEFT);
button.setText("Two"); //$NON-NLS-1$
button.setImage(display.getSystemImage(ICON_1));
final Scale scale = new Scale (fComposite, SWT.BORDER);
Rectangle clientArea = fComposite.getClientArea ();
scale.setBounds (clientArea.x, clientArea.y, 200, 64);
scale.setMaximum (5);
scale.setPageIncrement (1);
scale.setSelection(5);
Button rButton = new Button(fComposite, SWT.RIGHT);
rButton.setText("Two"); //$NON-NLS-1$
rButton.setImage(display.getSystemImage(ICON_2));
Did you read the article about SWT layouts that I posted in one of your other questions?
The Display and Shell are the first things to create. After that you can add things to the shell.
Your problem is based on the fact, that you created a GridLayout with just one column. Thus all widgets are below each other.
layout= new GridLayout(1, false);
The first parameter is the number of columns. Set it to 3 for three columns.
Please read the documentation of the layout and the article: Understanding layouts in SWT before asking further questions. It will definitely help you.

SWT Grid Layout width

I'm trying to create a simple display using SWT. So far, I am successfully displaying information from my database and displaying it using a RowLayout, with each row containing a GridLayout. It looks like this:
What I really want is for the rows to extend to take up the full width of the window. How do I achieve this?
Thanks for your help!
The usual way to achieve this is to use GridData. This GridData tells the component how to behave within it's parent, e.g. how to spread across the parent.
By using:
component.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
you tell the component to occupy as much space as possible horizontally, but only the necessary space vertically.
Here is a small example that should behave in the way you expect it to:
public class StackOverflow
{
public static void main(String[] args)
{
Display display = Display.getDefault();
Shell shell = new Shell(display);
/* GridLayout for the Shell to make things easier */
shell.setLayout(new GridLayout(1, false));
for(int i = 0; i < 5; i++)
{
createRow(shell, i);
}
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
private static void createRow(Shell shell, int i)
{
/* GridLayout for the rows, two columns, equal column width */
Composite row = new Composite(shell, SWT.NONE);
row.setLayout(new GridLayout(2, true));
/* Make each row expand horizontally but not vertically */
row.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
/* Create the content of the row, expand horizontally as well */
Button first = new Button(row, SWT.PUSH);
first.setText("FIRST " + i);
first.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
Button second = new Button(row, SWT.PUSH);
second.setText("SECOND " + i);
second.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
}
}
This is what it looks like after startup:
and after resizing:
As a side note: I would suggest reading this tutorial from Eclipse about Layouts, if you haven't already read it. Every SWT developer should have read it.

Categories