Now that my Interactive Color Wheel program/applet is in Swing, I guess I should continue my previous thread in here from the AWT forum ("list widget with different colors for each list item?"):
*
1557347
My current issue involves two canvas (well, JPanel) refresh issues likely linked to double buffering. You can see them by running the following file with "java -jar SIHwheel.jar":
* http://r0k.us/rock/Junk/SIHwheel.jar
[edit add]
(Heh, I just noticed Firefox and Chrome under Windows 7 will allow you to run thie .jar directly from the link. Cool.)
[edit]
If you don't trust me and would rather run it as an applet, use:
* http://r0k.us/rock/Junk/SIHwheel.html
(For some reason the first issue doesn't manifest when running as applet.)
1) The canvas goes "wonky-white" when the user first clicks on the wheel. What is supposed to happen is simply the user sees another dot on the wheel for his new selected color. Forcing a complete redraw via any of the GUI buttons at the bottom sets things right. The canvas behaves itself from then on, at least until minimized or resized, at which point one needs to click a GUI button again. I'll be disabling resizing, but minimizing will still be allowed.
2) A button image, and sometimes toolTip text, from an entirely different JPanel will appear in the ULC (0,0) of my canvas.
Upon first running the new Swing version, I had thought everything was perfect. I soon realized though that my old AWT update() method was never getting called. The desired case when the user clicks somewhere on the wheel is that a new dot appears on his selected color. This usually allows them to see what colors have been viewed before. The old paint(), and now paintComponent(), clear the canvas, erasing all the previous dots.
I soon learned that Swing does not call update(). I had been using it to intercept refresh events where only one of the components on my canvas needing updating. Most usefully, don't redraw the wheel (and forget the dots) when you don't need to. The way I chose to handle this is to slightly modify the update() to a boolean method. I renamed it partialOnly() and call it
at the beginning of paintComponent(). If it returns true, paintComponent() itself returns, and no clearing of the canvas occurs.
Since I first posted about these two issues, I've kludged-in a fix to #1. (The linked .jar file does not contain this kludge, so you can see the issue.) The kludge is included in the following code snippet:
public void paintComponent(Graphics g)
{
Rectangle ulc;
if (font == null) defineFont(g);
// handle partial repaints of specific items
if (partialOnly(g)) return;
... // follow with the normal, full-canvas refresh
}
private boolean partialOnly(Graphics g)
{
boolean imDone = true;
if (resized > 0) // this "if { }" clause is my kludge
{ // should enter on 1 or 2
imDone = false;
resized += 1; // clock thru two forced-full paints
if (resized > 2) resized = 0;
}
if (wedgeOnly)
{
putDotOnWheel(g);
paintWedge(g);
drawSnake(g);
drawSatSnake(g);
updateLumaBars(g);
wedgeOnly = false;
}
else if (wheelOnly)
{
...
wheelOnly = false;
}
...
else
imDone = false; // was paint() when method was update() in the AWT version
return(imDone);
}
Forcing two initial full paintComponent()s does whatever magic the double-buffering infrastructure needs to avoid the "wonky-white" problem. This also happens on a minimize; I've disabled resizing other than minimization. Even though it works, I consider it a kludge.
The second issue is not solved. All I can figure is that the double buffers are shared between the two JPanels, and the artifact buttons and toolTips at (0,0) are the result. I tried simply clearing the top twenty lines of the canvas when partialOnly() returns true, but for some reason that causes other canvas artifacting further down. And that was just a second kludge anyway.
Sorry for being so long-winded. What is the right way to avoid these problems?
-- Rich
Edited by: RichF on Oct 15, 2010 8:43 PM