스니펫:페이크 스크롤

위클립스
이동: 둘러보기, 찾기
스니펫 분류
스니펫 (3)
스니펫/JDT (1)
스니펫/PDE (3)
스니펫/SWT (7)

페이크 스크롤(Fake Scroll)은 운영체제가 직접 스크롤 하는 방식이 아닌, 스크롤을 개발자가 에뮬레이션 하는 것을 의미한다. Draw2D경량 UI 시스템에서는 실제 운영체제 컨트롤이 공간을 차지하고 있는 것이 아니기 때문에, 페이크 스크롤을 이용한다.

[편집] 결과

Fake-scroll-example.png

[편집] 소스

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
 
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
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.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell;
 
public class FakeScroll {
   private static class ImageCanvas extends Canvas {
      private Image image;
 
      public ImageCanvas(Composite parent) {
         super(parent, SWT.V_SCROLL | SWT.H_SCROLL | SWT.DOUBLE_BUFFERED);
 
         addListener(SWT.Paint, new Listener() {
            @Override
            public void handleEvent(Event event) {
               onPaint(event.gc);
            }
         });
 
         // 이미지 캔버스의 크기가 변경되면 스크롤바를 업데이트
         addListener(SWT.Resize, new Listener() {
            @Override
            public void handleEvent(Event event) {
               updateScrollBars();
            }
         });
 
         // 스크롤바가 이동되면 다시 그리기
         getHorizontalBar().addListener(SWT.Selection, new Listener() {
            @Override
            public void handleEvent(Event event) {
               redraw();
            }
         });
 
         getVerticalBar().addListener(SWT.Selection, new Listener() {
            @Override
            public void handleEvent(Event event) {
               redraw();
            }
         });
 
      }
 
      private void onPaint(GC gc) {
         if (image == null || image.isDisposed()) {
            return;
         }
         gc.setClipping(getClientArea());
         gc.drawImage(image, -getHorizontalBar().getSelection(), -getVerticalBar().getSelection());
      }
 
      private void updateScrollBars() {
         ScrollBar hBar = getHorizontalBar();
         ScrollBar vBar = getVerticalBar();
 
         if (image == null || image.isDisposed()) {
            hBar.setVisible(false);
            vBar.setVisible(false);
            return;
         }
 
         // 표시해야할 이미지의 크기
         Rectangle imageBounds = image != null ? image.getBounds() : new Rectangle(0, 0, 0, 0);
 
         // 표시에 사용할 수 있는 클라이언트 영역
         Rectangle clientArea = getClientArea();
 
         // 스크롤바 표시 여부 계산, 표시해야할 그림이 클라이언트 영역보다 넓으면 표시
         hBar.setVisible(imageBounds.width > clientArea.width);
         vBar.setVisible(imageBounds.height > clientArea.height);
 
         hBar.setMaximum(imageBounds.width);
         vBar.setMaximum(imageBounds.height);
 
         // 현재 표시중인 영역이 표시해야할 전체 영역에 대한 비율을 계산
         double hRatio = clientArea.width / (double) imageBounds.width;
         double vRatio = clientArea.height / (double) imageBounds.height;
 
         // 스크롤바의 썸 크기 업데이트
         hBar.setThumb((int) (hRatio * imageBounds.width));
         vBar.setThumb((int) (vRatio * imageBounds.height));
 
         // 스크롤바 빈영역 클릭시 10% 정도씩 이동하도록 지정
         hBar.setPageIncrement((int) (imageBounds.width * 0.1));
         vBar.setPageIncrement((int) (imageBounds.height * 0.1));
      }
 
      public void setImage(Image image) {
         if (this.image == image) {
            return;
         }
         this.image = image;
         updateScrollBars();
         redraw();
      }
   }
 
   public static void main(String[] args) throws MalformedURLException, IOException {
      Display display = Display.getDefault();
      Image image = new Image(display, new URL("http://eclipse.or.kr/images/0/01/Jeeeyul.jpg").openStream());
 
      Shell shell = new Shell(display);
      shell.setLayout(new FillLayout());
 
      ImageCanvas imageCanvas = new ImageCanvas(shell);
      imageCanvas.setImage(image);
 
      shell.setSize(500, 500);
      shell.open();
 
      while (!shell.isDisposed()) {
         if (!display.readAndDispatch()) {
            display.sleep();
         }
      }
      display.dispose();
   }
}
개인 도구
이름공간
변수
행위
포탈
탐색
도움
도구모음