SWT flicker?

lumo

Top Contributor
so weit ich weiss, sind alle SWT komponenten doublebuffered (falsch?)
ich hab nen canvas geschrieben, der nen text scrollt (horizontal)
mir kommt vor dass das teil flackert.

hier mal der code... wäre super wenn jemand das ansehen könnte um mir zu sagen ob ich mir das einbilde oder nicht...
und, wenns flackert, hat jemand ne idee wie ich das umgehe (double buffern... mach ich doch schon?)
Code:
package scrolling;

import org.eclipse.swt.SWT;

public class SideScroller extends Canvas implements PaintListener {

	Image originalImage = null;

	private String text = "default text";
	private boolean isDirty = false;

	protected int scrollWidth = 0;
	protected int currentPos = -1;
	protected SideScrollerTimer timer;

	/**
	 * Create the composite.
	 * 
	 * @param parent
	 * @param style
	 */
	public SideScroller(Composite parent, int style) {
		super(parent, SWT.NO_BACKGROUND);
		timer = new SideScrollerTimer(this);
		addPaintListener(this);
		addControlListener(new ControlListener() {

			@Override
			public void controlResized(ControlEvent e) {
				isDirty = true;
			}

			@Override
			public void controlMoved(ControlEvent e) {
			}
		});
	}

	@Override
	protected void checkSubclass() {
		// Disable the check that prevents subclassing of SWT components
	}

	@Override
	public void paintControl(PaintEvent e) {
		paint(e);
	}

	public void setText(String aText) {
		text = aText;
		isDirty = true;
	}

	protected void increasePos() {
		currentPos++;
		currentPos = currentPos % getSize().x;
		redraw();
	}

	private void paint(PaintEvent e) {
		if (currentPos < 0) {
			currentPos = getSize().x;
		}

		if (originalImage == null || isDirty) {
			originalImage = new Image(Display.getCurrent(), getClientArea());
			GC buffer = new GC(originalImage);
			int fontHeight = buffer.getFontMetrics().getHeight();

			buffer.setBackground(getParent().getBackground());
			buffer.fillRectangle(getClientArea());
			buffer.setFont(getFont());
			buffer.setForeground(getParent().getForeground());
			buffer.drawString(text, 0,
					(getClientArea().height - fontHeight) / 2, true);
			isDirty = false;
		}
		try {
			GC gc = e.gc;
			Image imgBuffer2 = new Image(Display.getCurrent(), getClientArea());
			GC buffer2 = new GC(imgBuffer2);

			buffer2.drawImage(originalImage, 0, 0, currentPos,
					getClientArea().height, getSize().x - currentPos, 0,
					currentPos, getClientArea().height);

			buffer2.drawImage(originalImage, currentPos, 0, getSize().x
					- currentPos, getClientArea().height, 0, 0, getSize().x
					- currentPos, getClientArea().height);
			buffer2.dispose();
			gc.drawImage(imgBuffer2, 0, 0);
			imgBuffer2.dispose();
			gc.dispose();
		} catch (Exception ex) {
			// System.err.println("SideScroller made a pooh!");
		}
	}

	protected class SideScrollerTimer implements Runnable {

		protected int time;
		protected SideScroller scroller;
		protected Boolean stop = false;

		public SideScrollerTimer(SideScroller aScroller) {
			scroller = aScroller;
			setFPS(60); // default is 60 FPS
			scroller.getDisplay().timerExec(time, this);
		}

		public void setFPS(int FPS) {
			time = 1000 / FPS;
		}

		public void run() {
			if (!stop) {
				scroller.increasePos();
				scroller.getDisplay().timerExec(time, this);
			}
		}

		public void stop() {
			stop = true;
			Thread.currentThread().interrupt();
		}
	}

	public void dispose() {
		originalImage.dispose();
		timer.stop();
		super.dispose();
	}
}

hier noch der code zum testen der component
Code:
package scrolling;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

public class ScrollerTest {

	protected Shell shell;
	private SideScroller text;

	/**
	 * Launch the application.
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			ScrollerTest window = new ScrollerTest();
			window.open();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Open the window.
	 */
	public void open() {
		Display display = Display.getDefault();
		createContents();
		shell.open();
		shell.layout();
		while (!shell.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
	}

	/**
	 * Create contents of the window.
	 */
	protected void createContents() {
		shell = new Shell();
		shell.setSize(450, 300);
		shell.setText("SWT Application");
		shell.setLayout(new GridLayout(1, false));
		
		Label lblThisIsA = new Label(shell, SWT.NONE);
		lblThisIsA.setText("this is a scrolling sample test");
		
		text = new SideScroller(shell, SWT.NONE);
		text.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
		
		Label lblTheScrollerIs = new Label(shell, SWT.NONE);
		lblTheScrollerIs.setLayoutData(new GridData(SWT.LEFT, SWT.FILL, false, true, 1, 1));
		lblTheScrollerIs.setText("the scroller is above!");

	}

}
 
Zuletzt bearbeitet:

Wildcard

Top Contributor
Warum willst du eine eigene Scroll Logik implementieren? Was fehlt dir denn?
Dieses Ding hat übrigens massive Memory Leaks weil du die Images und GCs die du erstellst nicht mehr disposed.
 

lumo

Top Contributor
nop, das ist was anderes.

NOTE: hab oben ein paar dispose eingefüht, also sollte der speicher jetzt sauber sein (falls du hnoch was siehst, bitte aufzeigen)

mein sidescroller scrollt text von rechts nach links (sowas wie ein news ticker auf diversen websites...)

also nichts mit scrollbars... :)
 

Neue Themen


Oben