在SWT中闪烁TableViewer或TreeViewer的背景行

我需要能够在TableViewer / TreeViewer中为行提供闪烁(红色,可能更多颜色)背景。 什么是最好的选择?

可能有多个行闪烁,闪烁必须是同步的,我需要两个闪烁模式,快速和慢速。

我会做类似的事情。 更新定期更改颜色所需的元素。 在每次更新时,根据您希望它们的闪烁方式切换颜色。

void scheduleColorChange(final Color colors[], final int startIndex, final int changeInterval) { getDisplay().timerExec(changeInterval, new Runnable() { public void run() { Object[] elements = getColorChangingElements(); setColorsForFlashingElements(elements, colors[index%colors.length]); getViewer().update(elements); scheduleColorChange(colors, startIndex+1, changeInterval) } }); } 

并且你有标签提供者实现IColorProvider。

你好,这是一个快速的黑客,它表明了这个想法,在很多方面都是可以改进的。 我展示了完成这项工作的三个class级。 如果你愿意,我可以提供一个导出的源代码插件,准备明天安装到你的eclipse工作台。 以下是核心课程:

 import java.util.TimerTask; import org.eclipse.jface.resource.ColorDescriptor; import org.eclipse.jface.viewers.IColorProvider; import org.eclipse.jface.viewers.ITableLabelProvider; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.RGB; import org.eclipse.ui.PlatformUI; public class Blinker extends LabelProvider implements ITableLabelProvider, IColorProvider { private final TableViewer viewer; public Blinker(TableViewer viewer){ this.viewer = viewer; } // this is just a lousy way to store blink_on/blink_off... private byte state; // there must be a better way to get a color... final static Color red = ColorDescriptor.createFrom(new RGB(255,0,0)).createColor(PlatformUI.getWorkbench().getDisplay()); final static Color green = ColorDescriptor.createFrom(new RGB(0,255,0)).createColor(PlatformUI.getWorkbench().getDisplay()); private final TimerTask task = new TimerTask(){ @Override public void run() { state++; PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable(){ public void run() { viewer.refresh(); } }); } }; private Timer t; synchronized byte getState(){ return state; } @Override public Image getColumnImage(Object element, int columnIndex) { return null; } @Override public String getColumnText(Object element, int columnIndex) { return ((Element) element).text; } @Override public Color getBackground(Object object) { Element element = (Element) object; if (element.isBlinking()){ return getState() % 2 == 0 ? Blinker.red : Blinker.green; } else { return Blinker.green; } } @Override public Color getForeground(Object element) { return null; } public void start() { t = new Timer(); t.schedule(task, 200, 1000); } public void stop() { t.cancel(); t = null; } } 

这是一个示例模型类。 闪烁状态存储在对象中,但您可能希望通过使用某种适配器来改进它:

 package com.example.blinker; public class Element { private boolean blinking; public final String text; public Element(String string, boolean b) { this.text = string; this.blinking = b; } public synchronized boolean isBlinking(){ return blinking; } public synchronized void setBlinking(boolean b){ this.blinking = b; } public static final Element[] sampledata = new Element[] { new Element("Merkur", false), new Element("Venus", true), new Element("Erde", false), new Element("Mars", true), new Element("Jupiter", false), new Element("Saturn", true), new Element("Uranus", false), new Element("Neptun", true), new Element("Pluto", false), }; } 

最后将一个TableViewer嵌入到View中,利用上面两个:

 package com.example.blinker.views; import org.eclipse.jface.viewers.IStructuredContentProvider; import org.eclipse.jface.viewers.TableViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.ui.part.ViewPart; import com.example.blinker.Blinker; import com.example.blinker.Element; public class SampleView extends ViewPart { public static final String ID = "com.example.blinker.views.SampleView"; private TableViewer viewer; private Blinker blinker; class ViewContentProvider implements IStructuredContentProvider { public void inputChanged(Viewer v, Object oldInput, Object newInput) {} public void dispose() {} public Object[] getElements(Object parent) { return Element.sampledata; } } public void createPartControl(Composite parent) { viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); viewer.setContentProvider(new ViewContentProvider()); blinker = new Blinker(viewer); viewer.setLabelProvider(blinker); viewer.setInput(new Object()); blinker.start(); } public void setFocus() { viewer.getControl().setFocus(); } public void dispose() { blinker.stop(); } } 

你应该有一个像这样的结构:

 LinkedList rows = new LinkedList(); Thread blinker = null; public void start() { blinker = new Thread() { public void run() { while(!this.interrupted()) { try { synchronized (rows) { for (Row row : rows) { row.setForegroundColor(color1); } } Thread.sleep(500); synchronized (rows) { for (Row row : rows) { row.setForegroundColor(color2); } } Thread.sleep(500); } catch (InterruptException e) { break; } } } }; blinker.start(); } public void stop() { if (blinker != null) { blinker.interrupt(); } } public void add(Row row) { synchronized (rows) { if (!rows.contains(row)) { rows.add(row); } } } public void remove(Row row) { synchronized (rows) { rows.remove(row); } } 

Shell显示时,它应该调用start() 。 处理时,调用stop()

请注意,我实际上没有测试过这个; 这是一些Javaish伪代码。 如果你不能使用上面建议的setForegroundColor()设置行颜色,你可以引入一个小部件并定义一个paint()事件。