2009-05-01 17 views
1

Ich verwende die neueste stabile Version von SWT.SWT Canvas Location

Ich habe eine Shell mit einer ToolBar, einem ScrolledComposite und einem Canvas. Der Canvas-Bereich wird als Inhalt des ScrolledComposites festgelegt (z. B. scrolledComposite.setContent (Canvas)). Der Canvas wird mit einer bestimmten Größe erstellt, die sich niemals ändert (z. B. 400 x 400). Während der ScrolledComposite ständig wächst oder schrumpft, um den Clientbereich der verfügbaren Shell zu füllen.

Ich habe ein Resize-Listener an die übergeordnete Shell, die Folgendes zu tun versucht: a) vergrößern Sie die ScrolledComposite wie oben beschrieben und b) Center Canvas sowohl horizontal als auch vertikal innerhalb der ScrolledComposite (siehe unten zum Beispiel Code).

Dies funktioniert genau so, wie es unter Mac OS X sein sollte, aber unter Windows wird das Resize-Ereignis ausgelöst und die neuen Positionen werden korrekt berechnet, aber letztendlich springt die Canvas auf 0,0 zurück. Eine weitere kleine Information ist, dass Sie, wenn Sie die Größe des Fensters kontinuierlich ändern, sehen, dass die Arbeitsfläche flackert und es aussieht, als ob sie an der richtigen Stelle kurz gezeichnet wird.

_shell.addListener (SWT.Resize, new Listener() { 
    public void handleEvent (Event e) 
    { 
     int toolBarOffset = _toolBar.getSize().y; 

     Rectangle clientArea = _shell.getClientArea(); 

     _scrollComposite.setBounds(0, toolBarOffset, clientArea.width, clientArea.height - toolBarOffset); 

     Point canvasSize = _canvas.getSize(); 

     int canvasX = Math.max(0, (clientArea.width/2) - (canvasSize.x/2)); 
     int canvasY = Math.max(0, ((clientArea.height - toolBarOffset)/2) - (canvasSize.y/2)); 

     _canvas.setLocation(canvasX, canvasY); 
    } 
}); 

Antwort

1

Nicht sicher, ob Sie es schon herausgefunden haben, aber das Problem ist, dass die ScrolledComposite immer um den Inhalt zu 0/0 setzt, wenn es geändert wird. Ich bin mir nicht sicher, warum Ihr Ansatz unter OS X funktioniert, und ich habe mein Beispiel nicht getestet, da ich hier keinen Mac habe.

Die Lösung besteht darin, ein Füller-Composite zu verwenden, das immer mindestens so groß ist wie der Client-Bereich des ScrolledComposite. In diesem Füller können Sie den Canvas korrekt zentrieren.

ich ein kleines Beispiel gemacht haben, als zusätzlichen Bonus auch sie die Leinwand zentriert, wenn der Client-Bereich des SC kleiner als die Leinwand ist (weil ich zuerst gedacht habe, dass Ihre Frage :) war)

Sie müssen möglicherweise einige kleinere Anpassungen vornehmen, ich denke, es gibt einige Störungen auf OS X mit diesem Code ...

package test; 

import org.eclipse.swt.SWT; 
import org.eclipse.swt.custom.ScrolledComposite; 
import org.eclipse.swt.events.ControlAdapter; 
import org.eclipse.swt.events.ControlEvent; 
import org.eclipse.swt.events.PaintEvent; 
import org.eclipse.swt.events.PaintListener; 
import org.eclipse.swt.graphics.Point; 
import org.eclipse.swt.graphics.Rectangle; 
import org.eclipse.swt.layout.FillLayout; 
import org.eclipse.swt.widgets.Canvas; 
import org.eclipse.swt.widgets.Composite; 

import org.eclipse.swt.widgets.Display; 
import org.eclipse.swt.widgets.Shell; 

public class Test { 

    public static void main(final String[] args) { 
     final Display display = new Display(); 
     final Shell shell = new Shell(display); 

     shell.setLayout(new FillLayout()); 

     final ScrolledComposite sComp = new ScrolledComposite(shell, SWT.H_SCROLL | SWT.V_SCROLL); 
     final Composite fillComp = new Composite(sComp, SWT.NONE); 

     sComp.setLayout(new FillLayout()); 

     final Canvas c = new Canvas(fillComp, SWT.DOUBLE_BUFFERED); 
     c.addPaintListener(new PaintListener() { 
      public void paintControl(PaintEvent e) { 
       Point p = c.getSize(); 
       e.gc.setBackground(display.getSystemColor(SWT.COLOR_RED)); 
       e.gc.fillRectangle(0, 0, p.x, p.y); 

       e.gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE)); 
       e.gc.fillRectangle(p.x/2 - 10, p.y/2 - 10, 20, 20); 
      } 
     }); 

     c.setSize(400, 400); 
     sComp.setContent(fillComp); 

     sComp.addControlListener(new ControlAdapter() { 
      @Override 
      public void controlResized(ControlEvent e) { 
       Rectangle clientArea = sComp.getClientArea(); 

       Point cSize = c.getSize(); 
       int fillX = Math.max(clientArea.width, cSize.x); 
       int fillY = Math.max(clientArea.height, cSize.y); 
       fillComp.setSize(fillX, fillY); 

       int cX = (clientArea.width - cSize.x)/2; 
       int cY = (clientArea.height - cSize.y)/2; 

       sComp.setOrigin(-cX, -cY); 

       int locX = Math.max(cX, 0); 
       int locY = Math.max(cY, 0); 
       c.setLocation(locX, locY); 
      } 
     }); 

     shell.open(); 
     shell.pack(); 
     while (!shell.isDisposed()) { 
      if (!display.readAndDispatch()) { 
       display.sleep(); 
      } 
     } 
    } 
}