This approach presented two main challenges: first, I wanted to develop a clean algorithm for fading between any two colors so that the speed of the pulsing would be consistent regardless of colors, and 2nd, all the heavy duty work would need to be done in a separate thread from the GUI thread so I wouldn't freeze up the interface.
The following code creates a listener that, upon being notified of a Table Mouse double click event, starts a new thread that controls a pulsing background that fades between two colors:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.eclipse.core.runtime.IAdaptable; | |
import org.eclipse.swt.SWT; | |
import org.eclipse.swt.graphics.Color; | |
import org.eclipse.swt.widgets.Display; | |
import org.eclipse.swt.widgets.Event; | |
import org.eclipse.swt.widgets.Listener; | |
import org.eclipse.swt.widgets.Table; | |
import org.eclipse.swt.widgets.TableItem; | |
public class ContextPulsePaintListener implements Listener { | |
private PulseThread pulseThread = null; | |
public ContextPulsePaintListener() { | |
} | |
public void handleEvent(Event event) { | |
switch (event.type) { | |
case SWT.MouseDoubleClick: { | |
Table table = (Table) event.widget; | |
TableItem ti = table.getSelection()[0]; | |
if (pulseThread != null) { | |
pulseThread.endPulsing(); | |
} | |
pulseThread = new PulseThread(ti); | |
pulseThread.start(); | |
break; | |
} | |
} | |
} | |
class PulseThread extends Thread { | |
private int waitTime = 10; | |
boolean pulsing = false; | |
TableItem item = null; | |
private boolean fadeIn = false; | |
private final Color color1 = new Color(Display.getDefault(), 150, 255, 150); | |
private final Color color2 = new Color(Display.getDefault(), 240, 255, 240); | |
public PulseThread(TableItem item) { | |
this.item = item; | |
waitTime = getTime(waitTime); | |
} | |
private int getTime(int wait) { | |
wait = Math.max(waitTime, (2000 / Math.max(Math.abs(color1.getRed() - color2.getRed()), 1))); | |
wait = Math.max(waitTime, (2000 / Math.max(Math.abs(color1.getGreen() - color2.getGreen()), 1))); | |
wait = Math.max(waitTime, (2000 / Math.max(Math.abs(color1.getBlue() - color2.getBlue()), 1))); | |
return wait; | |
} | |
public TableItem getItem() { | |
return item; | |
} | |
public boolean isFadeIn() { | |
return fadeIn; | |
} | |
@Override | |
public void run() { | |
pulsing = true; | |
if (!item.isDisposed()) { | |
item.getDisplay().syncExec(new Runnable() { | |
public void run() { | |
item.setBackground(color1); | |
} | |
}); | |
} | |
while (pulsing && !item.isDisposed()) { | |
item.getDisplay().syncExec(new Runnable() { | |
public void run() { | |
if (!item.isDisposed()) { | |
Color color = item.getBackground(); | |
item.setBackground(makeNewColor(color)); | |
} | |
} | |
}); | |
waitFor(waitTime); | |
} | |
if (!item.isDisposed()) { | |
item.getDisplay().syncExec(new Runnable() { | |
public void run() { | |
item.setBackground(item.getParent().getBackground()); | |
} | |
}); | |
} | |
} | |
public void endPulsing() { | |
this.pulsing = false; | |
} | |
private Color makeNewColor(Color current) { | |
int redCurrent = current.getRed(); | |
int greenCurrent = current.getGreen(); | |
int blueCurrent = current.getBlue(); | |
Color target = fadeIn ? color1 : color2; | |
Color original = !fadeIn ? color1 : color2; | |
int redTarget = target.getRed(); | |
int greenTarget = target.getGreen(); | |
int blueTarget = target.getBlue(); | |
int redAdjuster = makeAdjuster(redTarget, original.getRed()); | |
int greenAdjuster = makeAdjuster(greenTarget, original.getGreen()); | |
int blueAdjuster = makeAdjuster(blueTarget, original.getBlue()); | |
int mult = 1; | |
if (fadeIn) { | |
if (redCurrent == redTarget && greenCurrent == greenTarget && blueCurrent == blueTarget) { | |
fadeIn = false; | |
} | |
} else { | |
if (redCurrent == redTarget && greenCurrent == greenTarget && blueCurrent == blueTarget) { | |
fadeIn = true; | |
} | |
} | |
int newRed = redCurrent; | |
int newGreen = greenCurrent; | |
int newBlue = blueCurrent; | |
if (redAdjuster != 0) { | |
newRed = redAdjuster > 0 ? Math.min(target.getRed(), redCurrent + (redAdjuster * mult)) : Math.max( | |
target.getRed(), redCurrent + (redAdjuster * mult)); | |
} | |
if (greenAdjuster != 0) { | |
newGreen = greenAdjuster > 0 ? Math.min(target.getGreen(), greenCurrent + (greenAdjuster * mult)) : Math | |
.max(target.getGreen(), greenCurrent + (greenAdjuster * mult)); | |
} | |
if (blueAdjuster != 0) { | |
newBlue = blueAdjuster > 0 ? Math.min(target.getBlue(), blueCurrent + (blueAdjuster * mult)) : Math | |
.max(target.getBlue(), blueCurrent + (blueAdjuster * mult)); | |
} | |
return new Color(current.getDevice(), newRed, newGreen, newBlue); | |
} | |
} | |
private int makeAdjuster(int target, int current) { | |
return target == current ? 0 : target > current ? 1 : -1; | |
} | |
public static void waitFor(long s) { | |
try { | |
Thread.sleep(s); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
} | |
} |
No comments:
Post a Comment