Java SWT: setSize() not working on Button control - java

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

Related

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- equal weights to GridLayout row elements?

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;

Displaying notification count in CodaNameone

I am facing issues in displaying notification count against an icon. It should be displayed at right top corner.
First created button with padding and margin as zero and set the image to button.
FlowLayout buttonLayout = new FlowLayout();
buttonLayout.setAlign(Component.CENTER);
buttonLayout.setValign(Component.TOP);
Container buttonContainer = new Container(buttonLayout);
buttonContainer.setUIID("IconContainer");
Button button = new Button(buttonImage);
button.setUIID("ButtonLabelNew");
buttonContainer.addComponent(button);
The created a notification count container and laid it over button
FlowLayout countLayout = new FlowLayout();
countLayout.setAlign(Component.RIGHT);
countLayout.setValign(Component.TOP);
Container countContainer = new Container(countLayout);
Label countLabel = new Label(displayCount);
countLabel.setUIID("backgroundLabel");
countContainer.addComponent(countLabel);
/*Adding Button and Notification Count to ItemContainer*/
Container itemContainer = new Container(new LayeredLayout());
itemContainer.addComponent(buttonContainer);
itemContainer.addComponent(countContainer);
Now added the text below the button
BoxLayout iconLayout = new BoxLayout(BoxLayout.Y_AXIS);
Container iconContainer = new Container(iconLayout);
Label iconText= new Label(buttonText);
iconText.setUIID("Label");
iconContainer.addComponent(0,itemContainer);
iconContainer.addComponent(1,iconText);
FInally created a grid and added icon containers to the grid
GridLayout gridLayout = new GridLayout(numRows, MAX_ITEMS_PER_ROW);
Container gridContainer = new Container(gridLayout);
gridContainer.setUIID("LogoContainer");
for (int indx = 0; indx < itemContainers.length; indx++)
{
gridContainer.addComponent(itemContainers[indx]);
}
approvalsWorklist.addComponent(BorderLayout.CENTER,gridContainer);
The image is positioned at the right hand side but the component is larger than the icon so you see the image positioned where the components are sized.
There are two ways to solve this for you.
Set a padding or margin on countContainer so the count will be spaced and placed in the right location. This has the drawback of having to tune based on a uniform icon size which might not be the case but its a relatively simple approach.
I'm assuming the components are placed in a GridLayout which means they all have the exact same size. You will wrap each element in the grid layout in a FlowLayout or a an absolute center BorderLayout they will take up their preferred size internally and then the badge will be positioned exactly within the icon edge.

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.

Categories