3 TrakEM2 plugin for ImageJ(C).
4 Copyright (C) 2007-2009 Albert Cardona and Rodney Douglas.
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License
8 as published by the Free Software Foundation (http://www.gnu.org/licenses/gpl.txt )
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 You may contact Albert Cardona at acardona at ini.phys.ethz.ch
20 Institute of Neuroinformatics, University of Zurich / ETH, Switzerland.
23 package ini
.trakem2
.display
;
25 import ini
.trakem2
.utils
.CachingThread
;
27 import java
.awt
.Component
;
28 import java
.awt
.Rectangle
;
29 import java
.util
.LinkedList
;
31 public abstract class AbstractRepaintThread
extends CachingThread
{
33 final protected AbstractOffscreenThread off
;
34 private final java
.util
.List
<PaintEvent
> events
= new LinkedList
<PaintEvent
>();
35 private final Component target
;
37 public AbstractRepaintThread(final Component target
, final String name
, final AbstractOffscreenThread off
) {
41 setPriority(Thread
.NORM_PRIORITY
+ 1);
42 try { setDaemon(true); } catch (Exception e
) { e
.printStackTrace(); }
46 private class PaintEvent
{
47 final Rectangle clipRect
;
48 final boolean update_graphics
;
49 PaintEvent(final Rectangle clipRect
, final boolean update_graphics
) {
50 this.clipRect
= clipRect
;
51 this.update_graphics
= update_graphics
; // java is sooo verbose... this class is just a tuple!
55 /** Queue a new request for painting, updating offscreen graphics. */
56 public final void paint(final Rectangle clipRect
) {
57 paint(clipRect
, true);
60 /** Queue a new request for painting. */
61 public void paint(final Rectangle clipRect
, final boolean update_graphics
) {
62 //Utils.log2("update_graphics: " + update_graphics);
63 //Utils.printCaller(this, 5);
64 // queue the event and signal a repaint request
65 synchronized (events
) {
66 events
.add(new PaintEvent(clipRect
, update_graphics
));
71 /** Will gracefully kill this thread by breaking its infinite wait-for-event loop, and also call cancel on all registered offscreen threads. */
75 synchronized (events
) {
83 while (!isInterrupted()) {
85 // wait until anyone issues a repaint event
86 synchronized (events
) {
87 while (0 == events
.size()) {
88 if (isInterrupted()) return;
89 try { events
.wait(); } catch (InterruptedException ie
) {}
93 if (isInterrupted()) {
97 // wait a bit to catch fast subsequent events
99 try { Thread
.sleep(10); } catch (InterruptedException ie
) {}
101 // obtain all events up to now and clear the event queue
102 final PaintEvent
[] pe
;
103 synchronized (events
) {
104 pe
= new PaintEvent
[events
.size()];
108 if (0 == pe
.length
) {
112 // obtain repaint parameters from merged events
113 Rectangle clipRect
= pe
[0].clipRect
;
114 boolean update_graphics
= pe
[0].update_graphics
;
115 for (int i
=1; i
<pe
.length
; i
++) {
116 if (null != clipRect
) {
117 if (null == pe
[i
].clipRect
) clipRect
= null; // all
118 else clipRect
.add(pe
[i
].clipRect
);
119 } // else 'null' clipRect means repaint the entire canvas
120 if (!update_graphics
) update_graphics
= pe
[i
].update_graphics
;
121 else if (null == clipRect
) break;
124 // issue an offscreen thread if necessary
125 if (update_graphics
) {
126 handleUpdateGraphics(target
, clipRect
);
131 if (null == clipRect) target.repaint(0, 0, 0, target.getWidth(), target.getHeight()); // using super.repaint() causes infinite thread loops in the IBM-1.4.2-ppc
132 else target.repaint(0, clipRect.x, clipRect.y, clipRect.width, clipRect.height);
135 // Crazy idea: paint NOW
136 final java
.awt
.Graphics g
= target
.getGraphics();
138 // Ensure full clip rect
139 g
.setClip(0, 0, target
.getWidth(), target
.getHeight());
143 } catch (Throwable t
) {
149 /** Child classes need to extend this method for handling the need of recreating offscreen images. */
150 abstract protected void handleUpdateGraphics(Component target
, Rectangle clipRect
);
152 /** Waits until the offscreen thread is finished with the current cycle. */
153 public void waitForOffs() {
154 off
.waitOnRepaintCycle();