e4 RCP Application: How do I disable window interaction with a Dialog? - eclipse-rcp

I have a window with a table that allow users to add/edit and delete entries. The buttons will bring up a dialog window to perform the actions (Made with Window builder editor). However when the dialog window is up users can still interact with the table which could prove problematic. How can I "disable" interaction with the table window until the dialog window is closed?
Dialog class
public class RoleEditDialog {
Text txtRoleName;
Spinner spnrEksLvl;
Spinner spnrLvl;
#PostConstruct
public void postConstruct(Composite parent) {
parent.setLayout(null);
Group group = new Group(parent, SWT.BORDER);
group.setText("Role");
group.setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
group.setBounds(29, 83, 236, 164);
Label label = new Label(group, SWT.NONE);
label.setText("Role Name");
label.setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
label.setBounds(8, 30, 66, 14);
txtRoleName = new Text(group, SWT.BORDER);
txtRoleName.setBounds(74, 27, 152, 20);
Label label_1 = new Label(group, SWT.NONE);
label_1.setText("EKS Level");
label_1.setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
label_1.setBounds(8, 67, 59, 14);
spnrEksLvl = new Spinner(group, SWT.BORDER);
spnrEksLvl.setBounds(74, 64, 152, 20);
spnrLvl = new Spinner(group, SWT.BORDER);
spnrLvl.setBounds(74, 101, 152, 20);
Label label_2 = new Label(group, SWT.NONE);
label_2.setText("Level");
label_2.setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
label_2.setBounds(8, 104, 54, 14);
Label label_3 = new Label(parent, SWT.NONE);
label_3.setText("Role Administration");
label_3.setFont(SWTResourceManager.getFont("Lucida Bright", 19, SWT.BOLD));
label_3.setBounds(10, 10, 259, 29);
Label label_4 = new Label(parent, SWT.NONE);
label_4.setText("New/Update Role");
label_4.setBounds(97, 38, 93, 15);
}
}
Handler class to open dialog
public class OpenEditRoleHandler {
#Inject
EModelService modelService;
#Inject
MApplication application;
#Execute
public void execute(MPart part)
{
RoleController roleController = new RoleController();
if(part!=null)
{
RolesFrame rolesFrame = (RolesFrame) part.getObject();
int selecRow = rolesFrame.table.getSelectionIndex();
if(selecRow!=-1)
{
RightController rightController = new RightController();
//Dialog
modelService.find("ats_usermanagement_rcp.dialog.RoleAdmin", application).setToBeRendered(true);
//Dialog part (I have more than one part so depending on if Add/Edit was selected the appropriate part would be rendered)
modelService.find("ats_usermanagement_rcp.part.RoleEditDialog", application).setToBeRendered(true);
Role selectedRole = roleController.getRole((long) Integer.parseInt(rolesFrame.table.getItem(selecRow).getText(0)));
MPart editPart = (MPart) modelService.find("ats_usermanagement_rcp.part.RoleEditDialog", application);
RoleEditDialog editRole = (RoleEditDialog) editPart.getObject();
editRole.txtRoleName.setText(selectedRole.getRolename());
editRole.spnrLvl.setSelection(selectedRole.getLevel());
editRole.spnrEksLvl.setSelection(selectedRole.getEksLevel());
}
}
}
}

This isn't really what is traditionally known as a Dialog - it is another part opening in a separate window. e4 doesn't really have good support for dialogs done using the Application.e4xmi. Most dialogs are done using the JFace Dialog class (org.eclipse.jface.dialogs.Dialog) and aren't in the Application.e4xmi.
You may be able to adjust the behaviour of the window by overriding the window style using the styleOverride (see here) to specify the SWT.APPLICATION_MODAL flag. The override value for a dialog would be
styleOverride 68720
68720 is the numeric value of the SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL | SWT.MAX | SWT.RESIZE flags.

Related

SWT - How to change the size of Text box dynamically

I am trying to create a Simple UI which contains a combo, a text box and a browse button. The combo will be containing two values: Execution Times and Execute with File.
When the Execution Times option is selected, the combo box followed by a text box should be displayed.
when the Execute with File option is selected, the combo box, a text box, and a browse button should be displayed.
When I am switching between these options, the widgets are not getting aligned properly. Refer to the below image. The text box size is not getting expanded to the available space.
public class TestUI {
public static void main(String[] args)
{
Display display = new Display();
final Shell shell = new Shell(display);
shell.setText("StackOverflow");
shell.setLayout(new GridLayout(1, true));
Composite composite = new Composite(shell, SWT.NONE);
composite.setLayout(new GridLayout(3, false));
composite.setLayoutData(new GridData(GridData.FILL_BOTH));
Combo combo = new Combo(composite, SWT.READ_ONLY);
String[] input = { "Execution Times", "Execute with File" };
combo.setItems(input);
Text loopText = new Text(composite, SWT.SINGLE | SWT.BORDER);
GridData gridData = new GridData(SWT.BEGINNING | GridData.FILL_HORIZONTAL);
gridData.horizontalSpan = 2;
loopText.setLayoutData(gridData);
loopText.setEnabled(false);
Button browseButton = new Button(composite, SWT.PUSH);
browseButton.setText("Browse...");
browseButton.setVisible(false);
combo.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
String text2 = combo.getText();
System.out.println(text2);
if (text2.equals("Execution Times")) {
loopText.setEnabled(true);
loopText.setText("1");//$NON-NLS-1$
GridData gridData1 = new GridData(SWT.BEGINNING, SWT.TOP, false, false);
gridData1.grabExcessHorizontalSpace = true;
gridData1.horizontalSpan = 2;
loopText.setLayoutData(gridData1);
browseButton.setVisible(false);
loopText.getParent().layout();
}
if (text2.equals("Execute with File")) {
GridData gridData1 = new GridData(SWT.BEGINNING, SWT.TOP, false, false);
gridData1.grabExcessHorizontalSpace = true;
loopText.setLayoutData(gridData1);
gridData.exclude= false;
browseButton.setVisible(true);
browseButton.setFocus();
loopText.setText("");
loopText.setEnabled(false);
loopText.getParent().layout();
}
}
});
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
}
Can any one help me on this?
From what I understand, depending on the combo selection, the text field and text field plus button serve different purposes:
when Execution Times is selected, the number of times is to be entered
otherwise Execute with File requires a file name to be entered or browsed for
Therefore, I would use a Composite next to the combo widget to hold either a text field to enter a number (or even a Spinner) or a text field and button to enter/select a file name.
Composite composite = new Composite( parent, SWT.NONE );
Text executionTimesText = new Text( composite, SWT.BORDER );
composite.setLayout( new StackLayout() );
Composite executionFileComposite = new Composite( composite, SWT.NONE );
// use a GridLayout to position the file name text field and button within the executionFileComposite
combo.addListener( SWT.Selection, event -> {
StackLayout layout = ( StackLayout )composite.getLayout();
if( combo.getSelectionIndex() == 0 ) {
layout.topControl = executionTimesText;
} else if( combo.getSelectionIndex() == 1 ) {
layout.topControl = executionFileComposite;
}
composite.layout();
}
The StackLayout allows you to stack the different input fields and switch betwen them as needed (i.e. according to the combo's selection).
For starters, you don't need to recreate the GridData for the Text widget every time. Instead, just modify the original via gridData.horizontalSpan, or if in practice you don't have access to the GridData instance, you can get at it via ((GridData) gridData.getLayoutData()).horizontalSpan, etc.
The reason you're seeing the blank space at the bottom of the Shell is because you've created a layout with 3 columns, and then added the following:
The Combo
The Text (with horizontalSpan set to 2, so this uses 2 columns)
The Button
The Combo and the Text take up all 3 columns, so a new row is added for the Button. Then you call pack(), and the preferred size is calculated, which will be for 2 rows, and the first row only sized for 2 widgets.
Instead of calling pack() and shrinking the size of the Shell down to the preferred size, we can just set a size on the Shell via Shell.setSize(...). In general you don't want to mix setSize(...) and layouts, but you've tagged your post with "RCP", so your Shell will already have a size and you won't be manually calling pack() and open().
Full example:
public static void main(String[] args) {
Display display = new Display();
final Shell shell = new Shell(display);
shell.setSize(300, 80);
shell.setText("StackOverflow");
shell.setLayout(new GridLayout(1, true));
Composite composite = new Composite(shell, SWT.NONE);
composite.setLayout(new GridLayout(3, false));
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
final Combo combo = new Combo(composite, SWT.READ_ONLY);
String[] input = {"Execution Times", "Execute with File"};
combo.setItems(input);
final Text loopText = new Text(composite, SWT.SINGLE | SWT.BORDER);
final GridData textGridData = new GridData(SWT.FILL, SWT.FILL, true, false);
textGridData.horizontalSpan = 2;
loopText.setLayoutData(textGridData);
loopText.setEnabled(false);
final Button browseButton = new Button(composite, SWT.PUSH);
browseButton.setText("Browse...");
browseButton.setVisible(false);
combo.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
String text2 = combo.getText();
System.out.println(text2);
if (text2.equals("Execution Times")) {
loopText.setEnabled(true);
loopText.setText("1");
// Can also do ((GridData) textGridData.getLayoutData())...
textGridData.grabExcessHorizontalSpace = true;
textGridData.horizontalSpan = 2;
browseButton.setVisible(false);
loopText.getParent().layout();
}
if (text2.equals("Execute with File")) {
loopText.setEnabled(false);
loopText.setText("");
textGridData.grabExcessHorizontalSpace = true;
textGridData.horizontalSpan = 1;
browseButton.setVisible(true);
browseButton.setFocus();
loopText.getParent().layout();
}
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
Alternatively, if you are actually creating and opening a new Shell, then call pack() (to get the preferred size) prior to making the Text widget take up two columns:
shell.pack();
// Move these two lines down to the end
textGridData.horizontalSpan = 2;
browseButton.setVisible(false);
shell.layout(true, true);
shell.open();
What we've done is add all 3 widgets without adjusting the horizontalSpan. Then, call pack() to set the size of the Shell assuming that all 3 widgets appear in a single row. After calling pack(), set the horizontalSpan to 2, and hide the Button. When the Shell is opened, you will see:

Issue in displaying of SWT composite for RCP

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.

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.

ExpandBar in Eclipse View Part

I am trying to add an expand bar to an Eclipse viewpart. When I click the expand button I would like the viewpart to move items below the expand bar down and show the expanded items. What currently happens is the expand bar items just disappear below the items below the expand bar. Any thoughts?
final ExpandBar expandBar = new ExpandBar(parent, SWT.NONE);
expandBar.setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
expandBar.setSpacing(0);
fd_toolBar.top = new FormAttachment(expandBar, 6);
FormData fd_expandBar = new FormData();
fd_expandBar.top = new FormAttachment(0, 62);
fd_expandBar.left = new FormAttachment(0, 3);
expandBar.setLayoutData(fd_expandBar);
formToolkit.paintBordersFor(expandBar);
final ExpandItem xpndtmWarningDetails = new ExpandItem(expandBar, SWT.NONE);
xpndtmWarningDetails.setExpanded(true);
xpndtmWarningDetails.setText("Warning Details");
final Composite composite_1 = new Composite(expandBar, SWT.NONE);
composite_1.setBackground(SWTResourceManager.getColor(SWT.COLOR_YELLOW));
xpndtmWarningDetails.setControl(composite_1);
formToolkit.paintBordersFor(composite_1);
xpndtmWarningDetails.setHeight(xpndtmWarningDetails.getControl().computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
Label lblTest = new Label(composite_1, SWT.NONE);
lblTest.setBounds(10, 10, 55, 15);
lblTest.setText("Test");
expandBar.addExpandListener(new ExpandListener(){
#Override
public void itemCollapsed(ExpandEvent e) {
expandBar.setSize(expandBar.getSize().x, xpndtmWarningDetails.getHeaderHeight());
parent.layout(true);
}
#Override
public void itemExpanded(ExpandEvent e) {
expandBar.setSize(expandBar.getSize().x, 300);
expandBar.layout(true);
parent.layout(true);
}
});
I think the ExpandBar works best when used like it is in this example...
http://git.eclipse.org/c/platform/eclipse.platform.swt.git/tree/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet343.java
... with several expand bars stacked on top of each other, and nothing else mixed in.
I think the functionality your looking for can be accomplished with an ExpandableComposite object. It depends on what else is going on in your ViewPart.
Here's a quick example of an ExpandableComposite.
package com.amx.designsuite.rcp;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.widgets.ExpandableComposite;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.forms.widgets.TableWrapLayout;
public class ExpandableCompositeExample extends Composite {
/**
* Create the composite.
* #param parent
* #param style
*/
public ExpandableCompositeExample(final Composite parent, int style) {
super(parent, style);
FormToolkit toolkit;
toolkit = new FormToolkit(parent.getDisplay());
final ScrolledForm form = toolkit.createScrolledForm(parent);
form.setText("Title for Form holding Expandable Composite (optional)");
TableWrapLayout layout = new TableWrapLayout();
form.getBody().setLayout(layout);
ExpandableComposite expandableCompsite = toolkit.createExpandableComposite(form.getBody(), ExpandableComposite.TREE_NODE | ExpandableComposite.SHORT_TITLE_BAR);
toolkit.paintBordersFor(expandableCompsite);
expandableCompsite.setText("Expandable Composite Title (Optional)");
expandableCompsite.setExpanded(true);
Text txtMyNewText = toolkit.createText(expandableCompsite, "Text to show when composite is expanded", SWT.NONE);
expandableCompsite.setClient(txtMyNewText);
}
#Override
protected void checkSubclass() {
// Disable the check that prevents subclassing of SWT components
}
}