I have an Image in a grid that scales when the PartView is resized. If the BarsView starts smaller than 64 high (the size of the canvas), the bottom portion of the image gets cut off below the initial size. If it starts larger than what it is resized to, the minivitals does not shrink as it should. How can I the layout, when resized, to look like it does when I open the program at that size?
Screenshot of when the program is opened at normal size:
Shrunk after opening at normal size (notice the concentration bar is pushed off the bottom of the screen):
Opened at smaller size:
Opened at smaller size then expanded:
Restarting between resizing has the desired effect, except for the needing to restart part.
public class BarsView extends ViewPart {
private PageBook book;
public void createPartControl(Composite parent) {
book = new PageBook(parent, SWT.NONE);
book.setLayout(new FillLayout());
Composite page = new BarsPageView(book, view);
book.showPage(page);
}
private class BarsPageView extends Composite {
public BarsPageView(Composite parent, GameView view) {
super(parent, SWT.NONE);
this.setLayout(new GridLayout(3, false));
// This is a wrapper around a StyledText
entry = new StormFrontEntry(this, view);
GridData entryData = new GridData(SWT.FILL, SWT.BEGINNING, true, false);
entryData.heightHint = 22;
entry.getWidget().setLayoutData(entryData); // getWidget() returns the StyledText
// This is a Composite containing a Canvas
status = new StormFrontStatus(this, view);
status.setLayoutData(new GridData(SWT.CENTER, SWT.BEGINNING, false, false));
// This is defined below
GridData compassData = new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 2);
compassData.heightHint = 64;
compass = new WarlockCompass(this, SWT.NONE, theme, compassData);
compass.setLayoutData(compassData);
minivitals = new StormFrontDialogControl(this, SWT.NONE);
GridData mvData = new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1);
minivitals.setLayoutData(mvData);
}
}
public class WarlockCompass extends Canvas {
public WarlockCompass (final Composite parent, int style, CompassTheme theme, GridData layoutData) {
super(parent, style);
addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
drawCompass(e.gc);
}
});
parent.addListener(SWT.Resize, new Listener() {
#Override
public void handleEvent(Event event) {
// I cut out the calculations for this
layoutData.heightHint = height;
WarlockCompass.this.setSize(width, height);
}
});
}
private void drawCompass (GC gc) {
// Cut out the calculations to scale the image to fix the canvas
gc.drawImage(scaledImage, 0, 0);
}
}
// This is defined below
GridData compassData = new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 2);
compassData.heightHint = 64;
compass = new WarlockCompass(this, SWT.NONE, theme, compassData);
compass.setLayoutData(compassData);
Should have been:
// This is defined below
GridData compassData = new GridData(SWT.CENTER, SWT.CENTER, false, true, 1, 2);
compassData.heightHint = 64;
compass = new WarlockCompass(this, SWT.NONE, theme, compassData);
compass.setLayoutData(compassData);
Changing that flag makes it resize properly.
Related
I'm sadly far from being an expert in SWT and RCP, but I really tried my best here... I can't figure out how to configure the widgets to get this layout (just a Photoshopped screen, never worked this way):
This is what I get if I set the column number of the GridLayout to 2:
Here is the Refresh and the Blacklist button in the wrong row, but at least everything is visible...
And this is what I get if I set the column number of the GridLayout to 3:
This is total messed up... Most of the widgets are pushed outside the visible area. DatePicker, Refresh, Whitelist and the Calculate buttons are not visible, they are somewhere outside on the right.
This is the codepart for this screen area:
resultingProductsGroup = new Group(propProdGroup, SWT.NONE);
final GridData gd_resultingProductsGroup = new GridData(SWT.FILL,
SWT.CENTER, true, false);
gd_resultingProductsGroup.widthHint = 240;
resultingProductsGroup.setLayoutData(gd_resultingProductsGroup);
resultingProductsGroup.setText("Resulting products");
final GridLayout gridLayout_4 = new GridLayout();
gridLayout_4.numColumns = 2;
resultingProductsGroup.setLayout(gridLayout_4);
Label refDateLabel = new Label(resultingProductsGroup, SWT.NONE);
refDateLabel.setText("Reference date:");
refDateInput = new DateInput(resultingProductsGroup, SWT.BORDER);
refDateInput.setLayoutData(new GridData());
refDateInput.setValue(new Date());
calculateProductsButton1 = new Button(resultingProductsGroup, SWT.NONE);
setupImageButton(calculateProductsButton1, Images.getButtonRefresh());
calculateProductsButton1.setLayoutData(new GridData());
GridDataFactory.swtDefaults().hint(18, 18).applyTo(
calculateProductsButton1);
resultingProductsTable = new TableListWidget<Product>(
resultingProductsGroup, SWT.BORDER, ListWidgetMode.MULTI);
resultingProductsTable.setLinesVisible(true);
resultingProductsTable.setHeaderVisible(true);
final GridData rpTableProperty = new GridData(SWT.FILL, SWT.FILL, true,
true, 3, 1);
resultingProductsTable.setLayoutData(rpTableProperty);
GridDataFactory.swtDefaults().hint(230, 240).applyTo(
resultingProductsTable);
setupResultingProductsTableColumns();
resultingProductsTable.sortByComparator(new Comparator<Product>() {
#Override
public int compare(Product o1, Product o2) {
return o1.getPartNum().getExternalId().compareTo(
o2.getPartNum().getExternalId());
}
});
resultingProductsTable.addOpenListener(new IOpenListener() {
#Override
public void open(OpenEvent event) {
doResultingProductsTableOpen();
}
});
calculateProductsButton2 = new Button(resultingProductsGroup, SWT.NONE);
calculateProductsButton2.setText("Calculate");
whitelistAddButton = new Button(resultingProductsGroup, SWT.NONE);
whitelistAddButton.setText("Whitelist");
whitelistAddButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
doAddToWhitelist();
}
});
blacklistAddButton = new Button(resultingProductsGroup, SWT.NONE);
blacklistAddButton.setText("Blacklist");
blacklistAddButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
doAddToBlacklist();
}
});
What am I not seeing here? I'm stuck with this GUI bug for over 2 days now... Please, help me :)
You could design the whole composite with one GridLayout and 3 columns, while using horizontal span of 3 on the table. That doesn't give you the desired mocked up screen though, because reference date controls and buttons at the bottom would be aligned in columns.
Try instead using 3 composites
reference date: row layout
table: fill layout
button list: row layout
I am creating a legend view and inside the shell is supposed to have a rectangle followed by a label describing the color. I was able to get the view to work using just a normal composite but the legend continues beyond the screen and no way of see it without making the window larger. I am trying to use a scrolledComposite view for my shell but when I execute the program, nothing appears.
public void createPartControl(Composite parent)
{
display = parent.getDisplay();
parent.setLayout(new FillLayout());
sc = new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
LegendView.composite = new Composite(sc, SWT.NONE);
RowLayout layout = new RowLayout();
layout.wrap = true;
layout.spacing = 5;
composite.setLayout(layout);
}
public static void addRectangle(String legendMessage)
{
final String propId = legendMessage;
final String[] s = propId.split(",");
if (display != null)
{
display.syncExec(new Runnable()
{
#Override
public void run()
{
// Creating the color using the RBG values
final Color color =
new Color(display, Integer.parseInt(s[0]), Integer.parseInt(s[1]), Integer.parseInt(s[2]));
// Creating a canvas for which the rectangle can be drawn on
Canvas canvas = new Canvas(composite, SWT.NONE);
// Maybe set the bounds of the canvas
canvas.addPaintListener(new PaintListener()
{
public void paintControl(PaintEvent e)
{
e.gc.drawRectangle(1, 1, 50, 60);
e.gc.setBackground(color);
e.gc.fillRectangle(2, 2, 49, 59);
}
});
// Disposing the color after it has been used
canvas.addDisposeListener(new DisposeListener()
{
public void widgetDisposed(DisposeEvent e)
{
color.dispose();
}
});
// Creating a label and setting the font
Label label = new Label(composite, SWT.NULL);
Font boldFont = new Font( label.getDisplay(), new FontData( "Arial", 12, SWT.BOLD ) );
label.setFont( boldFont );
label.setText(s[3]);
composite.redraw();
composite.layout(true);
sc.setContent(composite);
}
});
}
}
I am calling add rectangle in a different class. I am fairly new at using SWT and after looking at examples and reading the docs for scrolled Composite, this is what I interpreted it as. Any help would be very appreciated.
You haven't told the ScrolledComposite how to manage the size. You must either call setSize or setMinSize. For this you probably want:
sc.setExpandHorizontal(true);
sc.setExpandVertical(true);
sc.setMinSize(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT));
Is it possible to always show the vertical scroll bar in a SWT table even if the table is empty? By always showing a (possible disabled) vertical scroll bar one can avoid that the last column get partially hidden when the columns use ColumnWeightData for layouting.
I tried to initialize the table with SWT.V_SCROLL or to use table.getVerticalBar().setVisible(true) - both without success.
There is a method setAlwaysShowScrollBars in ScrollableComposite. What I am looking for is a similar method in Table.
UPDATE: I suppose that the scroll bars which are visible when the table contains enough data are not those scroll bars which Table inherits from Scrollable. I have debugged ScrollBar.setVisible(boolean) and it seems not be called on table layout updates. Is this observation correct?
UPDATE 2: Here is a snippet for a table construction. It would be great to have the vertical scrollbar visible even if the table is empty and to have the column headers visible even if the table data are scrolled down. Note: The snippet has left out some details as the label provider and some other controls arranged at the same parent composite.
protected void createMasterPart(final IManagedForm managedForm, Composite parentComposite)
{
FormToolkit toolkit = managedForm.getToolkit();
Composite contentComposite = toolkit.createComposite(parentComposite, SWT.NONE);
contentComposite.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 1));
toolkit.paintBordersFor(contentComposite);
contentComposite.setLayout(new GridLayout(2, false));
GridData gd;
Composite tableComposite = new Composite(contentComposite, SWT.NONE);
TableColumnLayout tableColumnLayout = new TableColumnLayout();
tableComposite.setLayout(tableColumnLayout);
gd = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 3);
tableComposite.setLayoutData(gd);
speakerTableViewer = new TableViewer(tableComposite, SWT.BORDER | SWT.FULL_SELECTION);
speakerTableViewer.setContentProvider(ArrayContentProvider.getInstance());
Table speakerTable = speakerTableViewer.getTable();
speakerTable.setHeaderVisible(true);
speakerTable.setLinesVisible(true);
toolkit.paintBordersFor(speakerTable);
TableViewerColumn tableViewerAudiosampleColumn = new TableViewerColumn(speakerTableViewer, SWT.NONE);
TableColumn audiosampleColumn = tableViewerAudiosampleColumn.getColumn();
tableColumnLayout.setColumnData(audiosampleColumn, new ColumnWeightData(60, true));
audiosampleColumn.setText("Sample");
TableViewerColumn tableViewerSpeakerColumn = new TableViewerColumn(speakerTableViewer, SWT.NONE);
TableColumn speakerColumn = tableViewerSpeakerColumn.getColumn();
tableColumnLayout.setColumnData(speakerColumn, new ColumnWeightData(60, true));
speakerColumn.setText("Speaker");
TableViewerColumn tableViewerRemarkColumn = new TableViewerColumn(speakerTableViewer, SWT.NONE);
TableColumn remarkColumn = tableViewerRemarkColumn.getColumn();
tableColumnLayout.setColumnData(remarkColumn, new ColumnWeightData(120, true));
remarkColumn.setText("Remark");
}
It's not possible to force the Table to always show scroll bars, the OS decides when to show them.
Alternatives
Right, I came up with a solution very similar to my answer to this question:
Is it possible to get the vertical/horizontal scroll bar visible when the SWT List is in disabled state?
The idea is to use a ScrolledComposite (as the other answer already suggested) to take care of the scrolling. The Table itself won't scroll. However, this won't make any difference, because the user won't be able to tell the difference.
ScrolledComposite has a method called setAlwaysShowScrollBars(boolean) with which you can force it to always show the scroll bars, even if they aren't required.
Here is some sample code, that will illustrate what I just talked about:
public static void main(String[] args)
{
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setLayout(new GridLayout());
final ScrolledComposite composite = new ScrolledComposite(shell, SWT.V_SCROLL);
composite.setLayout(new GridLayout());
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
final Table table = new Table(composite, SWT.NO_SCROLL | SWT.FULL_SELECTION);
table.setHeaderVisible(true);
composite.setContent(table);
composite.setExpandHorizontal(true);
composite.setExpandVertical(true);
composite.setAlwaysShowScrollBars(true);
composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT));
Button fillTable = new Button(shell, SWT.PUSH);
fillTable.setText("Fill table");
fillTable.setLayoutData(new GridData(SWT.FILL, SWT.END, true, false));
fillTable.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event arg0)
{
if (table.getColumnCount() < 1)
{
for (int col = 0; col < 4; col++)
{
TableColumn column = new TableColumn(table, SWT.NONE);
column.setText("Column " + col);
}
}
for (int row = 0; row < 20; row++)
{
TableItem item = new TableItem(table, SWT.NONE);
for (int col = 0; col < table.getColumnCount(); col++)
{
item.setText(col, "Item " + row + " " + col);
}
}
for (int col = 0; col < table.getColumnCount(); col++)
{
table.getColumn(col).pack();
}
composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT));
}
});
Button clearTable = new Button(shell, SWT.PUSH);
clearTable.setText("Clear table");
clearTable.setLayoutData(new GridData(SWT.FILL, SWT.END, true, false));
clearTable.addListener(SWT.Selection, new Listener()
{
#Override
public void handleEvent(Event arg0)
{
table.removeAll();
composite.setMinSize(table.computeSize(SWT.DEFAULT, SWT.DEFAULT));
}
});
shell.pack();
shell.setSize(400, 300);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
Looks like this:
As you can see, the scroll bar is always visible.
UPDATE
As pointed out in the comment, this approach will not keep the Table headers visible when you scroll down. If you could post a small working code example that illustrates your problem, we might come up with an alternative (unrelated to forcing the scroll bars).
UPDATE2
Here is some code that should do what you want, the trick is to trigger a resize event on the parent of the TableViewer, the horizontal scrollbar that is shown isn't really necessary and it disappears after you resize the window:
public static void main(String[] args)
{
final Display display = new Display();
final Shell shell = new Shell(display);
shell.setText("StackOverflow");
shell.setLayout(new GridLayout());
createMasterPart(shell);
shell.pack();
shell.setSize(400, 300);
shell.open();
shell.layout(true, true);
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
private static void createMasterPart(Composite parentComposite)
{
Composite composite = new Composite(parentComposite, SWT.NONE);
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
composite.setLayout(new GridLayout(1, false));
Composite tableComposite = new Composite(composite, SWT.NONE);
TableColumnLayout tableColumnLayout = new TableColumnLayout();
tableComposite.setLayout(tableColumnLayout);
tableComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
TableViewer tableViewer = new TableViewer(tableComposite, SWT.BORDER | SWT.FULL_SELECTION);
tableViewer.setContentProvider(ArrayContentProvider.getInstance());
Table table = tableViewer.getTable();
table.setHeaderVisible(true);
table.setLinesVisible(true);
TableViewerColumn firstTableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
TableColumn firstTableColumn = firstTableViewerColumn.getColumn();
firstTableColumn.setText("Sample");
firstTableViewerColumn.setLabelProvider(new ColumnLabelProvider()
{
#Override
public String getText(Object element)
{
Dummy p = (Dummy) element;
return p.first;
}
});
TableViewerColumn secondTableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
TableColumn secondTableColumn = secondTableViewerColumn.getColumn();
secondTableColumn.setText("Speaker");
secondTableViewerColumn.setLabelProvider(new ColumnLabelProvider()
{
#Override
public String getText(Object element)
{
Dummy p = (Dummy) element;
return p.second;
}
});
TableViewerColumn thirdTableViewerColumn = new TableViewerColumn(tableViewer, SWT.NONE);
TableColumn thirdTableColumn = thirdTableViewerColumn.getColumn();
thirdTableColumn.setText("Remark");
thirdTableViewerColumn.setLabelProvider(new ColumnLabelProvider()
{
#Override
public String getText(Object element)
{
Dummy p = (Dummy) element;
return p.third;
}
});
List<Dummy> elements = new ArrayList<>();
for(int i = 0; i < 20; i++)
{
elements.add(new Dummy("firstfirstfirst " + i, "secondsecondsecond " + i, "thirdthirdthirdthirdthirdthird " + i));
}
tableViewer.setInput(elements);
tableColumnLayout.setColumnData(firstTableColumn, new ColumnWeightData(1, true));
tableColumnLayout.setColumnData(secondTableColumn, new ColumnWeightData(1, true));
tableColumnLayout.setColumnData(thirdTableColumn, new ColumnWeightData(2, true));
}
private static class Dummy
{
public String first;
public String second;
public String third;
public Dummy(String first, String second, String third)
{
this.first = first;
this.second = second;
this.third = third;
}
}
I have created a solution that I think is better than put your table inside a ScrolledComposite.
My solution: fill my table with empty items until my scroll bar is visible.
Example:
// Flag that knows if the empty item was added or not
boolean addedEmptyItem = false;
// Get the table client area
Rectangle rect = table.getClientArea ();
// Get the item height
int itemHeight = table.getItemHeight ();
// Get the header height
int headerHeight = table.getHeaderHeight ();
// Calculate how many items can be visible without scrolling
int visibleCount = (rect.height - headerHeight + itemHeight - 1) / itemHeight;
while ( visibleCount > table.getItemCount() ) {
// Add an empty item
new TableItem( table, SWT.NONE );
// Set the flag
addedEmptyItem = true;
}
// Vertical bar é disabled if an empty item was added
table.getVerticalBar().setEnabled( !addedEmptyItem );
I hope this solution helps someone.
Thanks.
I don't think you can do this but you can try call ScrolledComposite.setAlwaysShowScrollbars() to true, but you will see both of the enabled scrollbars all the time.
I want to use the JFace PopupDialog as lightweight dialog for user input. But I have some problems with the background color of text widgets.
As you can see below in 1, a SWT.MULTI text widget has no background and border, a SWT.SINGLE text widget has no background.
I tried to override the background color with:
Text comment = new Text(composite, SWT.MULTI|SWT.BORDER);
comment.setFocus();
comment.setBackground(new Color(Display.getDefault(), new RGB(000, 000, 000)));
// method of PopupDialog
applyBackgroundColor(new Color(Display.getDefault(), new RGB(000, 000, 000)), comment);
Does anybody has any idea how to handle this properly?
Thanks in advance!
EDIT: As requested, here is the source for the popup. I subclassed the PopupDialog, as I wanted the popup to be opened next to the Cursor location:
public class MouseLocationPopupDialog extends PopupDialog {
private final static int SHELL_STYLE = PopupDialog.INFOPOPUP_SHELLSTYLE;
public MouseLocationPopupDialog(Shell parent, String infoText) {
this(parent, SHELL_STYLE, true, false, false, false, false, null, infoText);
}
public MouseLocationPopupDialog(Shell parent, String titleText, String infoText) {
this(parent, SHELL_STYLE, true, false, false, false, false, titleText, infoText);
}
public MouseLocationPopupDialog(Shell parent, String infoText, final Point size) {
this(parent, infoText);
getShell().setSize(size);
}
public MouseLocationPopupDialog(Shell parent, int shellStyle, boolean takeFocusOnOpen, boolean persistSize, boolean persistLocation, boolean showDialogMenu, boolean showPersistActions, String titleText, String infoText) {
super(parent, shellStyle, takeFocusOnOpen, persistSize, persistLocation, showDialogMenu, showPersistActions, titleText, infoText);
}
#Override
protected void adjustBounds() {
super.adjustBounds();
Display d = Display.getCurrent();
if (d == null) {
d = Display.getDefault();
}
Point point = d.getCursorLocation();
getShell().setLocation(point.x + 9, point.y + 14);
}
}
The actual usage is as follows:
final PopupDialog dialog = new MouseLocationPopupDialog(HandlerUtil.getActiveShell(event), "Title", "Bottom bar") {
#Override
protected Control createDialogArea(Composite parent) {
Control composite = super.createDialogArea(parent);
Composite table = new Composite((Composite) composite, SWT.NONE);
table.setLayout(new GridLayout(2, true));
// text is a member variable
text = new Text(table, SWT.SINGLE | SWT.BORDER);
Button submit = new Button(table, SWT.PUSH);
return composite;
}
#Override
protected Control createContents(Composite parent) {
Control contents = super.createContents(parent);
final Color backgroundColor = new Color(Display.getCurrent(), new RGB(255, 255, 255));
text.setBackground(backgroundColor);
final Color foregroundColor = new Color(Display.getCurrent(), new RGB(0,0,0));
text.setForeground(foregroundColor);
backgroundColor.dispose();
foregroundColor.dispose();
return contents;
}
};
dialog.open();
Note that this Popup is independent from other UI elements: The code will not wait for the completion of the popups open() like other JFace dialogs (e.g. TitleAreaDialog)
First of all, use SWT.BORDER instead of SWT.BORDER_SOLID. If you're lucky, this somehow causes your problem. Other than that, from your small snippet alone it's hard to see what goes wrong. Unless there is some other code that resets the background color later on, this should work.
Update:
Try to override the method getBackground() of PopupDialog and let it return the color you want. Your code probably is in createDialogArea(..) and PopupDialog applies this color to basically everything after your code.
If you only want to change the background color of specific controls, you could try the following:
#Override
protected Control createContents(Composite parent) {
Composite contents = super.createContents(parent);
// set the color here
return contents;
}
I have a composite element, that initially has a Label. Now I call dispose on the it (the label) and create another label in the same container (composite elm), but I don't see the new text. It brings me to question how do I enable redraw on the composite, so that the new label (or any other component I might create) will render in place of the old one.
Here is the code I have (separated into a unit test for redraw a composite)
private Label createLabel( Composite parent) {
Label label = new Label(parent, SWT.NONE);
label.setAlignment(SWT.CENTER);
label.setLayoutData( new GridData( SWT.CENTER, SWT.CENTER, true, true) );
return label;
}
private void changeText() {
assert testCell != null : "Please initialize test cell";
testCell.getChildren()[0].dispose();
Label l = createLabel(testCell);
l.setText("New TexT");
testCell.redraw();
}
private void draw() {
Display display = new Display();
shell = new Shell(display);
shell.setLayout(new GridLayout(2,false));
testCell = new Composite(shell,SWT.BORDER);
testCell.setLayout(new GridLayout());
Label l = createLabel(testCell);
l.setText("Old Text");
Composite btnCell = new Composite(shell,SWT.NONE);
btnCell.setLayout(new GridLayout());
Button b = new Button(btnCell, SWT.PUSH);
b.setText("Change");
b.addListener(SWT.MouseDown, new Listener() {
public void handleEvent(Event e) {
changeText();
}
});
As you can see, I am calling redraw on the composite after I add a new element. Also, I have verified that after the call to dispose, testCell.getChildren().length returns 0, as expected, and when I create a new label, I get the same expression to return 1, verifying that the new element is indeed getting added to its parent composite container
Am I missing something here ?
In the changeText() function, the
testCell.redraw();
line should be replaced by
testCell.layout();
Or, if you want to resize it correctly you should use
shell.layout();.
I would say add a selectionListener on the label.
.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(final SelectionEvent e) {
//Change text by Label.setText();
}
}