Java SWT ScrolledComposite在32768像素后切断画布生成的图像

Java SWT ScrolledComposite在32768像素后切断画布生成的图像,java,canvas,swt,buffering,scrolledcomposite,Java,Canvas,Swt,Buffering,Scrolledcomposite,因此,我编写了一个程序,根据给定的“模型”,它会生成一个高度为50像素、长度约为84600像素的水平“时间线”条。每个像素代表一秒,因为它在24小时内以秒为单位模拟事件 问题是,在32768像素之后,该条被切断 我读过一些解决方案,比如使用ScrolledComposite只显示画布的一部分,并在滚动条通过缓冲拖动时显示新数据,但我对如何实现这一点并不熟悉 我看到的另一个解决方案是不使用ScrolledComposite,而只是使用canvas.scroll,如果运行了我的源代码(用于说明问题的

因此,我编写了一个程序,根据给定的“模型”,它会生成一个高度为50像素、长度约为84600像素的水平“时间线”条。每个像素代表一秒,因为它在24小时内以秒为单位模拟事件

问题是,在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();

}
}
包装画布;
导入org.eclipse.swt.swt;
导入org.eclipse.swt.events.PaintEvent;
导入org.eclipse.swt.events.PaintListener;
导入org.eclipse.swt.graphics.Image;
导入org.eclipse.swt.graphics.Point;
导入org.eclipse.swt.graphics.Rectangle;
导入org.eclipse.swt.layout.FillLayout;
导入org.eclipse.swt.widgets.Canvas;
导入org.eclipse.swt.widgets.Display;
导入org.eclipse.swt.widgets.ScrollBar;
导入org.eclipse.swt.widgets.Shell;
导入org.eclipse.swt.widgets.Listener;
导入org.eclipse.swt.widgets.Event;
公开课考试{
static int shellStyle=SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND | SWT.H_SCROLL;
静态int canvasStyle=SWT.NO_REDRAW_RESIZE;/| SWT.H|u SCROLL | SWT.V|u SCROLL;
公共静态void main(字符串[]args){
最终显示=新显示();
最终外壳=新外壳(显示,外壳样式);
setLayout(新的FillLayout());
shell.setBackground(display.getSystemColor((SWT.COLOR_青色));
shell.setText(“画布测试”);
图像;
最终画布=新画布(外壳、画布样式);
setLayout(新的FillLayout());
canvas.setBackground(display.getSystemColor(SWT.COLOR_-WHITE));
最终点原点=新点(0,0);
最终滚动条hBar=shell.getHorizontalBar();
矩形大小=canvas.getBounds();
hBar.setMaximum(大小、宽度);
hBar.setMinimum(0);
//为画布创建绘制处理程序
addPaintListener(新的PaintListener(){
公共无效油漆控制(油漆事件e){
//画画
e、 gc.setBackground(display.getSystemColor(SWT.COLOR_深_黄));
e、 gc.fillRectangle(100200100200);
e、 gc.setBackground(display.getSystemColor(SWT.COLOR_深色_青色));
e、 gc.fillRectangle(900200600200);
e、 gc.setBackground(display.getSystemColor(SWT.COLOR\u DARK\u洋红));
e、 gc.fillRectangle(500200300200);
e、 gc.setBackground(display.getSystemColor(SWT.COLOR_GRAY));
e、 gc.fillRectangle(1600、200、300、200);
}
});
//下面的事件处理程序允许水平滚动功能
hBar.addListener(SWT.Selection,new Listener()){
公共无效handleEvent(事件e){
int x=0;
int hSelection=hBar.getSelection();
int destX=-hSelection-origin.x;
矩形rect=shell.getBounds();
画布。滚动(destX,0,x,0,rect.width,rect.height,false);
origin.x=-hSelection;
x=destX;
}
});
addListener(SWT.Resize,new Listener()){
公共无效handleEvent(事件e){
矩形rect=canvas.getClientArea();
矩形客户端=shell.getClientArea();
hBar.setMaximum(矩形宽度);
setThumb(Math.min(rect.width,client.width));
int hPage=rect.width-client.width;
int hSelection=hBar.getSelection();
如果(hs选择>=hPage){
如果(hPage使用
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();

  }
}
import org.eclipse.swt.swt;
导入org.eclipse.swt.events.PaintEvent;
导入org.eclipse.swt.events.PaintListener;
导入org.eclipse.swt.graphics.Point;
导入org.eclipse.swt.graphics.Rectangle;
导入org.eclipse.swt.layout.FillLayout;
导入org.eclipse.swt.widgets.Canvas;
导入org.eclipse.swt.widgets.Display;
导入org.eclipse.swt.widgets.Event;
导入org.eclipse.swt.widgets.Listener;
导入org.eclipse.swt.widgets.ScrollBar;
导入org.eclipse.swt.widgets.Shell;
公开课考试{
静态int canvasStyle=SWT.NO_REDRAW|u RESIZE | SWT.H_SCROLL;/| SWT.V_SCROLL;
公共静态void main(字符串[]args){
最终显示=新显示();
最终外壳=新外壳(显示);
setLayout(新的FillLayout());
shell.setBackground(display.getSystemColor((SWT.COLOR_青色));
shell.setText(“画布测试”);
最终画布=新画布(外壳、画布样式);
setForeground(display.getSystemColor(SWT.COLOR_BLACK));
canvas.setBackground(display.getSystemColor(SWT.COLOR_-WHITE));
终点时间线尺寸=新点(84600,50);
最终点偏移=新点(0,0);
最终滚动条hBar=canvas.getHorizontalBar();
//为画布创建绘制处理程序
addPaintListener(新的PaintListener(){
公共无效油漆控制(油漆事件e){
对于(int x=100;x