<br><font size=2 face="sans-serif">John,</font>
<br>
<br><font size=2 face="sans-serif">I had this problem too with vtkPanel using multiple instances in a Swing MDI. The way I got around it was to create a new set of swing classes for JInternalFrame, JDesktopPane (which is a layered pane), JMenu etc so that I could have the vtkPanel sat on a dialog owned by the desktopframe to keep it on top, synchronised to the position of JPanel sat on the JInternalFrame (so it looked like it was on the Panel), and wrote a function in the desktopPane to check for overlaps with other windows. Whenever my vtkPanel should be partly covered by a swingcomponent I hide the dialog with the vtkPanel on it and display a message on the JPanel underneath instead. Its not perfect but it looks pretty good for the majority of the time and certainly looks a lot better than drawing through the lightweight components.</font>
<br>
<br><font size=2 face="sans-serif">Rich</font>
<br>
<br>
<br>
<br>
<br>
<br>
<table width=100%>
<tr valign=top>
<td>
<td><font size=1 face="sans-serif"><b>Jeff Lee &lt;jeff@cdnorthamerica.com&gt;</b></font>
<br><font size=1 face="sans-serif">Sent by: </font>
<br><font size=1 face="sans-serif">vtkusers-admin@public.kitware.com</font>
<p><font size=1 face="sans-serif">08/05/2003 09:01 AST</font>
<br>
<td><font size=1 face="Arial">&nbsp; &nbsp; &nbsp; &nbsp; </font>
<br><font size=1 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; To: &nbsp; &nbsp; &nbsp; &nbsp;John Biddiscombe &lt;john.biddiscombe@mirada-solutions.com&gt;</font>
<br><font size=1 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; cc: &nbsp; &nbsp; &nbsp; &nbsp;vtkusers@public.kitware.com</font>
<br><font size=1 face="sans-serif">&nbsp; &nbsp; &nbsp; &nbsp; Subject: &nbsp; &nbsp; &nbsp; &nbsp;Re: [vtkusers] vtk + JAVA Swing</font></table>
<br>
<br>
<br><font size=2><tt>Hi John,<br>
Here is a modified vtkPanel which shows a popup menu when invoked with<br>
&lt;SHIFT&gt;-MB1. &nbsp;You can diff this vtkPanel against cvs to see what I<br>
added, but it is pretty straightforward. &nbsp;I quoted our previous message<br>
for the mailing list.<br>
</tt></font>
<br><font size=2><tt>John Biddiscombe wrote:<br>
</tt></font>
<br><font size=2><tt>&gt; Does anyone know if the JAVA vtkPanel control can be made to work by<br>
&gt; deriving it from a JComponent rather than a Canvas class.<br>
</tt></font>
<br>
<br><font size=2><tt>There are ways to do this that would involve sacrifice of hardware<br>
acceleration - basically replacing the native render window with an<br>
image of the render window contents. &nbsp;Interaction will be slow, and you<br>
would need to render offscreen. &nbsp;A compromise might be to only do this<br>
when the user tries to invoke a widget which will be displayed on top of<br>
the render window.<br>
</tt></font>
<br><font size=2><tt>&gt; I want to put the panel into a JLayeredPane and place other<br>
&gt; (lightweight) controls over the top.<br>
</tt></font>
<br>
<br><font size=2><tt>a render window inside a JComponent will always be on-top, except for<br>
the case where JPopupMenu.setLightWeightPopupEnabled(false) is called,<br>
which allows menus/popups to be displayed as heavyweight, thus obeying<br>
z-order when displayed atop another heavyweight component (see modified<br>
vtkPanel). &nbsp;What types of controls do you intend to use? -Jeff<br>
</tt></font>
<br><font size=2><tt>&gt; Currently it overwrites anything else in the same screen space<br>
&gt; (Presumably blitting on top of anything drawn using native swing-type<br>
&gt; code).<br>
&gt;<br>
&gt; thanks<br>
&gt;<br>
&gt; JB<br>
&gt;<br>
</tt></font>
<br>
<br><font size=2><tt>package vtk;<br>
import java.awt.*;<br>
import java.awt.event.*;<br>
import java.util.*;<br>
import javax.swing.*;<br>
</tt></font>
<br><font size=2><tt>public class vtkPanel extends Canvas implements<br>
MouseListener,<br>
MouseMotionListener,<br>
KeyListener</tt></font>
<br><font size=2><tt>{<br>
protected vtkRenderWindow rw = new vtkRenderWindow();<br>
protected vtkRenderer ren = new vtkRenderer();<br>
protected vtkCamera cam = null;<br>
protected vtkLight lgt = new vtkLight();<br>
protected int lastX;<br>
protected int lastY;<br>
protected int windowset = 0;<br>
protected int lightingset = 0;<br>
protected int LightFollowCamera = 1;<br>
protected int InteractionMode = 1;<br>
protected boolean rendering = false;<br>
protected WindowObservable windowSetObservable = new WindowObservable();<br>
private final JPopupMenu viewMenu = new JPopupMenu();</tt></font>
<br>
<br><font size=2><tt>static {<br>
System.loadLibrary(&quot;vtkCommonJava&quot;);<br>
System.loadLibrary(&quot;vtkFilteringJava&quot;);<br>
System.loadLibrary(&quot;vtkIOJava&quot;);<br>
System.loadLibrary(&quot;vtkImagingJava&quot;);<br>
System.loadLibrary(&quot;vtkGraphicsJava&quot;);<br>
System.loadLibrary(&quot;vtkRenderingJava&quot;);<br>
try {</tt></font>
<br><font size=2><tt>System.loadLibrary(&quot;vtkHybridJava&quot;);<br>
} catch (Throwable e) {</tt></font>
<br><font size=2><tt>System.out.println(&quot;cannot load vtkHybrid, skipping...&quot;);<br>
}<br>
JPopupMenu.setDefaultLightWeightPopupEnabled(false);</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>protected native int RenderCreate(vtkRenderWindow id0);<br>
protected native int Lock();<br>
protected native int UnLock();</tt></font>
<br>
<br><font size=2><tt>public vtkPanel()<br>
{</tt></font>
<br><font size=2><tt>rw.AddRenderer(ren);<br>
addMouseListener(this);<br>
addMouseMotionListener(this);<br>
addKeyListener(this);<br>
super.setSize(200,200);<br>
rw.SetSize(200,200);<br>
addWindowSetObserver(new WindowSetObserver());<br>
JMenuItem testMenuItem = new JMenuItem(new AbstractAction(&quot;do test&quot;) {</tt></font>
<br><font size=2><tt>public void actionPerformed(ActionEvent e) {<br>
JOptionPane.showMessageDialog(null, &quot;tested.&quot;);</tt></font>
<br><font size=2><tt>}<br>
});</tt></font>
<br><font size=2><tt>JMenu testMenu = new JMenu(&quot;test&quot;);<br>
testMenu.add(testMenuItem);<br>
viewMenu.add(testMenu);</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public void Report() {<br>
</tt></font>
<br><font size=2><tt>// must be performed on awt event thread<br>
Runnable updateAComponent = new Runnable() {</tt></font>
<br><font size=2><tt>public void run() {<br>
Lock();<br>
System.out.println(&quot;direct rendering = &quot; + (rw.IsDirect()==1));<br>
System.out.println(&quot;opengl supported = &quot; + (rw.SupportsOpenGL()==1));<br>
System.out.println(&quot;report = &quot; + rw.ReportCapabilities());<br>
UnLock();</tt></font>
<br><font size=2><tt>}<br>
};</tt></font>
<br>
<br><font size=2><tt>SwingUtilities.invokeLater(updateAComponent);<br>
</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public vtkRenderer GetRenderer()<br>
{</tt></font>
<br><font size=2><tt>return ren;<br>
}</tt></font>
<br>
<br><font size=2><tt>public vtkRenderWindow GetRenderWindow()<br>
{</tt></font>
<br><font size=2><tt>return rw;<br>
}</tt></font>
<br>
<br><font size=2><tt>public void addWindowSetObserver(Observer obs) {<br>
windowSetObservable.addObserver(obs);</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public void removeWindowSetObserver(Observer obs) {<br>
windowSetObservable.deleteObserver(obs);</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public void setSize(int x, int y)<br>
{</tt></font>
<br><font size=2><tt>super.setSize(x,y);<br>
if (windowset == 1)</tt></font>
<br><font size=2><tt>{<br>
Lock();<br>
rw.SetSize(x,y);<br>
UnLock();</tt></font>
<br><font size=2><tt>}<br>
}</tt></font>
<br>
<br><font size=2><tt>public void addNotify()<br>
{</tt></font>
<br><font size=2><tt>super.addNotify();<br>
windowset = 0;<br>
rw.SetForceMakeCurrent();<br>
rendering = false;</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public void removeNotify()<br>
{</tt></font>
<br><font size=2><tt>rendering = true;<br>
super.removeNotify();</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public synchronized void Render()<br>
{</tt></font>
<br><font size=2><tt>if (!rendering)<br>
{</tt></font>
<br><font size=2><tt>rendering = true;<br>
if (ren.VisibleActorCount() == 0) {rendering = false; return;}<br>
if (rw != null)</tt></font>
<br><font size=2><tt>{<br>
if (windowset == 0)</tt></font>
<br><font size=2><tt>{<br>
// set the window id and the active camera<br>
cam = ren.GetActiveCamera();<br>
if (lightingset == 0) {</tt></font>
<br><font size=2><tt>ren.AddLight(lgt);<br>
lgt.SetPosition(cam.GetPosition());<br>
lgt.SetFocalPoint(cam.GetFocalPoint());<br>
lightingset = 1;</tt></font>
<br><font size=2><tt>}<br>
RenderCreate(rw);<br>
Lock();<br>
rw.SetSize(getWidth(), getHeight());<br>
UnLock();<br>
windowset = 1;<br>
// notify observers that we have a renderwindow created<br>
windowSetObservable.notifyObservers();</tt></font>
<br><font size=2><tt>}<br>
Lock();<br>
rw.Render();<br>
UnLock();<br>
rendering = false;</tt></font>
<br><font size=2><tt>}<br>
}</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public boolean isWindowSet()<br>
{</tt></font>
<br><font size=2><tt>return (this.windowset==1);<br>
}</tt></font>
<br>
<br><font size=2><tt>public void paint(Graphics g)<br>
{</tt></font>
<br><font size=2><tt>this.Render();<br>
}</tt></font>
<br>
<br><font size=2><tt>public void update(Graphics g) {<br>
paint(g);</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public void LightFollowCameraOn()<br>
{</tt></font>
<br><font size=2><tt>this.LightFollowCamera = 1;<br>
}</tt></font>
<br>
<br><font size=2><tt>public void LightFollowCameraOff()<br>
{</tt></font>
<br><font size=2><tt>this.LightFollowCamera = 0;<br>
}</tt></font>
<br>
<br><font size=2><tt>public void InteractionModeRotate()<br>
{</tt></font>
<br><font size=2><tt>this.InteractionMode = 1;<br>
}</tt></font>
<br>
<br><font size=2><tt>public void InteractionModeTranslate()<br>
{</tt></font>
<br><font size=2><tt>this.InteractionMode = 2;<br>
}</tt></font>
<br>
<br><font size=2><tt>public void InteractionModeZoom()<br>
{</tt></font>
<br><font size=2><tt>this.InteractionMode = 3;<br>
}</tt></font>
<br>
<br><font size=2><tt>public void UpdateLight()<br>
{</tt></font>
<br><font size=2><tt>lgt.SetPosition(cam.GetPosition());<br>
lgt.SetFocalPoint(cam.GetFocalPoint());</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public void resetCameraClippingRange() {<br>
Lock();<br>
ren.ResetCameraClippingRange();<br>
UnLock();</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public void resetCamera() {<br>
Lock();<br>
ren.ResetCamera();<br>
UnLock();</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public void mouseClicked(MouseEvent e) {<br>
</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public void mousePressed(MouseEvent e)<br>
{</tt></font>
<br><font size=2><tt>if (ren.VisibleActorCount() == 0) return;<br>
rw.SetDesiredUpdateRate(5.0);<br>
lastX = e.getX();<br>
lastY = e.getY();<br>
if ((e.getModifiers()==(InputEvent.BUTTON3_MASK | InputEvent.SHIFT_MASK)))</tt></font>
<br><font size=2><tt>{<br>
viewMenu.show(this, e.getX(),e.getY());</tt></font>
<br><font size=2><tt>}<br>
if ((e.getModifiers()==InputEvent.BUTTON2_MASK) ||</tt></font>
<br><font size=2><tt>(e.getModifiers()==(InputEvent.BUTTON1_MASK | InputEvent.SHIFT_MASK)))<br>
{</tt></font>
<br><font size=2><tt>InteractionModeTranslate();<br>
}</tt></font>
<br><font size=2><tt>else if (e.getModifiers()==InputEvent.BUTTON3_MASK)<br>
{</tt></font>
<br><font size=2><tt>InteractionModeZoom();<br>
}</tt></font>
<br><font size=2><tt>else<br>
{</tt></font>
<br><font size=2><tt>InteractionModeRotate();<br>
}</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public void mouseReleased(MouseEvent e)<br>
{</tt></font>
<br><font size=2><tt>rw.SetDesiredUpdateRate(0.01);<br>
}</tt></font>
<br>
<br><font size=2><tt>public void mouseEntered(MouseEvent e)<br>
{</tt></font>
<br><font size=2><tt>this.requestFocus();<br>
}</tt></font>
<br>
<br><font size=2><tt>public void mouseExited(MouseEvent e) {}<br>
</tt></font>
<br><font size=2><tt>public void mouseMoved(MouseEvent e)<br>
{</tt></font>
<br><font size=2><tt>lastX = e.getX();<br>
lastY = e.getY();</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br>
<br><font size=2><tt>public void mouseDragged(MouseEvent e)<br>
{</tt></font>
<br><font size=2><tt>if (ren.VisibleActorCount() == 0) return;<br>
int x = e.getX();<br>
int y = e.getY();<br>
// rotate<br>
if (this.InteractionMode == 1)</tt></font>
<br><font size=2><tt>{<br>
cam.Azimuth(lastX - x);<br>
cam.Elevation(y - lastY);<br>
cam.OrthogonalizeViewUp();<br>
resetCameraClippingRange();<br>
if (this.LightFollowCamera == 1)</tt></font>
<br><font size=2><tt>{<br>
lgt.SetPosition(cam.GetPosition());<br>
lgt.SetFocalPoint(cam.GetFocalPoint());</tt></font>
<br><font size=2><tt>}<br>
}</tt></font>
<br><font size=2><tt>// translate<br>
if (this.InteractionMode == 2)</tt></font>
<br><font size=2><tt>{<br>
double &nbsp;FPoint[];<br>
double &nbsp;PPoint[];<br>
double &nbsp;APoint[] = new double[3];<br>
double &nbsp;RPoint[];<br>
double focalDepth;</tt></font>
<br>
<br><font size=2><tt>// get the current focal point and position<br>
FPoint = cam.GetFocalPoint();<br>
PPoint = cam.GetPosition();</tt></font>
<br>
<br><font size=2><tt>// calculate the focal depth since we'll be using it a lot<br>
ren.SetWorldPoint(FPoint[0],FPoint[1],FPoint[2],1.0);<br>
ren.WorldToDisplay();<br>
focalDepth = ren.GetDisplayPoint()[2];</tt></font>
<br>
<br><font size=2><tt>APoint[0] = rw.GetSize()[0]/2.0 + (x - lastX);<br>
APoint[1] = rw.GetSize()[1]/2.0 - (y - lastY);<br>
APoint[2] = focalDepth;<br>
ren.SetDisplayPoint(APoint);<br>
ren.DisplayToWorld();<br>
RPoint = ren.GetWorldPoint();<br>
if (RPoint[3] != 0.0)</tt></font>
<br><font size=2><tt>{<br>
RPoint[0] = RPoint[0]/RPoint[3];<br>
RPoint[1] = RPoint[1]/RPoint[3];<br>
RPoint[2] = RPoint[2]/RPoint[3];</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>/*<br>
* Compute a translation vector, moving everything 1/2<br>
* the distance to the cursor. (Arbitrary scale factor)<br>
*/</tt></font>
<br><font size=2><tt>cam.SetFocalPoint(<br>
(FPoint[0]-RPoint[0])/2.0 + FPoint[0],<br>
(FPoint[1]-RPoint[1])/2.0 + FPoint[1],<br>
(FPoint[2]-RPoint[2])/2.0 + FPoint[2]);</tt></font>
<br><font size=2><tt>cam.SetPosition(<br>
(FPoint[0]-RPoint[0])/2.0 + PPoint[0],<br>
(FPoint[1]-RPoint[1])/2.0 + PPoint[1],<br>
(FPoint[2]-RPoint[2])/2.0 + PPoint[2]);</tt></font>
<br><font size=2><tt>resetCameraClippingRange();<br>
}</tt></font>
<br><font size=2><tt>// zoom<br>
if (this.InteractionMode == 3)</tt></font>
<br><font size=2><tt>{<br>
double zoomFactor;<br>
double clippingRange[];</tt></font>
<br>
<br><font size=2><tt>zoomFactor = Math.pow(1.02,(y - lastY));<br>
if (cam.GetParallelProjection() == 1)</tt></font>
<br><font size=2><tt>{<br>
cam.SetParallelScale(cam.GetParallelScale()/zoomFactor);</tt></font>
<br><font size=2><tt>}<br>
else</tt></font>
<br><font size=2><tt>{<br>
cam.Dolly(zoomFactor);<br>
resetCameraClippingRange();</tt></font>
<br><font size=2><tt>}<br>
}</tt></font>
<br><font size=2><tt>lastX = x;<br>
lastY = y;<br>
this.Render();</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public void keyTyped(KeyEvent e) {}<br>
</tt></font>
<br><font size=2><tt>public void keyPressed(KeyEvent e)<br>
{</tt></font>
<br><font size=2><tt>if (ren.VisibleActorCount() == 0) return;<br>
char keyChar = e.getKeyChar();</tt></font>
<br>
<br><font size=2><tt>if ('r' == keyChar)<br>
{</tt></font>
<br><font size=2><tt>resetCamera();<br>
this.Render();</tt></font>
<br><font size=2><tt>}<br>
if ('u' == keyChar)</tt></font>
<br><font size=2><tt>{<br>
pickActor(lastX, lastY);</tt></font>
<br><font size=2><tt>}<br>
if ('w' == keyChar)</tt></font>
<br><font size=2><tt>{<br>
vtkActorCollection ac;<br>
vtkActor anActor;<br>
vtkActor aPart;<br>
int i, j;</tt></font>
<br>
<br><font size=2><tt>ac = ren.GetActors();<br>
ac.InitTraversal();<br>
for (i = 0; i &lt; ac.GetNumberOfItems(); i++)</tt></font>
<br><font size=2><tt>{<br>
anActor = ac.GetNextActor();<br>
anActor.InitPartTraversal();<br>
for (j = 0; j &lt; anActor.GetNumberOfParts(); j++)</tt></font>
<br><font size=2><tt>{<br>
aPart = anActor.GetNextPart();<br>
aPart.GetProperty().SetRepresentationToWireframe();</tt></font>
<br><font size=2><tt>}<br>
}</tt></font>
<br><font size=2><tt>this.Render();<br>
}</tt></font>
<br><font size=2><tt>if ('s' == keyChar)<br>
{</tt></font>
<br><font size=2><tt>vtkActorCollection ac;<br>
vtkActor anActor;<br>
vtkActor aPart;<br>
int i, j;</tt></font>
<br>
<br><font size=2><tt>ac = ren.GetActors();<br>
ac.InitTraversal();<br>
for (i = 0; i &lt; ac.GetNumberOfItems(); i++)</tt></font>
<br><font size=2><tt>{<br>
anActor = ac.GetNextActor();<br>
anActor.InitPartTraversal();<br>
for (j = 0; j &lt; anActor.GetNumberOfParts(); j++)</tt></font>
<br><font size=2><tt>{<br>
aPart = anActor.GetNextPart();<br>
aPart.GetProperty().SetRepresentationToSurface();</tt></font>
<br><font size=2><tt>}<br>
}</tt></font>
<br><font size=2><tt>this.Render();<br>
}</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public void HardCopy(String filename, int mag) {<br>
</tt></font>
<br><font size=2><tt>Lock();<br>
</tt></font>
<br><font size=2><tt>vtkWindowToImageFilter w2if = new vtkWindowToImageFilter();<br>
w2if.SetInput(rw);</tt></font>
<br>
<br><font size=2><tt>w2if.SetMagnification(mag);<br>
w2if.Update();</tt></font>
<br>
<br><font size=2><tt>vtkTIFFWriter writer = new vtkTIFFWriter();<br>
writer.SetInput(w2if.GetOutput());<br>
writer.SetFileName(filename);<br>
writer.Write();</tt></font>
<br>
<br><font size=2><tt>UnLock();<br>
}</tt></font>
<br>
<br><font size=2><tt>public void pickActor(int x, int y) {<br>
</tt></font>
<br><font size=2><tt>vtkPropPicker picker = new vtkPropPicker();<br>
</tt></font>
<br><font size=2><tt>Lock();<br>
picker.PickProp(x, rw.GetSize()[1] - y , ren);<br>
UnLock();</tt></font>
<br>
<br><font size=2><tt>if (picker.GetActor() != null)<br>
System.out.println(picker.GetActor().GetClassName());</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public void keyReleased(KeyEvent e) {}<br>
</tt></font>
<br><font size=2><tt>private class WindowObservable extends Observable {<br>
</tt></font>
<br><font size=2><tt>public void notifyObservers() {<br>
this.setChanged();<br>
super.notifyObservers();</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public void notifyObservers(Object message) {<br>
this.setChanged();<br>
super.notifyObservers(message);</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>public boolean hasObservers() {<br>
return 0 &lt; super.countObservers();</tt></font>
<br><font size=2><tt>}<br>
}</tt></font>
<br>
<br><font size=2><tt>private class WindowSetObserver implements Observer {<br>
</tt></font>
<br><font size=2><tt>public void update(Observable o, Object arg) {<br>
// we know the window is set, so changes to the render window size<br>
// will actually take place</tt></font>
<br><font size=2><tt>// &nbsp; &nbsp; &nbsp; if (getWidth() &gt; 0 &amp;&amp; getHeight() &gt; 0)<br>
// &nbsp; &nbsp; &nbsp; &nbsp; rw.SetSize(getWidth(), getHeight());</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>}<br>
</tt></font>
<br><font size=2><tt>}</tt></font>
<br>
<br>
<br><font size=2 face="sans-serif"><br>
<br>
This message is confidential and may be privileged. It is intended for the addressee(s) only. Access to this message by anyone else is unauthorized and strictly prohibited. If you have received this message in error, please inform the sender immediately.<br>
<br>
TESSELLA &nbsp; Richard.Bridge@tessella.com<br>
__/__/__/ &nbsp;Tessella Support Services plc<br>
__/__/__/ &nbsp;3 Vineyard Chambers, ABINGDON, OX14 3PX, England<br>
__/__/__/ &nbsp;Tel: (44)(0)1235-555511 &nbsp;Fax: (44)(0)1235-553301<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; www.tessella.com<br>
 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Registered in England No. 1466429<br>
</font>