Issue in displaying of SWT composite for RCP - swt

I am creating a simple SWT container in my Eclipse RCP application and was having an issue with the location/order in which it is displayed. Here is the code I am using.
#PostConstruct
public void createControls(Composite parent)
{
parent.setBackground(new Color (Display.getCurrent (), 255, 144, 0));
GridData parentData = new GridData(SWT.FILL, SWT.FILL, true, true);
parent.setLayout(new GridLayout(1, true));
parent.setLayoutData(parentData);
Device device = Display.getCurrent ();
Color backgroundColor = parent.getBackground();
Color whiteColor = new Color (device, 255, 255, 255);
Color randomColor = new Color (device, 255, 0, 0);
final Composite criteriaContainer = new Composite(parent, SWT.BORDER);
criteriaContainer.setBackground(randomColor);
final GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, false);
final GridData comboGridData = new GridData(SWT.FILL, SWT.TOP, true, false,1,1);
criteriaContainer.setLayout(new GridLayout(1, false));
criteriaContainer.setLayoutData(gridData);
final Label primaryComboLabel = new Label(criteriaContainer, SWT.NONE);
primaryComboLabel.setLayoutData(comboGridData);
primaryComboLabel.setForeground(whiteColor);
primaryComboLabel.setText("View by:");
criteriaContainer.layout();
criteriaContainer.pack();
parent.layout();
parent.pack();
}
I cant seem to get the label to appear at the top of the application(appears at the bottom center)[enter image description here][1]. If I write the same code and execute it as a standalone SWT application, the label appears at the top left. [1]: http://i.stack.imgur.com/OL312.png
Here is the difference when I have a standalone swt app.
public void showHistoryContainer() throws Exception {
Display display = new Display();
final Shell shell = new Shell(display);
shell.setBackground(new Color (Display.getCurrent (), 255, 144, 0));
the rest of the code is the same. [2]: http://i.stack.imgur.com/fJmR6.png
Any ideas why this may be happening ?
Note: In my RCP application, I am not doing any other processing on my parent composite.

You don't say what the createControls is a part of. Is it an MPart?
I can't really reproduce this problem but there are a number of issues in your code which might be causing it.
Never change the Layout of a Composite passed to your code (parent here). Create another Composite as a child and set the layout on that.
Don't call layout and pack.
So simplifying your code I have:
#PostConstruct
public void postConstruct(Composite parent)
{
Display device = parent.getDisplay();
Composite body = new Composite(parent, SWT.NONE);
body.setBackground(new Color(device, 255, 144, 0));
body.setLayout(new GridLayout());
Color whiteColor = new Color(device, 255, 255, 255);
Color randomColor = new Color(device, 255, 0, 0);
Composite criteriaContainer = new Composite(body, SWT.BORDER);
criteriaContainer.setBackground(randomColor);
criteriaContainer.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
criteriaContainer.setLayout(new GridLayout());
Label primaryComboLabel = new Label(criteriaContainer, SWT.NONE);
primaryComboLabel.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
primaryComboLabel.setForeground(whiteColor);
primaryComboLabel.setText("View by:");
}
Finally if you create Color objects like this you must arrange to dispose of them or you will leak resources. If this is an e4 RCP you should use the CSS support instead.

Related

How to create a text box when click on button in swt?

I have created 2 composite in swt. 1 button created inside 1st composite. I want to create one text box when I will click on the button. But I am unable to do that functionality.
Assuming you are using layouts for your code you just need to create the Text control and then redo the layout.
For example, using GridLayout:
shell.setLayout(new GridLayout());
final Composite buttonComposite = new Composite(shell, SWT.NONE);
buttonComposite.setLayout(new GridLayout());
final Button button = new Button(buttonComposite, SWT.PUSH);
button.setText("Create Text");
final Composite textComposite = new Composite(shell, SWT.NONE);
textComposite.setLayout(new GridLayout());
button.addSelectionListener(new SelectionAdapter()
{
#Override
public void widgetSelected(final SelectionEvent e)
{
final Text newText = new Text(textComposite, SWT.SINGLE | SWT.BORDER);
newText.setText("New text control");
newText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
// Update the layout
shell.layout(true);
}
});
Alternatively you can create the Text control at the beginning but make it not visible and exclude it from the layout:
shell.setLayout(new GridLayout());
final Composite buttonComposite = new Composite(shell, SWT.NONE);
buttonComposite.setLayout(new GridLayout());
final Button button = new Button(buttonComposite, SWT.PUSH);
button.setText("Create Text");
final Composite textComposite = new Composite(shell, SWT.NONE);
textComposite.setLayout(new GridLayout());
final Text newText = new Text(textComposite, SWT.SINGLE | SWT.BORDER);
newText.setText("New text control");
// Not visible
newText.setVisible(false);
// Exclude from layout
final GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false);
data.exclude = true;
newText.setLayoutData(data);
button.addSelectionListener(new SelectionAdapter()
{
#Override
public void widgetSelected(final SelectionEvent e)
{
// Include in layout
final GridData data = (GridData)newText.getLayoutData();
data.exclude = false;
// Make visible
newText.setVisible(true);
// Redo layout
shell.layout(true);
}
});

Composite with label aligned left and buttons right

I work on an Eclipse plug-in and at a moment in time a pop-up is shown. Inside the pop-up dialog box, I want to create an area where I have a label on the left and two buttons alligned right.
public void createBottom(Composite parent) {
Composite composite = new Composite(parent, SWT.FILL | SWT.WRAP | SWT.BORDER);
GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, false);
composite.setLayoutData(gridData);
composite.setLayout(new GridLayout(3, false));
addLabel(composite);
addButton1(composite);
addButton2(composite);
}
Currently the result looks like this:
While I'm expecting something more like this:
How can I possibly align the Label on the left and the two buttons on the right?
First SWT.FILL and SWT.WRAP are not valid styles for Composite. The Javadoc for the control specifies which styles you can use.
Use something like:
Composite composite = new Composite(parent, SWT.BORDER);
GridData gridData = new GridData(GridData.FILL, GridData.FILL, true, false);
composite.setLayoutData(gridData);
composite.setLayout(new GridLayout(3, false));
Label label = new Label(composite, SWT.BEGINNING);
label.setText("Test");
label.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
Button but1 = new Button(composite, SWT.PUSH);
but1.setText("OK");
but1.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false));
Button but2 = new Button(composite, SWT.PUSH);
but2.setText("Close");
but2.setLayoutData(new GridData(SWT.END, SWT.CENTER, false, false));
The layout data for the label grabs the extra space in the composite, and the buttons have end alignment.

Eclipse e4: creating a 3 part window trim without resizing text in tool control

I created a Window Trim - Top
now I add 3 Tool Control
first only should contain a SWT-Text and not resize ever...
however, when I type some text and resize my window, it automatically resizes the SWT-Text to fit the text, which it should not.
So how can I give that Tool Control, or the Composite, or the Text the right Size and tell it, NOT to resize!?
public class TrimBarSearch {
#Inject
ISearchService searchService;
private Text txtSearch;
private Composite composite;
#Inject
public TrimBarSearch() {
}
#PostConstruct
public void createGui(final Composite parent) {
parent.setLayoutData(new GridLayout(3, false));
composite = new Composite(parent, SWT.NONE);
Point xy = new Point(300, 15);
Point sizeComposite = new Point(310, 25);
composite.setLayout(new GridLayout(1, false));
composite.setSize(sizeComposite);
txtSearch = new Text(composite, SWT.FILL);
txtSearch.setSize(xy);
txtSearch.setText("");
// TODO fix resizing-problem
parent.getShell().addListener(SWT.Resize, e -> {
//maybe here?!
});}
Never try and mix Layouts with setSize - it does not work, the layout will override your size.
Instead you can specify a width hint for the text in the GridData for the text. Instead of:
txtSearch.setSize(xy);
use:
GridData data = new GridData(SWT.BEGINNING, SWT.CENTER, false, false);
data.widthHint = 300;
txtSize.setLayoutData(data);

Have a way to set the length of JFace's ComboViewer?

There is situation that I have a ComboViewer which will have different content in different time.Thus, it will sometimes need to relayout the ComboViewer so that it can show the full content. Is there any way to define the max length of ComboViewer in beginning? I will very appreciate if you can give me some idea.
The following code is the demo I try according to the rudiger.It works well in windows 7, while the length of the comboviewer is still short when it switches to "abcedfgabcedfg" in linux
.
public class ComboViewerTest {
/**
* #param args
*/
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("Comboviewer Test");
shell.setLayout(new GridLayout(1, false));
Composite composite = new Composite(shell,SWT.None);
composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
composite.setLayout(new GridLayout(2, true));
final String[] txtStrings = {"a","abc"};
final String[] txtStrings2 = { "abcedfg", "abcedfgabcedfg"};
Label label = new Label(composite, SWT.NONE);
label.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true, 1, 1));
label.setText("comboviewer");
final ComboViewer comboViewer = new ComboViewer(composite,SWT.NONE | SWT.READ_ONLY);
Combo combo = comboViewer.getCombo();
combo.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, true, 1, 1));
comboViewer.setContentProvider(new ArrayContentProvider());
comboViewer.setInput(txtStrings);
comboViewer.setLabelProvider(new LabelProvider() {
#Override
public String getText(Object element) {
return super.getText(element);
}
});
Composite composite2 = new Composite(shell,SWT.None);
composite2.setLayout(new GridLayout(2, true));
Button btnNewButton = new Button(composite2, SWT.RADIO);
btnNewButton.setBounds(0, 0, 84, 29);
btnNewButton.setText("change the comboviewr");
btnNewButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
comboViewer.setInput(txtStrings2);
comboViewer.getCombo().select(0);
}});
Button btnNewButton2 = new Button(composite2, SWT.RADIO);
btnNewButton2.setBounds(0, 0, 84, 29);
btnNewButton2.setText("reset");
btnNewButton2.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
comboViewer.setInput(txtStrings);
comboViewer.getCombo().select(0);
}});
comboViewer.getCombo().select(0);
setComboViewerLength(comboViewer);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
private static void setComboViewerLength(ComboViewer comboViewer) {
String string = "abcedfgabcedfg";
Combo control = comboViewer.getCombo();
GC gc = new GC( control );
Point stringExtent = gc.stringExtent( string );
gc.dispose();
Rectangle bounds = control.computeTrim( 0, 0, stringExtent.x, stringExtent.y );
GridData gridData = new GridData();
gridData.widthHint = bounds.width;
control.setLayoutData( gridData );
}
}
If I understand your question correctly, the problem is twofold.
1. Determining the necessary size to fully display a string of a certain length
The ComboViewer uses SWT's Combo or CCombo widget to display its data. Given the string to display, you can determine the necessary size of the combo in pixels as follows:
String string = "abc";
ComboViewer comboViewer = ...;
Combo control = comboViewer.getCombo();
GC gc = new GC( control );
Point stringExtent = gc.stringExtent( string );
gc.dispose();
Rectangle bounds = control.computeTrim( 0, 0, stringExtent.x, stringExtent.y );
The returned bounds describe a rectangle that if the combo's bounds were set to that rectangle, is large enough to display the string and trimmings (the drop-down button, borders, etc.).
2. Configuring the layout to use the above calculated size for the combo box
How to control the size of a widget depends on which layout manager you are using. The layout manager that is used is set on the parent of your combo.
Some - but not all - layouts allow to give hints or explicitly set the desired width and height of a control.
If you are using a GridLayout, for example, define a GridData for the combo to control its size.
Combo control = comboViewer.getCombo();
GridData gridData = new GridData();
gridData.widthHint = bounds.width;
control.setLayoutData( gridData );
For more on layouts and a description of the SWT standard layouts I recommend reading the Understanding Layouts in SWT article.

How to add 2 different composite having different layout on main composite?

I want to show view which contains 2 Tree Viewers and one Table Viewer.
It will look as follow,
TreeViewer1 | TreeViewer2
-------------TableViewer------------
(Sorry as I can't upload the image from my machine due to some restrictions, but the above controls must fill the entire area of the view)
For this I had created one mainComposite, which will hold all the controls and which is having RowLayout with SWT.VERTICAL style.
After that I had created top composite which is going to hold TreeViewer1 and TreeViewer2, and which is having Grid layout with 2 columns.(Where each column will contain one TreeViewer resp.)
After that I had created bottom composite which is going to hold TableViewer, and which is again having grid layout with 1 column.
mainComposite holds top and bottom composite. The top and bottom composite needs to share mainComposites height equally and both composites needs to acquire entire width of mainComposite.
When I run the program, my controls are coming in order as I want.But they are not acquiring the entire width of the composite.( i.e. they are coming in left corner ).
I tried using different type of layouts but no help.
I tried with the post
http://www.programcreek.com/2012/03/eclipse-rcp-tutorial-5-how-to-layout-your-view-gridlayout-example/ but didn't work for me since I am having table viewer and not Text.
Any help is appreciated.
Regards,
Mandar
You can get the behavior that I think you're looking for (both trees as well as the table using all available space) by using a bunch of GridLayouts with alignments set to SWT.FILL and both grabExcess*Space parameters set to true.
Try this:
#Override
public void createPartControl(Composite parent) {
Composite container = new Composite(parent, SWT.NONE);
GridLayout gl_container = new GridLayout(1, false);
gl_container.horizontalSpacing = 15;
container.setLayout(gl_container);
Composite mainComposite = new Composite(container, SWT.NONE);
mainComposite.setLayout(new GridLayout(1, false));
mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
Composite treesComposite = new Composite(mainComposite, SWT.NONE);
treesComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
treesComposite.setLayout(new GridLayout(2, false));
TreeViewer leftTreeViewer = new TreeViewer(treesComposite, SWT.BORDER);
Tree leftTree = leftTreeViewer.getTree();
leftTree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
TreeViewer rightTreeViewer = new TreeViewer(treesComposite, SWT.BORDER);
Tree rightTree = rightTreeViewer.getTree();
rightTree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
TableViewer bottomTableViewer = new TableViewer(mainComposite, SWT.BORDER | SWT.FULL_SELECTION);
bottomTable = bottomTableViewer.getTable();
bottomTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
}
Alternatively, you could try using FormLayouts.
Here I specify the locations of things using the "numerator/offset" approach. Where you see numbers like 0/50/100, those are essentially percentages of the available space. The smaller numbers like 5/-5 are offsets, in pixels, from the positions described by those percentages; they provide a small margin between components.
#Override
public void createPartControl(Composite parent) {
Composite container = new Composite(parent, SWT.NONE);
GridLayout gl_container = new GridLayout(1, false);
gl_container.horizontalSpacing = 15;
container.setLayout(gl_container);
Composite mainComposite = new Composite(container, SWT.NONE);
mainComposite.setLayout(new FormLayout());
mainComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
Composite treesComposite = new Composite(mainComposite, SWT.NONE);
FormData fd_treesComposite = new FormData();
fd_treesComposite.bottom = new FormAttachment(50);
fd_treesComposite.right = new FormAttachment(100);
fd_treesComposite.top = new FormAttachment(0);
fd_treesComposite.left = new FormAttachment(0);
treesComposite.setLayoutData(fd_treesComposite);
treesComposite.setLayout(new FormLayout());
TreeViewer leftTreeViewer = new TreeViewer(treesComposite, SWT.BORDER);
Tree leftTree = leftTreeViewer.getTree();
FormData fd_leftTree = new FormData();
fd_leftTree.bottom = new FormAttachment(100);
fd_leftTree.right = new FormAttachment(50, -2);
fd_leftTree.top = new FormAttachment(0, 5);
fd_leftTree.left = new FormAttachment(0, 5);
leftTree.setLayoutData(fd_leftTree);
TreeViewer rightTreeViewer = new TreeViewer(treesComposite, SWT.BORDER);
Tree rightTree = rightTreeViewer.getTree();
FormData fd_rightTree = new FormData();
fd_rightTree.bottom = new FormAttachment(100);
fd_rightTree.right = new FormAttachment(100, -5);
fd_rightTree.top = new FormAttachment(0, 5);
fd_rightTree.left = new FormAttachment(50, 3);
rightTree.setLayoutData(fd_rightTree);
TableViewer bottomTableViewer = new TableViewer(mainComposite, SWT.BORDER | SWT.FULL_SELECTION);
bottomTable = bottomTableViewer.getTable();
FormData fd_bottomTable = new FormData();
fd_bottomTable.bottom = new FormAttachment(100, -5);
fd_bottomTable.right = new FormAttachment(100, -5);
fd_bottomTable.top = new FormAttachment(50, 5);
fd_bottomTable.left = new FormAttachment(0, 5);
bottomTable.setLayoutData(fd_bottomTable);
}
Use in all composites FillLayout. Here is an small example how to use it. Important is to set SWT.VERTICAL/SWT.HORIZONTAL.