Resizing label to fit content - java

I am creating a widget, which will display a text followed by a progress bar. For this I create a Composite
container = new Composite(parent, SWT.BORDER);
container.setLayoutData(layoutData);
container.setLayout(new GridLayout(1, true));
To this I add a Label
messageText = new Label(container, SWT.WRAP | SWT.BORDER | SWT.CENTER);
messageText.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
followed by a composite holding the progress bar:
final Composite progressContainer = new Composite(container, SWT.BORDER);
progressContainer
.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
This is the result:
What I would expect is the label to grow as to be able to contain the full text. I have been trying to follow the instructions from this post however, I must be missing something as I am not able to achieve the desired behavior.
Thanks for the input.

The GridData you have specified uses all the available horizontal space but the vertical space only uses the initial size calculated for the control.
To use all available vertical space use:
messageText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Note that you are also specifying that the progressContainer should also grab all available space - this is probably not what you want so you may need to change that as well. Possibly:
progressContainer.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
If you want the message text to resize when you change the text you need to call
container.layout(true);
after setting the new text to force the sizes to be recalculated. Use your original GridData values.

Related

Keeping SWT Text box size after setting text

When I use setText() on one or both Text fields, it resizes the field to the length of the text. How do I prevent that from happening?
inner = new Composite(middle, SWT.NONE);
inner.setLayout(new GridLayout(5, false));
chkbxBtn = new Button(inner, SWT.CHECK);
chkbxBtn.setText("Check box button: ");
chkbxBtn.setSelection(false);
new Label(inner, SWT.NONE).setText("Text field 1: ");
startCol = new Text(inner, SWT.BORDER | SWT.NONE);
new Label(inner, SWT.NONE).setText("Text field 2: ");
endCol = new Text(inner, SWT.BORDER | SWT.NONE);
To clarify, SWT does not re-layout after changing the text (or any other property) of a Text control (or controls in general). It is your code or a resize event that causes the re-layout.
If you want a control to have a pre-set size, and its parent uses a GridLayout, you can set GridData with a widthHint like this:
GridData gridData = new GridData();
gridData.widthHint = ...
text.setLayoutData( gridData );
However, it is usually a bad idea trying to control the size of widgets. Thus make sure that your layout strategy aligns with best practices of UI design.
There are situations when changes to the text trigger a component re-layout. For example, show an error message as a text validation result (I found it in SWT forms).
Setting the width hint in the GridData for the text component fixes this. Width hint can be set to 0 or the minimum required size.
GridDataFactory.swtDefaults()//
.grab(true, false)//
.hint(0, SWT.DEFAULT)// width hint prevents text from expanding to full line
.align(SWT.FILL, SWT.CENTER)//
.applyTo(text);

What does the moveBelow method of Control class do?

I am using a Gridlayout with 2 column. I have Labels and corresponding Text control with it. I wanted the Text control of first label to slip down the label instead of right next to it (since its a gridlayout). For this I thought the moveBelow method would work but doesn't seem to be. Am i interpreting the use of the method wrongly?
Label label = Components.createLabel(myContainer, SWT.LEFT
| SWT.WRAP);
abel.setText("WC Plan Name");
textName = createTextControl(myContainer, SWT.LEFT);
textName.moveBelow(label);
private Text createTextControl(Composite parent, int horizontalAlignment)
{
final Text textControl = Components.createText(parent, SWT.SINGLE | SWT.BORDER);
final GridData layoutData = new GridData(horizontalAlignment, SWT.FILL, false, false);
layoutData.widthHint = 200;
textControl.setLayoutData(layoutData);
return textControl;
}
moveBelow() does exactly what it says in the documentation:
Moves the receiver below the specified control in the drawing order. If the argument is null, then the receiver is moved to the bottom of the drawing order. The control at the bottom of the drawing order will be covered by all other controls which occupy intersecting areas.
This means that it can be used to reorder children (if the layout of the parent allows it). For example, if you have a RowLayout and call moveBelow(null) on the last child, it will be moved to the top.
Now to solve your problem: You have a GridLayout with 2 columns. A GridLayout is filled from top left to bottom right. If you want two elements to appear below each other rather than next to each other, there are two options:
Add an empty Label in between, so that it can occupy the space to the right of your first element
Add a GridData to your first element and set GridData#horizontalSpan to 2. This way it will span two columns.
UPDATE
Here is an example of solution 2:
public static void main(String[] args)
{
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setText("StackOverflow");
shell.setLayout(new GridLayout(4, false));
Text text = new Text(shell, SWT.BORDER);
text.setLayoutData(new GridData(SWT.BEGINNING, SWT.TOP, false, true, 4, 1));
text = new Text(shell, SWT.BORDER);
text.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true, 4, 1));
for (int i = 0; i < 8; i++)
{
new Button(shell, SWT.PUSH).setText("Button " + i);
}
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
{
display.sleep();
}
}
display.dispose();
}
Looks like this:

SWT TreeViewer resize issue

I have 3 treeviewer objects in one view in a column like disposition and I want their size to increase equally if I maximize/minimize the view/eclipse window. Here is my code:
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(1, false));
treeViewer1 = new TreeViewer(composite, SWT.BORDER);
tree1 = treeViewer1.getTree();
tree1.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
tree1.pack();
treeViewer2 = new TreeViewer(composite, SWT.BORDER);
tree2 = treeViewer2.getTree();
tree2.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
tree2.pack();
treeViewer3 = new TreeViewer(composite, SWT.BORDER);
tree3 = treeViewer3.getTree();
tree3.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
tree3.pack();
However, when the contents of a certain tree are surpass the current viewing space and I maximize/minimize the view, that tree viewing space gets bigger than the others.
Is there a way to prevent this resize behaviour due to content size?
Many thanks,
ND
If you read the documentation of GridLayout, you will find your answer:
Constructs a new instance of this class given the number of columns, and whether or not the columns should be forced to have the same width. If numColumns has a value less than 1, the layout will not set the size and position of any controls.
The solution to your problem is replacing this (since you are talking about columns):
composite.setLayout(new GridLayout(1, false));
with:
composite.setLayout(new GridLayout(3, true));

SWT Button image limit

When an image is set on a SWT Button and the image is bigger (in this case the width), the limits of the button are not honored, and the image from one button can "touch" the image from another.
Strangely, if SWT.LEFT or SWT.RIGHT is used, the problem does no occur on the respective side. Tried with SWT.CENTER, without success.
Is there any "workaround" to bypass this problem? Or is just something that any SWT user must get used to?
Composite Code:
GridLayout gridLayout = new GridLayout(1, true);
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
gridLayout.verticalSpacing = 0;
setLayout(gridLayout);
setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Button Code:
Button button=new Button(this, SWT.PUSH | SWT.WRAP);
GridData gridData=new GridData(SWT.FILL, SWT.FILL, true, false);
gridData.widthHint=size.width;
gridData.heightHint=size.height;
button.setLayoutData(gridData);
I also have a listener associated with the Composite Layout, to adjust the Number of Columns, but i assume that's irrelevant.
Using a Button for this task doesn't seem to be the best choice (because of the borders).
You might be better off using a Label to host the Image. Your code will only change very little, since you only need to replace all occurrences of Button with Label.

How to have text fields fill 100% horizontally

If I have a text field with SWT, how can I get the field to fill to 100% or some specified width.
For example, this text field will only reach for so much horizontally.
public class Tmp {
public static void main (String [] args) {
Display display = new Display ();
Shell shell = new Shell (display);
GridLayout gridLayout = new GridLayout ();
shell.setLayout (gridLayout);
Button button0 = new Button(shell, SWT.PUSH);
button0.setText ("button0");
Text text = new Text(shell, SWT.BORDER | SWT.FILL);
text.setText ("Text Field");
shell.setSize(500, 400);
//shell.pack();
shell.open();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ())
display.sleep ();
}
display.dispose ();
}
}
Make something like this:
Text text = new Text(shell, SWT.BORDER);
text.setText ("Text Field");
text.setLayoutData(new GridData(SWT.FILL, SWT.CENTER));
/: Since this is the accepted answer I remove the errors. Thx for correcting me.
Positioning of elements in a Component depends on the Layout object that you are using. In the sample provided, you are using a GridLayout. That means, that you need to provide a specific LayoutData object to indicate how you want your component displayed. In the case of GridLayout, the object is GridData.
To achieve what you want, you must create a GridData object that grabs all horizontal space and fills it:
// Fills available horizontal and vertical space, grabs horizontal space,grab
// does not grab vertical space
GridData gd = new GridData(SWT.FILL, SWT.FILL, true, false);
text.setLayoutData(gd);
Alternative ways include using a different LayoutManager, such as FormLayout. This layout uses a FormData object that also allows you to specify how the component will be placed on the screen.
You can also read this article on Layouts to understand how Layouts work.
As a side note, the constructor new GridData(int style) is marked as "not recommended" in the documentation. The explicit constructor shown in this example is preferred instead.

Categories

Resources