Skip to content

SWT Labels not displaying after disposal and recreation

In the following code, clicking on one of the three display list buttons will first dispose of any labels in a composite and then create labels for each row in a list of Strings.

The problem is that if you click on the same button a second time the text all dispersal.

When you switch to one of the other buttons and the text displays.

The code does the same thing each time which is dispose all the labels inside a composite then add new labels to the composite, what seems to happen is that if you add labels with exactly the same content back in to the composite then it doesn’t display them on screen anymore for some reason.

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

public class BasicMapLabelTestDialog extends Dialog
{
    List<Label> displaylabels = new ArrayList<>();
    Composite content, list;
    
    public BasicMapLabelTestDialog(Shell parentShell)
    {
        super(parentShell);
    }

    @Override
    protected void configureShell(Shell shell)
    {
        super.configureShell(shell);
        shell.setSize(new Point(700, 500));
        shell.setText("FML"); //$NON-NLS-1$
    }

    @Override
    public Control createDialogArea(final Composite comp)
    {
        content = (Composite) super.createDialogArea(comp);
        content.setLayout(new GridLayout(1, false));
        content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); 
        
        
        final List<String> rows1 = new ArrayList<>(3);
        rows1.add("Hello");
        rows1.add("Baz");
        rows1.add("Please");
        rows1.add("Help");
        
        final List<String> rows2 = new ArrayList<>(3);
        rows2.add("You're");
        rows2.add("My");
        rows2.add("Only");
        rows2.add("Hope");
        
        
        final List<String> rows3 = new ArrayList<>(3);
        rows3.add("Or");
        rows3.add("Maybe");
        rows3.add("greg?");
        
        
        
        Button set1 = new Button(content, SWT.PUSH);
        set1.setText("Display List 1");
        set1.addSelectionListener(new SelectionAdapter() {
            
            @Override
            public void widgetSelected(SelectionEvent e) {
                updateList(rows1);
            }
        });
                
        
        Button set2 = new Button(content, SWT.PUSH);
        set2.setText("Display List 2");           
        set2.addSelectionListener(new SelectionAdapter() {
            
            @Override
            public void widgetSelected(SelectionEvent e) {
                updateList(rows2);
            }
        });
        
        Button set3 = new Button(content, SWT.PUSH);
        set3.setText("Display List 3");           
        set3.addSelectionListener(new SelectionAdapter() {
            
            @Override
            public void widgetSelected(SelectionEvent e) {
                updateList(rows3);
            }
        });
        
        
        Button test = new Button(content, SWT.PUSH);
        test.setText("Print Label Content");           
        test.addSelectionListener(new SelectionAdapter() {
            
            @Override
            public void widgetSelected(SelectionEvent e) {
                for (Label l : displaylabels) {
                    System.out.println(l.getText());
                }
            }
        });
        
        
        
        list = new Composite(content, SWT.NONE);
        list.setLayout(new GridLayout(1, true));
        new Label(content, SWT.HORIZONTAL | SWT.SEPARATOR);
        

        return content;
    }
    
    private void updateList(List<String> rows) {
        if (this.displaylabels == null) {
            this.displaylabels = new ArrayList<>();
        }
        for (Label l : displaylabels) {
            l.dispose();
        }
        this.displaylabels.clear();


        for (String item : rows) {
            addListLabel(item);
        }
        
        content.layout();
        content.redraw();
    }
    
    private void addListLabel(String whoText) {
        Label a = new Label(list, SWT.NONE);
        a.setText(whoText);
        this.displaylabels.add(a);
    }
    
    public static void main(String[] args)
    {
        Display d = new Display();
        Shell s = new Shell();

        BasicMapLabelTestDialog fml = new BasicMapLabelTestDialog(s);
        fml.open();
    }
    
}

Answer

Calling

content.layout();

is not enough to do a full layout here. You need to call

content.layout(true, true);

to force all controls to be layed out.

You don’t need the redraw call.