SWT ScrolledComposite отрязва изображения, генерирани от платно след 32768 пиксела

Затова написах програма, която в зависимост от даден „модел“ генерира хоризонтална лента „времева линия“ с височина 50 пиксела и дължина приблизително 84 600 пиксела. Всеки пиксел представлява секунда, тъй като моделира събития в секунди за период от 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! Само въпрос...този ред: final Point timelineSize = new Point(84600, 50);

Това означава ли, че има "Точка" за всеки пиксел по оста x, но 50 пиксела по оста y надолу? Като например: ++++++++++

. . . . . . . . . .

Така че всеки „знак +“ е хоризонтален пиксел по оста x, а 84600 „точки“ са „периодите“, както е показано 50 пиксела по оста y надолу. Моето разбиране за това правилно ли е? (BTW примерът, който показах по-горе, илюстрира 10 точки)

Също според вас какво съм направил грешно? Или съм го внедрил грешно..


person JackSparrow123    schedule 08.02.2012    source източник


Отговори (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();

  }
}
person p12t    schedule 08.02.2012