我正在为SWT实现甘特图组件,这需要重新绘制一下(例如,图表的整个可见部分为200毫秒).
现在,当我滚动时,我只重新绘制剪切矩形所需的内容.当我快速滚动时,这使得应用程序看起来非常糟糕,因为滚动后仍然可见的部分似乎首先被OS移动,并且当我完成绘制剩余部分(滚动期间变得可见的部分)时,立即显示新的滚动步骤开始,将我的图表的一半移到右边,让我重新绘制另一半.这实际上看起来像我的图表在滚动期间在中间闪烁.
这看起来不太好.有办法解决这个问题吗?这个问题可以理解吗?
编辑:这是一个“小”测试程序,准确显示所描述的行为.您只需要在类路径中运行SWT即可运行它.
package de.ikoffice.gui; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.ScrolledComposite; import org.eclipse.swt.events.PaintEvent; import org.eclipse.swt.events.PaintListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Canvas; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; public class SlowRepaintProblem { public Color[] colors = new Color[501]; public SlowRepaintProblem() { Display display = Display.getDefault(); for( int i=0; i<=500; i++ ) { int r = ( i * 10 ) % 256; int g = ( i * 20 ) % 256; int b = ( i * 30 ) % 256; colors[i] = new Color(display,r,g,b); } Shell shell = new Shell(display); shell.setText("SlowRepaintTest"); ScrolledComposite comp = new ScrolledComposite(shell,SWT.H_SCROLL | SWT.V_SCROLL | SWT.DOUBLE_BUFFERED | SWT.NO_BACKGROUND); SlowRepaintingCanvas canvas = new SlowRepaintingCanvas(comp,SWT.NONE| SWT.NO_BACKGROUND); comp.setContent(canvas); canvas.setSize(5000,5000); // Layouting shell.setLayout(new GridLayout()); comp.setLayoutData(new GridData(GridData.FILL_BOTH)); shell.setBounds(50,50,800,600); // Showing the control shell.open(); while (!shell.isDisposed()) { try { if (!shell.getDisplay().readAndDispatch()) { shell.getDisplay().sleep(); } } catch (Throwable e) { String message = e.getMessage(); if( message == null || !e.getMessage().equals("Widget is diposed") ) { e.printStackTrace(); } break; } } } public static void main(String[] args) { new SlowRepaintProblem(); // Evil constructor call to start main program flow. } class SlowRepaintingCanvas extends Canvas { public SlowRepaintingCanvas(Composite parent,int style) { super(parent,style); addPaintListener(new PaintListener() { @Override public void paintControl(PaintEvent e) { GC gc = e.gc; Rectangle r = gc.getClipping(); gc.setAlpha(255); // gc.setBackground(ColorUtils.WHITE); // gc.fillRectangle(r); int x = r.x - (r.x % 10); int width = (r.width + r.x - x) - (r.width + r.x - x) % 10 + 10; int y = r.y - (r.y % 10); int height = (r.height + r.y - y) - (r.height + r.y - y) % 10 + 10; gc.setAlpha(128); for( int i = x; i < x+width; i+= 10 ) { gc.setBackground(colors[i/10]); gc.fillRectangle(i,r.y,10,r.height); } for( int j = y; j < y+height; j+= 10 ) { gc.setBackground(colors[j/10]); gc.fillRectangle(r.x,j,r.width,10); } } }); } } }