Java learn using SWT gridlayout and griddata - java

I understand and can use FormLayout, FormData, FormAttachment but I can't understand how GridLayout, GridData is working. I want to learn using GridLayout and GridData because it's more like a table, it has a structure and doesn't depend on other widgets.
I was working as a web developer (front-end, back-end) and I got lost in Java "Grid" structure. How am I supposed to align, move widgets within a cell (horizontal/vertical Aling, hor./vert. Indent)? Like in HTML/CSS: margin, padding, etc. Ex: move a block from left by 100px. (margin-left: 100px), but in Java?
When I was working as a web developer, I created a page (here in Java it's view), I know how to organize parents and blocks. Can I compare a Composite to a div, like a block element like in HTML/CSS ?
I need to create the following app:
Am I need to use 4 composites?

The following article should shed some light on GridLayout for you:
Understanding Layouts in SWT
To achieve something like the form you have there, you would need something like this:
shell.setLayout(new GridLayout(3, false));
Label title = new Label(shell, SWT.NONE);
title.setText("My first text editor");
GridData data = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
data.horizontalSpan = 3;
title.setLayoutData(data);
Label select = new Label(shell, SWT.NONE);
select.setText("Select a file:");
data = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
select.setLayoutData(data);
Text text = new Text(shell, SWT.BORDER);
data = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
text.setLayoutData(data);
Button button = new Button(shell, SWT.PUSH);
button.setText("Browse...");
data = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
button.setLayoutData(data);
List result = new List(shell, SWT.BORDER);
data = new GridData(SWT.FILL, SWT.FILL, true, true);
data.horizontalSpan = 3;
result.setLayoutData(data);
The GridData us used to define the behavior of the component within the layout. You can define vertical/horizontal alignment, margins and so on. horizontalSpan is used to tell the layout how many columns the widget will cover.

Related

How to set a composite to the right side of the screen

I have created 2 labels and I wish to move these labels to the right most side of the screen. I have created a new composite for the 2 labels and set the labels with the label composite. But now the label is somewhere towards the center. I have 7 other widgets already in the screen.
Following is the code I used:
Composite blockControls = this.formToolkit.createComposite(this.mainComposite, SWT.NONE);
blockControls.setLayout(GridLayoutFactory.fillDefaults().numColumns(8).create());
blockControls.setLayoutData(new GridData(GridData.FILL, GridData.FILL, true, false));
Composite labelComposite = new Composite(blockControls, SWT.NONE);
GridLayout layout = new GridLayout();
labelComposite.setLayout(layout);
GridData layoutData = new GridData(SWT.END, SWT.END, true, true);
labelComposite.setLayoutData(layoutData);
labelComposite.setBackground(GUIHelper.COLOR_WHITE);
Label mappedEleLabel = new Label(labelComposite, SWT.LEAD);
mappedEleLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
mappedEleLabel.setText("hello");
mappedEleLabel.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_YELLOW));
mappedEleLabel.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
Label unmappedEleLabel = new Label(labelComposite, SWT.LEAD);
unmappedEleLabel.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
unmappedEleLabel.setText("world");
unmappedEleLabel.setBackground(Display.getDefault().getSystemColor(SWT.COLOR_GREEN));
unmappedEleLabel.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
You can use FormData but there are many ways.
FormData objects specify how each widget in a FormLayout will be laid out.
But the solution depends on the arrangement of the other 7 widgets.
I recommend this article: Layouts in SWT
Though the article may seem deprecated , Layouts in SWT haven't changed.

What is the proper way to add custom Controls to the Eclipse toolbar (using WorkbenchWindowControlContribution)?

I'm developing a set of Eclipse plugins, one of which is responsible for adding a toolbar to the Eclipse workspace.
While adding new commands (and the corresponding buttons) can be done in plugin.xml, I also need a text box and a label, which requires the addition of a Control to the plugin.xml, plus an implementation in Java that extends org.eclipse.ui.menus.WorkbenchWindowControlContribution. In practice, this comes down to overriding createControl(Composite parent) in the subclass.
This part is clear to me. The problem is that I'm not sure what type of Control object I should return.
I have tried the following:
Create a ToolBarManager, add an SWT Label and an STW Text to it (both wrapped in separate ControlContribution objects), and return the toolbar obtained by ToolBarManager.createControl(parent):
#Override
protected Control createControl(Composite parent)
{
ToolBarManager manager = new ToolBarManager(SWT.FLAT | SWT.HORIZONTAL);
LabelContributionItem labelItem = new LabelContributionItem("myLabelId");
manager.add(labelItem);
TextContributionItem textItem = new TextContributionItem("myTextId");
manager.add(textItem);
ToolBar toolbar = manager.createControl(parent);
return toolbar;
}
However, the label is not positioned correctly:
Use a GridLayout as the control to return (code adapted from this answer):
#Override
protected Control createControl(Composite parent)
{
Composite composite = new Composite(parent, SWT.SINGLE);
GridLayout compositeLayout = new GridLayout(2, false);
compositeLayout.marginTop = -1;
compositeLayout.marginBottom = 0;
compositeLayout.marginLeft = 5;
compositeLayout.marginWidth = 0;
composite.setLayout(compositeLayout);
Label myLabel = new Label(composite, SWT.BORDER | SWT.SINGLE);
myLabel.setText("myLabel");
Text myText = new Text(composite, SWT.BORDER | SWT.SINGLE);
myText.setText("myText");
return composite;
}
The result is an incorrectly sized and aligned text box, plus a border around the label (rightmost text box added for comparison):
I also tried some other combinations and layouts, but cannot get this to work properly. Furthermore, I'd like to add a ControlDecoration to the text box, like this:
For the ControlDecoration's mouseover text to work properly, there needs to be margin space to the left of the text box (source):
Clients using ControlDecoration should typically ensure that enough margin space is reserved for a decoration
Adding this space has also proved troublesome, except when using the GridLayout's marginLeft parameter (but GridLayout gave the alignment problems described above).
I had the same problem with labels. Use CLabel if you want to add text to the toolbar.
My advice would be to first create a standalone Composite that contains the desired controls and decorations independantly of the workbench contribution.
There you can test the layout in a simple Shell until it looks like how it should.
As far as I understood your question, this is how the controls should be layed out:
Composite composite = new Composite( shell, SWT.NONE );
composite.setLayout( new GridLayout( 2, false ) );
composite.setBackground( composite.getDisplay().getSystemColor( SWT.COLOR_GREEN ) );
Label label = new Label( composite, SWT.NONE );
label.setText( "MyLabel" );
Text text = new Text( composite, SWT.BORDER );
text.setText( "my text" );
ControlDecoration decoration = new ControlDecoration( text, SWT.TOP | SWT.LEFT );
FieldDecorationRegistry registry = FieldDecorationRegistry.getDefault();
FieldDecoration fieldDecoration = registry.getFieldDecoration( DEC_CONTENT_PROPOSAL );
decoration.setImage( fieldDecoration.getImage() );
label.setLayoutData( new GridData( SWT.BEGINNING, SWT.CENTER, false, false ) );
GridData gridData = new GridData( SWT.BEGINNING, SWT.CENTER, false, false );
gridData.horizontalIndent = 10;
text.setLayoutData( gridData );
Then you can attempt to contribute the controls to the workbench. The extension should be specified as described in this post: Contributed control to the status bar not visible
createControl() should return the above mentioned composite and look like this
protected Control createControl( Composite parent ) {
Composite composite = new Composite( shell, SWT.NONE );
// ... create label, text, decoration as above
return composite;
}
You need to create a tool item of type SWT.SEPARATOR and then attach the label to that. The following code demonstrates this:
public static ToolItem createToolBarLabel(ToolBar toolBar, String text, int width) {
ToolItem labelItem = new ToolItem(toolBar, SWT.SEPARATOR);
CLabel label = new CLabel(toolBar, SWT.NONE);
label.setText(text);
labelItem.setWidth(width);
labelItem.setControl(label);
return labelItem;
}

How to align two composites in a parent composite without using widthHint and heightHint

I want two composites (one below the other) inside a parent component.
This is how my code looks like:
Composite composite = (Composite) super.createDialogArea(parent);
Composite rowComposite = new Composite(composite, SWT.NONE);
rowComposite.setLayout(new GridLayout(2, false));
GridData gd1 = new GridData(SWT.LEFT, SWT.CENTER, false, false);
gd1.widthHint = 760;
gd1.heightHint = 240;
rowComposite.setLayoutData(gd1);
Composite columnComposite = new Composite(composite, SWT.NONE);
columnComposite .setLayout(new GridLayout(2, false));
GridData gd2 = new GridData(SWT.LEFT, SWT.CENTER, false, false);
gd2.widthHint = 760;
gd2.heightHint = 240;
columnComposite .setLayoutData(gd1);
Here, I'm using widthHint and heightHint which is not recommended as the whole layout will be ruined when the user decides to change the system font or resolution.
How do i achieve the same without using widthHint and heightHint.
Removed the widthHint and heightHint from both composites and updated grid data as:
new GridData(SWT.FILL, SWT.FILL, true, true);
The GridLayout has taken care of width and height.
composite.setLayout(new GridLayout(1, true));
Set layout of parent to GridLayout, which the first parameter is the number of columns and the second is whether or not the columns will have equal width.
I suggest you to try WidowBuilder Pro
This will help you to build HMI rapidly

ScrolledComposite parent with GridLayout

I'd like to have a ScrolledComposite which has a parent with GridLayout but the scrollbar doesn't show up, unless I use FillLayout. My problem with FillLayout is that its children takes equal parts of the available space.
In my case there are two widgets, the one on top should take not more than 1/4 of the window and the ScrolledComposite should take the remainder space. However, both of them take half of it.
Is there a way to use a GridLayout with ScrolledComposite or is it possible to modify the behaviour of FillLayout?
Here's my code:
private void initContent() {
//GridLayout shellLayout = new GridLayout();
//shellLayout.numColumns = 1;
//shellLayout.verticalSpacing = 10;
//shell.setLayout(shellLayout);
shell.setLayout(new FillLayout(SWT.VERTICAL));
searchComposite = new SearchComposite(shell, SWT.NONE);
searchComposite.getSearchButton().addListener(SWT.Selection, this);
ScrolledComposite scroll = new ScrolledComposite(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
scroll.setLayout(new GridLayout(1, true));
Composite scrollContent = new Composite(scroll, SWT.NONE);
scrollContent.setLayout(new GridLayout(1, true));
for (ChangeDescription description : getChanges(false)) {
ChangesComposite cc = new ChangesComposite(scrollContent, description);
}
scroll.setMinSize(scrollContent.computeSize(SWT.DEFAULT, SWT.DEFAULT));
scroll.setContent(scrollContent);
scroll.setExpandVertical(true);
scroll.setExpandHorizontal(true);
scroll.setAlwaysShowScrollBars(true);
}
In addition to setLayout(), it is necessary to call setLayoutData(). In the following code example, take a look at how the GridData objects are constructed and passed to each of the two setLayoutData() calls.
private void initContent(Shell shell)
{
// Configure shell
shell.setLayout(new GridLayout());
// Configure standard composite
Composite standardComposite = new Composite(shell, SWT.NONE);
standardComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
// Configure scrolled composite
ScrolledComposite scrolledComposite = new ScrolledComposite(shell, SWT.V_SCROLL | SWT.H_SCROLL | SWT.BORDER);
scrolledComposite.setLayout(new GridLayout());
scrolledComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
scrolledComposite.setExpandVertical(true);
scrolledComposite.setExpandHorizontal(true);
scrolledComposite.setAlwaysShowScrollBars(true);
// Add content to scrolled composite
Composite scrolledContent = new Composite(scrolledComposite, SWT.NONE);
scrolledContent.setLayout(new GridLayout());
scrolledComposite.setContent(scrolledContent);
}
NB! This answer is based on Eclipse RAP which might behave differently then regular SWT.
I was struggling with the exact same issue a couple of days ago. I had two ScrolledComposites on the same page and i needed that the left one would not take more space then needed (even if the space would be available).
While trying out different solutions i noticed that the behavior of a ScrolledComposite depends on its LayoutData as follows:
If the layoutData is set to new GridData(SWT.LEFT, SWT.TOP, false, true), then the ScrolledComposite will keep it's intended size regardless of parent Composite size changes.
If the layoutData is set to new GridData(SWT.LEFT, SWT.TOP, true, true), then the ScrolledComposite will shrink/expand according to the size changes of the parent Composite. This also includes expanding to greater width that was desired (meaning that the columns are kept equal).
Based on this behavior i was able to solve the problem by adding a resize listener to the parent Composite that changes the layoutData of the left ScrolledComposite based on the parent Composite size.
This approach is illustrated the following example:
public class LayoutingScrolledComposites extends AbstractEntryPoint {
public void createContents( Composite parent ) {
parent.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
parent.setLayout(new GridLayout(2, false));
ScrolledComposite sc1 = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
Composite c1 = new Composite(sc1, SWT.BORDER);
sc1.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true));
c1.setLayout(new GridLayout(3, false));
sc1.setContent(c1);
Label l1 = new Label (c1, SWT.BORDER);
l1.setText("Some text");
l1 = new Label (c1, SWT.BORDER);
l1.setText("Some text");
l1 = new Label (c1, SWT.BORDER);
l1.setText("Some text");
c1.setSize(c1.computeSize(SWT.DEFAULT, SWT.DEFAULT));
ScrolledComposite sc2 = new ScrolledComposite(parent, SWT.H_SCROLL | SWT.V_SCROLL);
sc2.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true));
Composite c2 = new Composite(sc1, SWT.BORDER);
c2.setLayout(new GridLayout(3, false));
sc2.setContent(c2);
Label l2 = new Label (c2, SWT.BORDER);
l2.setText("Some text");
l2 = new Label (c2, SWT.BORDER);
l2.setText("Some text");
l2 = new Label (c2, SWT.BORDER);
l2.setText("Some text");
c2.setSize(c2.computeSize(SWT.DEFAULT, SWT.DEFAULT));
parent.addListener(SWT.Resize, new Listener() {
public void handleEvent(Event e) {
int sc1_x = sc1.getContent().getSize().x;
int sc2_x = sc2.getContent().getSize().x;
//Enable/Disable grabExcessHorizontalSpace based on whether both sc's would fit in the shell
if (LayoutingScrolledComposites.this.getShell().getSize().x > sc1_x+sc2_x) {
if (((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace) {
//sc1 does not change width in this mode
((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace=false;
}
} else {
if (!((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace) {
//sc1 changes width in this mode
((GridData)sc1.getLayoutData()).grabExcessHorizontalSpace=true;
}
}
parent.layout(); //Needed so that the layout change would take effect during the same event
}
});
}
}
However this approach does seem to me a bit too "hackish" solution. Therefore i would love to see a better approach.
I think what you're missing here is to define the GridData for the children.
A layout controls the position and size of children. And every layout class has a corresponding layout data class which allows to configure each specific children within the layout, if they fill up the whole space, how many cells they take, etc.
I guess your grid layout could have 4 rows, with the widget on top taking just one cell and the other child taking the rest (3). This is achieved through the GridData.verticalSpan property.
Take a look at Understanding Layouts in SWT and try the different layout data properties to see what they do.

Add scrollbar to JFACE Wizard

Problem
I have a Composite in my wizardPage and I want to add scrollbars to it if the Composite is bigger than the wizard window, but no method I tried so far worked. Anyone an idea how to add the scrollbars?
I want to add them to a Composite to which I add text;
compositeInfo = new Composite(container, SWT.BORDER);
What I tried
I tried creating a ScrollableComposite without succes, when I use the ScrollableComponent, the text doesnt get added to the Composite.
compositeInfo = new ScrolledComposite(container, SWT.BORDER
| SWT.H_SCROLL | SWT.V_SCROLL);
compositeInfo.setBackground(SWTResourceManager
.getColor(SWT.COLOR_WHITE));
GridLayout gl = new GridLayout(1, false);
gl.numColumns = 1;
compositeInfo.setLayout(gl);
GridData gd_composite_2 = new GridData(SWT.CENTER, SWT.CENTER, false,
false, 2, 1);
gd_composite_2.widthHint = 450;
compositeInfo.setLayoutData(gd_composite_2);
add some text
c = compositeInfo;
Label lblGD = new Label(c, SWT.NONE);
GridData gd_lblG = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1,
1);
gd_lblG.widthHint = 450;
lblGD.setLayoutData(gd_lblG);
lblGD.setForeground(SWTResourceManager.getColor(SWT.COLOR_DARK_BLUE));
lblGD.setFont(SWTResourceManager.getFont("Tahoma", 10, SWT.BOLD));
lblGD.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
lblGD.setAlignment(SWT.LEFT);
lblGD.setText(t);
((ScrolledComposite) c).setContent(lblGD);
See JavaDoc of ScrolledComposite. You need to call either compositeInfo.setSize or compositeInfo.setMinSize.

Categories

Resources