2009-05-01 7 views
1

가장 안정적인 SWT 버전을 사용하고 있습니다.SWT 캔버스 위치

ToolBar, ScrolledComposite 및 Canvas가 포함 된 셸이 있습니다. 캔버스는 ScrolledComposite의 콘텐츠로 설정됩니다 (예 : scrolledComposite.setContent (canvas)). Canvas는 변경되지 않는 특정 크기 (예 : 400 x 400)로 생성됩니다. ScrolledComposite가 사용 가능한 상위 쉘 클라이언트 영역을 채우기 위해 끊임없이 증가하거나 축소되는 반면.

다음과 같은 시도를하는 부모 셸에 resize 리스너가 첨부되어 있습니다. a) 위에서 설명한대로 ScrolledComposite 크기를 늘리고 b) ScrolledComposite 내에서 Canvas를 가로 및 세로 가운데에 가운데에 배치합니다 (아래 예제 코드 참조).

이것은 Mac OS X에서와 똑같이 작동하지만 Windows에서는 크기 조정 이벤트가 발생하고 새 위치가 제대로 계산되지만 궁극적으로 Canvas는 다시 0,0으로 스냅합니다. 또 하나의 작은 정보는 창 크기를 지속적으로 조정하면 캔버스가 깜박 거리는 것을 볼 수 있으며 올바른 위치에 잠시 그려진 것처럼 보입니다.

_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); 
    } 
}); 

답변

1

당신은 이미 그것을 알아 냈어요,하지만 문제는 그것의 크기가 변경 될 때 ScrolledComposite 항상 0/0로 내용을 설정하는 것이 아닌 경우 확인합니다. 왜 당신의 접근 방식이 OS X에서 작동하는지 모르겠다. 나는 여기에 Mac이 없기 때문에 나의 예제를 테스트하지 않았다.

해결책은 ScrolledComposite의 클라이언트 영역보다 항상 크기가 큰 필러 합성을 사용하는 것입니다. 그 필러에서 캔버스를 올바르게 가운데에 맞출 수 있습니다.

는 SC의 클라이언트 영역이

(내가 먼저 귀하의 질문 :)라고 생각했기 때문에) 캔버스보다 작은 경우는 캔버스를 중심으로 추가 보너스로 난 작은 예를했습니다

,

당신은 약간의 조정을해야 할 수도 있습니다, 그 코드와 OS X에 몇 가지 결함이있는 것 같아요 ...

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(); 
      } 
     } 
    } 
}