【问题标题】:SWT ScrolledComposite cuts off canvas generated images after 32768 pixelsSWT ScrolledComposite 在 32768 像素后切断画布生成的图像
【发布时间】:2012-02-08 01:38:06
【问题描述】:

所以我编写了一个程序,它根据给定的“模型”生成一个水平“时间线”条,高度为 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();

}
}

编辑:嘿,谢谢 p12t! 只是一个问题......这一行: 最终点timelineSize = new Point(84600, 50);

这是否意味着每个 x 轴像素都有一个“点”,但向下 50 个 y 轴像素?如: ++++++++++

。 . . . . . . . . .

因此,每个“+ 号”是一个水平 x 轴像素,84600 个“点”是“周期”,如下所示 50 个 y 轴像素。我对此的理解正确吗? (顺便说一下,我上面显示的示例说明了 10 个点)

您还认为我做错了什么?或者我错误地实现了它..

【问题讨论】:

    标签: java canvas swt buffering scrolledcomposite


    【解决方案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();
    
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-22
      • 2018-06-30
      • 2019-09-19
      • 2013-06-07
      • 1970-01-01
      相关资源
      最近更新 更多