Search code examples
javauser-interfaceswtdraw2d

Enabling scrolling for canvas SWT Draw2d


I'm trying to display more on the canvas than is allowed by the window's/canvas's size limits. I know that there are a couple of ways to this. I could use the FigureCanvas but I'm unsure how the viewport ties into it. I opted to create a ScrolledComposite and placing a canvas within it. My problem is that the scroll bars appear but moving them makes no difference to what is shown on the canvas. Could anyone please point me in the right direction of fixing this? Thanks. *I've added short testable code illustrating the problem.

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.LightweightSystem;
import org.eclipse.draw2d.SimpleRaisedBorder;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.SWT;
import org.eclipse.wb.swt.SWTResourceManager;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.GridData;
import org.xml.sax.SAXException;
import org.eclipse.swt.custom.ScrolledComposite;


public class ScrollDemo extends Dialog {

    protected Shell shell;
    protected IFigure panel;
    protected IFigure v_panel;

    public static void main(String[] args)
    {
        ScrollDemo act= new ScrollDemo(new Shell(), SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
        act.open();
    }


    /**
     * Create the dialog.
     * @param parent
     * @param style
     */
    public ScrollDemo(Shell parent, int style) {
        super(parent, style);
        setText("Scrolling Demo");
    }

    /**
     * Open the dialog.
     * @throws SAXException 
     */
    public void open(){
            createContents();
        shell.open();
        shell.layout();
        Display display = getParent().getDisplay();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }
    }

    /**
     * Create contents of the dialog.
     */
    private void createContents(){
        shell = new Shell(getParent(), getStyle());
        shell.setSize(475, 375);
        shell.setText(getText());
        shell.setLayout(new GridLayout(1, false));

        ScrolledComposite scrolledComposite = new ScrolledComposite(shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
        scrolledComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_DARK_MAGENTA));
        GridData gd_scrolledComposite = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
        gd_scrolledComposite.widthHint = 453;
        gd_scrolledComposite.heightHint = 245;
        scrolledComposite.setLayoutData(gd_scrolledComposite);
        scrolledComposite.setExpandHorizontal(true);
        scrolledComposite.setExpandVertical(true);

        Canvas canvas = new Canvas(scrolledComposite,  SWT.H_SCROLL | SWT.V_SCROLL);
        canvas.setBackground(SWTResourceManager.getColor(SWT.COLOR_DARK_YELLOW));
        scrolledComposite.setContent(canvas);
        scrolledComposite.setMinSize(canvas.computeSize(SWT.DEFAULT, SWT.DEFAULT));

        LightweightSystem lws = new LightweightSystem(canvas); 
        panel = new Figure(); 
        lws.setContents(panel);

        int starting_xpos= 0;
        int starting_ypos= 0;
        makeStructure(starting_xpos, starting_ypos, 0);


    }

    private void makeStructure(int starting_xpos, int starting_ypos, int index)
    {
        org.eclipse.draw2d.Label lblRoot= new org.eclipse.draw2d.Label();
        Rectangle rect= new Rectangle(starting_xpos, starting_ypos, 200, 25);
        //Anything longer than 200 cannot be displayed

        lblRoot.setText("BAAAAAAAAAAAB");

        lblRoot.setBorder(new SimpleRaisedBorder());
        lblRoot.setForegroundColor(ColorConstants.black);
        lblRoot.setVisible(true);
        lblRoot.setOpaque(true);
        lblRoot.setBounds(rect);

        panel.add(lblRoot);

         if (index<10)
            {
                makeStructure(starting_xpos+20, starting_ypos+50, index+1);
            }
        }


    }

Solution

  • Ok, I managed to get it working by using a FigureCanvas instead of a Canvas and by using a Viewport as the root element:

    public class Draw2d extends Dialog
    {
        protected Shell     shell;
        private Viewport    viewport;
    
        public static void main(String[] args)
        {
            Draw2d act = new Draw2d(new Shell(), SWT.DIALOG_TRIM | SWT.APPLICATION_MODAL);
            act.open();
        }
    
        public Draw2d(Shell parent, int style)
        {
            super(parent, style);
            setText("Draw2d");
        }
    
        public void open()
        {
            createContents();
            shell.open();
            shell.layout();
            Display display = getParent().getDisplay();
            while (!shell.isDisposed())
            {
                if (!display.readAndDispatch())
                {
                    display.sleep();
                }
            }
        }
    
        private void createContents()
        {
            shell = new Shell(getParent(), getStyle());
            shell.setSize(475, 375);
            shell.setText(getText());
            shell.setLayout(new GridLayout(1, false));
    
            FigureCanvas canvas = new FigureCanvas(shell, SWT.H_SCROLL | SWT.V_SCROLL);
            canvas.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_DARK_YELLOW));
            canvas.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
            canvas.setScrollBarVisibility(FigureCanvas.ALWAYS);
            viewport = new Viewport(true);
            canvas.setViewport(viewport);
    
            LightweightSystem lws = new LightweightSystem(canvas);
            lws.setContents(viewport);
    
            makeStructure(0, 0, 0);
        }
    
        private void makeStructure(int starting_xpos, int starting_ypos, int index)
        {
            org.eclipse.draw2d.Label lblRoot = new org.eclipse.draw2d.Label();
            Rectangle rect = new Rectangle(starting_xpos, starting_ypos, 210, 25);
    
            lblRoot.setText("BAAAAAAAAAAAB");
    
            lblRoot.setBorder(new SimpleRaisedBorder());
            lblRoot.setForegroundColor(ColorConstants.black);
            lblRoot.setVisible(true);
            lblRoot.setOpaque(true);
            lblRoot.setBounds(rect);
    
            viewport.add(lblRoot);
    
            if (index < 10)
            {
                makeStructure(starting_xpos + 20, starting_ypos + 50, index + 1);
            }
        }
    }
    

    Scrolling works just fine now.