How to have text fields fill 100% horizontally - java

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.

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);

SWT: How to get a Composite to automatically fill it's container

In the following code I use SWT and also draw2d. When I run the program however nothing shows up. After some debugging I've found it to be because the container's size are all 0. I have to manually enter a size like
canvasData.heightHint = 500;
canvasData.widthHint = 500;
This is fine and dandy but I need these containers to fit themselves into the space given to them by form. Is there any way to accomplish this? Any advice would be helpful.
/* (non-Javadoc)
* #see org.eclipse.ui.forms.editor.FormPage#createFormContent(org.eclipse.ui.forms.IManagedForm)
*/
#Override
protected void createFormContent( IManagedForm managedForm )
{
super.createFormContent(managedForm);
ScrolledForm form = managedForm.getForm();
Composite tabParent = managedForm.getToolkit().createComposite(form.getBody());
GridData tabParentData = new GridData(SWT.FILL,SWT.FILL,true,true);
tabParent.setLayoutData(tabParentData);
tabParent.setLayout(new GridLayout());
FigureCanvas canvas = new FigureCanvas(tabParent);
GridData canvasData = new GridData(SWT.FILL,SWT.FILL,true,true);
canvas.setLayoutData(canvasData);
//diagramContents is an IFigure from draw2d. it holds other IFigures, Labels, ect.
//Essentially everything being displayed
canvas.setContents(diagramContents);
//This method is what creates everything being displayed (the stuff in diagramContents)
refreshDisplayFromModel();
canvas.pack();
tabParent.pack();
}
Throw out GridLayout and GridData and try to set a FillLayout onto tabParent like this:
form.getBody().setLayout(new FillLayout()); //*
Composite tabParent = managedForm.getToolkit().createComposite(form.getBody());
tabParent.setLayout(new FillLayout());
FigureCanvas canvas = new FigureCanvas(tabParent);
//no layouting
canvas.setContents(diagramContents);
FillLayout doesn't need a constraints object and just makes its child grab everything. If you have more than one child, I propose you take a look at RowLayout for simple stuff and FormLayout for complex stuff, and just forget about GridLayout.
You can get rid of the pack() calls aswell.
*: Since you gave tabParent a GridData object aswell, I figured your form has a GridLayout. Got rid of that for you, too.
Use
canvas.getViewPort().setContentsTracksWidth( true );
canvas.getViewPort().setContentsTracksHeight( true );

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:

how to split the screen to 3 parts in SWT?

I am new in SWT and java
I really need an help here.
I need to build Eclipse plug-in that should open a dialog when you press on button.
The dialog should look like
label 1 textBox1 label 2 textBox 2
label 3 textBox13 label 4 textBox 4
could be alot of them -> should be with scroller
---------------------------------------------------
output ( should be textbox)
-----------------------------------------------------
messages ( should be textbox)
It could be alot of labels and textbox, How I can add them to control that could hold alot of them ? ( it should be with scroller )
How I can split the screen to 3 parts in SWT or fjace ? and how I can control on the size for example that the first part ( label textbox) will be 60% and the output will be 30% and the messages 10% ?
Maybe you could help me with an example for this ?
This is asking for far too much code - you are supposed to show us what you have tried!
Some hints:
Use org.eclipse.jface.dialog.Dialog for the dialog, you could also use org.eclipse.jface.dialog.TitleAreaDialog which has an area for error messages.
To split an area by percentages use org.eclipse.swt.custom.SashForm.
To get multiple items on a line use org.eclipse.swt.layout.GridLayout specifying the number of columns.
To get a scrolled area use org.eclipse.swt.custom.ScrolledComposite
So something like:
#Override
protected Control createDialogArea(final Composite parent)
{
Composite body = (Composite)super.createDialogArea(parent);
// Vertical sash
SashForm sashForm = new SashForm(body, SWT.VERTICAL);
sashForm.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
// First part, scrollable
ScrolledComposite scrolledComp = new ScrolledComposite(sashForm, SWT.V_SCROLL);
Composite comp1 = new Composite(scrolledComp, SWT.NONE);
comp1.setLayout(new GridLayout());
// TODO: add controls to comp1
// Set scroll size - may need to adjust this
Point size = comp1.computeSize(SWT.DEFAULT, SWT.DEFAULT);
scrolledComp.setMinHeight(size.y);
scrolledComp.setMinWidth(size.x);
scrolledComp.setExpandVertical(true);
scrolledComp.setExpandHorizontal(true);
scrolledComp.setContent(comp1);
// Second part
Composite comp2 = new Composite(sashForm, SWT.NONE);
comp2.setLayout(new GridLayout());
// TODO: add controls to comp2
// Third part
Composite comp3 = new Composite(sashForm, SWT.NONE);
comp3.setLayout(new GridLayout());
// TODO: add controls to comp3
// Set the sash weighting (must be after controls are created)
sashForm.setWeights(new int [] {60, 30, 10});
return body;
}

SWT - Creating a grid of numbers that I'd like to be able to tab through with keyboard

This problem has been driving me CRAZY!!! Using SWT, I'd like to create a grid of numbers that I can tab traverse using the keyboard. I'd like to be able to select and click into each cell (not just on the numbers) to perform some action. In other words, I'm looking for a way to make a true FLAT button. The goal here is to make the grid accessible with screen readers such that when a cell has focus, the screen reader will read the number value in the middle of each cell.
Originally, I created a GridLayout with a set of button controls to display the number values. This actually worked but I didn't want the buttons to look like buttons. The SWT.FLAT style for button controls doesn't work on Windows operating systems. This is caused by an OS limitation.
Next I then tried converting all buttons to labels but since label controls cant take focus, I couldn't implement any type of tab traversal. Next I tried replacing all labels with read-only text controls. I was able to re-introduce the tab traversal/focusing but I can't get the text to display in the dead-center of each cell. This is actually caused by a SWT limitation. The SWT.CENTER style for text controls only affects the horizontal alignment. Text controls can't be vertically aligned.
So finally, someone told me to wrap each read-only text control in a Composite. This allowed me to center the read-only text controls but I don't know how to make the composite itself to be tab traversed.
Any ideas on how I can get this done or how I can make controls that typically dont take focus (like composite, canvas, label) actually take focus so I can tab traverse each control with my keyboard?
I'm fairly new to java and SWT so I apologize if some of this is confusing. Many thanks. This is how I've constructed each of my cells thus far (I've replaced the read-only text with CLabel controls):
Display display = new Display();
Shell shell = new Shell(display);
GridLayout gridLayout = new GridLayout(5, false);
gridLayout.marginWidth = 0;
gridLayout.marginHeight = 0;
gridLayout.horizontalSpacing = 1;
gridLayout.verticalSpacing = 1;
shell.setLayout(gridLayout);
Composite resetComp = new Composite(shell, SWT.BORDER);
GridData compgridData = new GridData(SWT.CENTER, SWT.CENTER, true, true);
GridData resetGD = new GridData(SWT.FILL, SWT.FILL, false, false);
resetGD.verticalSpan = 2;
resetComp.setLayoutData(resetGD);
resetComp.setLayout(new GridLayout(1, false));
CLabel resetCLabel = new CLabel(resetComp, SWT.SHADOW_OUT | SWT.CENTER);
resetCLabel.setText("Reset"); //$NON-NLS-1$
resetCLabel.setLayoutData(compgridData);
resetCLabel.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_RED)); //$NON-NLS-1$
resetComp.setToolTipText(resetCLabel.getText());
Here is a trick, maybe it will suits you: create each button inside a Composite, and set the size of the Button bigger than its parent Composite; This way, the border of button is not visible, because outside of its parent composite.
private static final int GRID_SIZE = 5;
private static final int CELL_SIZE = 40;
private static final int PADDING = 3;
public static void main (String [] args) {
Display display = new Display ();
Shell shell = new Shell (display);
shell.setLayout(new GridLayout(GRID_SIZE, true));
for (int i = 0; i < GRID_SIZE * GRID_SIZE; i++) {
createButton(shell, i+1);
}
shell.pack ();
shell.open ();
while (!shell.isDisposed ()) {
if (!display.readAndDispatch ()) display.sleep ();
}
display.dispose ();
}
private static void createButton(Shell shell, final int number) {
Composite c = new Composite(shell, SWT.NONE);
c.setLayoutData(new GridData(CELL_SIZE, CELL_SIZE));
Button button = new Button(c, SWT.NONE);
button.setText(Integer.toString(number));
button.setBounds(-PADDING, -PADDING, CELL_SIZE + 2 * PADDING, CELL_SIZE + 2 * PADDING);
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
System.err.println("click on " + number);
}
});
}
It fulfills your requirement: focus, centered. The result may be more or less nice depending on the Windows version (try to change the padding, or add a border to the Composite, it may look nicer).

Categories

Resources