2012-02-08 15 views
3

因此,我編寫了一個程序,根據給定的「模型」生成水平「時間軸」條,高度爲50像素,長度約爲84600像素。每個像素代表一秒鐘,因爲它在24小時內以秒爲單位建模事件。SWT ScrolledComposite在32768像素之後切斷畫布生成的圖像

問題是,32768像素後,酒吧被切斷。

我讀過的解決方案,如使用ScrolledComposite只顯示畫布的一部分,使滾動時,而新的數據顯示爲滾動條通過緩衝拖動完成,但我不熟悉如何做到這一點所有。

我看到的另一個解決方案是沒有使用ScrolledComposite,但只是使用canvas.scroll,如果我的源代碼運行(測試程序來說明我的問題),問題很明顯,滾動條不滾動以允許整個畫布這個'解決方案'的測試程序如下所示。請幫忙!

package canvas; 

import org.eclipse.swt.SWT; 
import org.eclipse.swt.events.PaintEvent; 
import org.eclipse.swt.events.PaintListener; 
import org.eclipse.swt.graphics.Image; 
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.Display; 
import org.eclipse.swt.widgets.ScrollBar; 
import org.eclipse.swt.widgets.Shell; 
import org.eclipse.swt.widgets.Listener; 
import org.eclipse.swt.widgets.Event; 

public class Test { 
static int shellStyle = SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND | SWT.H_SCROLL; 
static int canvasStyle = SWT.NO_REDRAW_RESIZE;// | SWT.H_SCROLL | SWT.V_SCROLL; 

public static void main(String[] args) { 
    final Display display = new Display(); 
    final Shell shell = new Shell(display, shellStyle); 
    shell.setLayout(new FillLayout()); 
    shell.setBackground(display.getSystemColor((SWT.COLOR_CYAN))); 
    shell.setText("Canvas Test"); 
    Image image; 

    final Canvas canvas = new Canvas(shell, canvasStyle);  
    canvas.setLayout(new FillLayout()); 
    canvas.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); 

    final Point origin = new Point(0,0); 
    final ScrollBar hBar = shell.getHorizontalBar(); 
    Rectangle size = canvas.getBounds(); 
    hBar.setMaximum(size.width); 
    hBar.setMinimum(0); 

    // Create a paint handler for the canvas 
    canvas.addPaintListener(new PaintListener() { 
     public void paintControl(PaintEvent e) { 
     // Do some drawing 
      e.gc.setBackground(display.getSystemColor(SWT.COLOR_DARK_YELLOW)); 
      e.gc.fillRectangle(100, 200, 100, 200); 

      e.gc.setBackground(display.getSystemColor(SWT.COLOR_DARK_CYAN)); 
      e.gc.fillRectangle(900, 200, 600, 200); 

      e.gc.setBackground(display.getSystemColor(SWT.COLOR_DARK_MAGENTA)); 
      e.gc.fillRectangle(500, 200, 300, 200); 

      e.gc.setBackground(display.getSystemColor(SWT.COLOR_GRAY)); 
      e.gc.fillRectangle(1600, 200, 300, 200); 
     } 

    }); 

// The below event handlers allow for horizontal scrolling functionality 
    hBar.addListener(SWT.Selection, new Listener() { 
     public void handleEvent(Event e) { 
      int x = 0; 
      int hSelection = hBar.getSelection(); 
      int destX = -hSelection - origin.x; 
      Rectangle rect = shell.getBounds(); 
      canvas.scroll(destX, 0, x, 0, rect.width, rect.height, false); 
      origin.x = -hSelection;  
      x = destX; 
     } 

    }); 

    shell.addListener(SWT.Resize, new Listener() { 
     public void handleEvent(Event e) { 
      Rectangle rect = canvas.getClientArea(); 
      Rectangle client = shell.getClientArea(); 
      hBar.setMaximum(rect.width); 
      hBar.setThumb(Math.min(rect.width, client.width)); 
      int hPage = rect.width - client.width; 
      int hSelection = hBar.getSelection(); 
      if (hSelection >= hPage) { 
      if (hPage <= 0) 
       hSelection = 0; 
      origin.x = -hSelection; 
      } 
      shell.redraw(); 
     } 
     }); 

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

} 
} 

編輯:嘿謝謝p12t! 只是一個問題......這一行: final Point timelineSize = new Point(84600,50);

那麼這是否意味着每個x軸像素都有一個「點」,但是50個y軸像素向下?如: ++++++++++

。 。 。 。 。 。 。 。 。 。因此,每個「+符號」是水平x軸像素,並且84600'點'是如圖所示的50個y軸像素向下的'週期'。我的理解是否正確? (順便說一句,我上面顯示的例子是說明10分)

也在你看來,我做錯了什麼?或者我錯誤地實現了它。

回答

1

使用Canvas#scroll(..)絕對是最好的選擇。我修正了你的例子來繪製從0到84600的比例,所以它超過了32k的「物理」限制。

import org.eclipse.swt.SWT; 
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.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 Test { 
static int canvasStyle = SWT.NO_REDRAW_RESIZE | SWT.H_SCROLL; // | SWT.V_SCROLL; 

public static void main(String[] args) { 
    final Display display = new Display(); 
    final Shell shell = new Shell(display); 
    shell.setLayout(new FillLayout()); 
    shell.setBackground(display.getSystemColor((SWT.COLOR_CYAN))); 
    shell.setText("Canvas Test"); 

    final Canvas canvas = new Canvas(shell, canvasStyle);  
    canvas.setForeground(display.getSystemColor(SWT.COLOR_BLACK)); 
    canvas.setBackground(display.getSystemColor(SWT.COLOR_WHITE)); 

    final Point timelineSize = new Point(84600, 50); 
    final Point offset = new Point(0,0); 
    final ScrollBar hBar = canvas.getHorizontalBar(); 

    // Create a paint handler for the canvas 
    canvas.addPaintListener(new PaintListener() { 
     public void paintControl(PaintEvent e) { 
     for (int x = 100; x < timelineSize.x; x += 100) 
     { 
      e.gc.drawLine(x + offset.x, 0, x + offset.x, 20); 
      e.gc.drawText(Integer.toString(x), x + offset.x, 30, true); 
     } 
     } 
    }); 

// The below event handlers allow for horizontal scrolling functionality 
    hBar.addListener(SWT.Selection, new Listener() { 
     public void handleEvent(Event e) { 
      int hSelection = hBar.getSelection(); 
      int destX = -hSelection - offset.x; 
      canvas.scroll(destX, 0, 0, 0, timelineSize.x, timelineSize.y, false); 
      offset.x = -hSelection;  
     } 
    }); 

    canvas.addListener(SWT.Resize, new Listener() { 
     public void handleEvent(Event e) { 
      Rectangle client = canvas.getClientArea(); 
      hBar.setMaximum(timelineSize.x); 
      hBar.setThumb(Math.min(timelineSize.x, client.width)); 
      int hPage = timelineSize.y - client.width; 
      int hSelection = hBar.getSelection(); 
      if (hSelection >= hPage) { 
      if (hPage <= 0) 
       hSelection = 0; 
      offset.x = -hSelection; 
      } 
      shell.redraw(); 
     } 
     }); 

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

    } 
}