9 Stimmen

Blinkende Hintergrundzeilen von TableViewer oder TreeViewer in SWT

Ich brauche die Möglichkeit, einen blinkenden (rot, vielleicht mehr Farben) Hintergrund für Zeilen in einem TableViewer/TreeViewer zu haben. Was sind die besten Optionen?

Es kann mehr als eine Zeile blinken, die blinkende MUSS synchron sein und ich brauche zwei Blinkmodi, schnell und langsam.

4voto

Kire Haglin Punkte 5892

Ich würde etwas Ähnliches machen. Aktualisieren Sie die Elemente, für die Sie die Farben ändern müssen, in regelmäßigen Abständen. Bei jeder Aktualisierung schalten Sie die Farben um, je nachdem, wie Sie sie blinken lassen möchten.

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)
    }
  });
}  

und der Etikettenanbieter muss IColorProvider implementieren.

1voto

zedoo Punkte 9933

Hallo, dies ist ein schneller Hack, der die Idee zeigt, die auf viele Arten verbessert werden kann. Ich zeige die drei Klassen, die den Job machen. Wenn Sie möchten, kann ich Ihnen ein exportiertes Plugin zur Verfügung stellen, das Sie morgen in Ihre Eclipse Workbench einbauen können. Hier sind die Kernklassen:

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;
        }

}

Dies ist ein Beispiel für eine Modellklasse. Der Blink-Status wird innerhalb des Objekts gespeichert, aber Sie könnten dies durch die Verwendung einer Art von Adapter verbessern wollen:

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),
    };

}

Und schließlich ein TableViewer, der in eine Ansicht eingebettet ist und die beiden oben genannten Elemente verwendet:

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();
    }
}

0voto

Paul Lammertsma Punkte 36529

Sie sollten eine Konstruktion haben, die in etwa so aussieht:

LinkedList<Row> rows = new LinkedList<Row>();
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);
    }
}

Wenn die Shell anzeigt, sollte sie start() . Wenn es sich entledigt, rufen Sie stop() .

Beachten Sie, dass ich dies nicht wirklich getestet habe; es handelt sich um einen Java-Pseudocode. Wenn Sie die Zeilenfarbe nicht mit dem vorgeschlagenen setForegroundColor() könnten Sie vielleicht ein Widget einführen und eine paint() Veranstaltung.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X