Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/xerox/VTM/engine/AccViewPanel.java


1   /*   FILE: AccViewPanel.java
2    *   DATE OF CREATION:   Jun 08 2000
3    *   AUTHOR :            Emmanuel Pietriga (emmanuel.pietriga@xrce.xerox.com)
4    *   MODIF:              Tue Aug 05 14:55:10 2003 by Emmanuel Pietriga (emmanuel@w3.org, emmanuel@claribole.net)
5    *   Copyright (c) Xerox Corporation, XRCE/Contextual Computing, 2002. All Rights Reserved
6    * 
7    * This library is free software; you can redistribute it and/or
8    * modify it under the terms of the GNU Lesser General Public
9    * License as published by the Free Software Foundation; either
10   * version 2.1 of the License, or (at your option) any later version.
11   * 
12   * This library is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15   * Lesser General Public License for more details.
16   *
17   * For full terms see the file COPYING.
18   */
19  
20  package com.xerox.VTM.engine;
21  
22  import com.xerox.VTM.glyphs.*;
23  import javax.swing.*;
24  import java.awt.*;
25  import java.awt.geom.*;
26  import java.awt.image.*;
27  import java.awt.event.*;
28  import java.util.Vector;
29  import java.util.Date;
30  import java.util.Enumeration;
31  
32  /**
33   * Each view runs in its own thread - uses double buffering - 
34   * this one is hardware accelerated (at least under Win32) using VolatileImage available since JDK 1.4.0 (does not accelerate bitmaps)
35   * @author Emmanuel Pietriga
36   */
37  public class AccViewPanel extends ViewPanel implements Runnable {
38  
39      /**for Double Buffering*/
40      VolatileImage vImg;
41  
42      //get the BufferedImage for this view
43      protected BufferedImage getImage(){
44    return this.vImg.getSnapshot();
45      }
46  
47      public AccViewPanel(Vector cameras,View v) {
48    addHierarchyListener(
49        new HierarchyListener() {
50           public void hierarchyChanged(HierarchyEvent e) {
51         if (isShowing()) {
52             start();
53         } else {
54             stop();
55         }
56           }
57       }
58    );
59    parent=v;
60    //init of camera array
61    cams=new Camera[cameras.size()];  //array of Camera
62    for (int nbcam=0;nbcam<cameras.size();nbcam++){
63        cams[nbcam]=(Camera)(cameras.get(nbcam));
64    }
65    //init other stuff
66    setBackground(Color.lightGray);
67    this.addMouseListener(this);
68    this.addMouseMotionListener(this);
69    start();
70  //   for (int i=0;i<cams.length;i++){
71  //       System.out.println(cams[i].toString());
72  //   }
73  //   BufferedImage cImage=new BufferedImage(1,1,BufferedImage.TYPE_INT_ARGB); //create a BufferedImage with transparent background
74  //   try {//this buffer represents the mouse cursor shape  (it does not appear since it is transparent)
75  //       Cursor custCursor=Toolkit.getDefaultToolkit().createCustomCursor(cImage,new Point(0,0),"myCursor");
76  //       this.setCursor(custCursor);
77  //   }
78  //   catch(IndexOutOfBoundsException e){if (parent.parent.debug){System.err.println("Error while creating custom cursor "+e);setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));}}
79    setAWTCursor(Cursor.CUSTOM_CURSOR);  //custom cursor means VTM cursor
80    if (parent.parent.debug){System.out.println("View refresh time set to "+frameTime+"ms");}
81      }
82  
83      public void start() {
84    Dimension size = getSize();
85    runView = new Thread(this);
86    runView.setPriority(Thread.NORM_PRIORITY);
87    runView.start();
88      }
89  
90      public synchronized void stop() {
91    runView = null;
92    notify();
93      }
94  
95      public void run() {
96    Thread me = Thread.currentThread();
97    while (getSize().width <= 0) {  //Wait until the window actually exists
98        try {
99      runView.sleep(500);
100       } 
101       catch (InterruptedException e) {
102     if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep "+e);}
103     return;
104       }
105         }
106   Graphics2D g2d = null;
107   Graphics2D BufferG2D = null;
108   Dimension oldSize=getSize();
109   //clipRect=new Rectangle(0,0,oldSize.width,oldSize.height);
110   while (runView == me) {
111       if (notBlank){
112     if (active){
113         if (repaintNow) {
114       repaintNow=false;//do this first as the thread can be interrupted inside this branch and we want to catch new requests for repaint
115       updateMouseOnly=false;
116       d1=System.currentTimeMillis();
117       Dimension size=getSize();
118       if (size.width != oldSize.width || size.height != oldSize.height) {
119           //each time the parent window is resized, adapt the buffer image size
120           vImg=null;
121           if (BufferG2D != null) {
122         BufferG2D.dispose();
123         BufferG2D = null;
124           }
125           //clipRect=new Rectangle(0,0,size.width,size.height);
126           if (parent.parent.debug){System.out.println("Resizing JPanel: ("+oldSize.width+"x"+oldSize.height+") -> ("+size.width+"x"+size.height+")");}
127           oldSize=size;
128           updateAntialias=true;
129           updateFont=true;
130       }
131       if (vImg==null) {
132           GraphicsConfiguration gc=getGraphicsConfiguration();
133           vImg=gc.createCompatibleVolatileImage(size.width,size.height);
134           updateAntialias=true;
135           updateFont=true;
136       }
137       if (BufferG2D == null) {
138           BufferG2D = vImg.createGraphics();
139           BufferG2D.setFont(VirtualSpaceManager.mainFont);
140           updateAntialias=true;
141           updateFont=true;
142       }
143       if (updateFont) {BufferG2D.setFont(VirtualSpaceManager.mainFont);updateFont=false;}
144       if (updateAntialias){if (antialias){BufferG2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);} else {BufferG2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);}updateAntialias=false;}
145       g2d = BufferG2D;
146       //g2d.setClip(clipRect);
147       GraphicsConfiguration gc=this.getGraphicsConfiguration();
148       int valCode=vImg.validate(gc);
149       if (valCode==VolatileImage.IMAGE_INCOMPATIBLE){
150           vImg=gc.createCompatibleVolatileImage(size.width,size.height);
151       }
152       standardStroke=g2d.getStroke();
153       standardTransform=g2d.getTransform();
154       //parent.parent.constMgr.updateAttribsFromMvars();
155       synchronized(this){
156           g2d.setPaintMode();
157           g2d.setBackground(backColor);
158           g2d.clearRect(0, 0, getWidth(), getHeight());
159           //begin actual drawing here
160           for (int nbcam=0;nbcam<cams.length;nbcam++){
161         if ((cams[nbcam]!=null) && (cams[nbcam].enabled) && ((cams[nbcam].eager) || (cams[nbcam].shouldRepaint()))){
162             camIndex=cams[nbcam].getIndex();
163             drawnGlyphs=cams[nbcam].parentSpace.getDrawnGlyphs(camIndex);
164             synchronized(drawnGlyphs){
165           drawnGlyphs.removeAllElements();
166           uncoef=(float)((cams[nbcam].focal+cams[nbcam].altitude)/cams[nbcam].focal);
167           viewW=this.getSize().width;//compute region's width and height
168           viewH=this.getSize().height;
169           viewWHu=(long)(cams[nbcam].posx+this.getSize().width/2*uncoef);//compute region seen from this view
170           viewHHu=(long)(cams[nbcam].posy+this.getSize().height/2*uncoef);//through camera
171           viewWLu=(long)(cams[nbcam].posx-this.getSize().width/2*uncoef);
172           viewHLu=(long)(cams[nbcam].posy-this.getSize().height/2*uncoef);
173           if (parent.detectMultipleFullFills){//if detect multiple fills option is ON
174               for (Enumeration en=cams[nbcam].parentSpace.getVisibleGlyphs().elements();en.hasMoreElements();){
175             gl=(Glyph)(en.nextElement());
176             if (gl.drawMe(viewWHu,viewHHu,viewWLu,viewHLu,camIndex)){
177                 cams[nbcam].parentSpace.drewGlyph(gl,camIndex);gl.project(cams[nbcam],this);
178             }
179               }
180               //drawnGlyphs=cams[nbcam].parentSpace.getDrawnGlyphs(camIndex);
181               beginAt=0;
182               for (int j=drawnGlyphs.size()-1;j>=0;j--){//glyphs must have been projected because fillsView uses
183             if (((Glyph)drawnGlyphs.elementAt(j)).fillsView(viewW,viewH,cams[nbcam].getIndex())){//projected coords
184                 beginAt=j;
185                 break;
186             }
187               }
188               for (int j=beginAt;j<drawnGlyphs.size();j++){
189             gl=(Glyph)drawnGlyphs.elementAt(j);
190             if (gl.isVisible()){
191                 gl.draw(g2d,size.width,size.height,cams[nbcam].getIndex(),standardStroke,standardTransform);
192             }
193               }
194           }
195           else {//if detect multiple fills option is OFF
196               for (Enumeration en=cams[nbcam].parentSpace.getVisibleGlyphs().elements();en.hasMoreElements();){
197             gl=(Glyph)(en.nextElement());
198             if (gl.drawMe(viewWHu,viewHHu,viewWLu,viewHLu,camIndex)){
199                 //if glyph is al least partially visible in the reg. seen from this view, display
200                 synchronized(gl){
201               gl.project(cams[nbcam],this);
202               if (gl.isVisible()){
203                   gl.draw(g2d,size.width,size.height,cams[nbcam].getIndex(),standardStroke,standardTransform);
204                   cams[nbcam].parentSpace.drewGlyph(gl,camIndex);
205               }
206                 }
207             }
208               }
209           }
210             }
211         }
212           }
213           if (inside){//deal with mouse glyph only if mouse cursor is inside this window
214         try {
215             parent.mouse.unProject(cams[activeLayer],this); //we project the mouse cursor wrt the appropriate coord sys
216             if (computeListAtEachRepaint && parent.mouse.isSensitive()){
217           parent.mouse.computeMouseOverList(evH,cams[activeLayer]);
218             }
219         }
220         catch (NullPointerException ex) {if (parent.parent.debug){System.err.println("viewpanel.run.drawdrag "+ex);}}
221         g2d.setColor(parent.mouse.color);
222         if (drawDrag){g2d.drawLine(origDragx,origDragy,parent.mouse.mx,parent.mouse.my);}
223         if (drawRect){g2d.drawRect(Math.min(origDragx,parent.mouse.mx),Math.min(origDragy,parent.mouse.my),Math.max(origDragx,parent.mouse.mx)-Math.min(origDragx,parent.mouse.mx),Math.max(origDragy,parent.mouse.my)-Math.min(origDragy,parent.mouse.my));}
224         if (drawOval){
225             if (circleOnly){
226           g2d.drawOval(origDragx-Math.abs(origDragx-parent.mouse.mx),origDragy-Math.abs(origDragx-parent.mouse.mx),2*Math.abs(origDragx-parent.mouse.mx),2*Math.abs(origDragx-parent.mouse.mx));
227             }
228             else {
229           g2d.drawOval(origDragx-Math.abs(origDragx-parent.mouse.mx),origDragy-Math.abs(origDragy-parent.mouse.my),2*Math.abs(origDragx-parent.mouse.mx),2*Math.abs(origDragy-parent.mouse.my));
230             }
231         }
232         if (drawVTMcursor){
233             synchronized(this){
234           g2d.setXORMode(backColor);
235           parent.mouse.draw(g2d);
236           oldX=parent.mouse.mx;
237           oldY=parent.mouse.my;
238             }
239         }
240           }
241           //end drawing here
242           if (g2d == BufferG2D) {
243         repaint();
244           }
245           d2=System.currentTimeMillis();
246           timeToSleep=frameTime-d2+d1;   //40-(d2-d1)  = wanted refresh rate - time needed to do the actual repaint operations
247       }
248       //either we do - BETTER UNDER Win32
249       try {
250           runView.sleep((timeToSleep>10) ? timeToSleep : 10);   //sleep ... ms  
251       } 
252       catch (InterruptedException e) {
253           if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep2 "+e);}
254           return;
255       }
256       //or this   both seem to work well (have to test on several config) - BETTER UNDER SOLARIS
257       //Thread.yield();
258         }
259         else if (updateMouseOnly){
260       updateMouseOnly=false;
261       d1=System.currentTimeMillis();
262       try {
263           parent.mouse.unProject(cams[activeLayer],this); //we project the mouse cursor wrt the appropriate coord sys
264           if (computeListAtEachRepaint && parent.mouse.isSensitive()){parent.mouse.computeMouseOverList(evH,cams[activeLayer]);}
265       }
266       catch (NullPointerException ex) {if (parent.parent.debug){System.err.println("viewpanel.run.drawdrag "+ex);}}
267       if (drawVTMcursor){
268           synchronized(this){
269         try {
270             g2d.setXORMode(backColor);
271             g2d.setColor(parent.mouse.color);
272             g2d.drawLine(oldX-10,oldY,oldX+10,oldY);
273             g2d.drawLine(oldX,oldY-10,oldX,oldY+10);
274             g2d.drawLine(parent.mouse.mx-10,parent.mouse.my,parent.mouse.mx+10,parent.mouse.my);
275             g2d.drawLine(parent.mouse.mx,parent.mouse.my-10,parent.mouse.mx,parent.mouse.my+10);
276             oldX=parent.mouse.mx;
277             oldY=parent.mouse.my;
278         }//a nullpointerex on g2d seems to occur from time to time when going in or exiting from blank mode - just catch it and wait for next loop until we find out what's causing this
279         catch (NullPointerException ex47){if (parent.parent.debug){System.err.println("viewpanel.run.runview.drawVTMcursor "+ex47);}}
280           }
281       }
282       repaint();
283       d2=System.currentTimeMillis();
284       timeToSleep=frameTime-d2+d1;   //40-(d2-d1)  = wanted refresh rate - time needed to do the actual repaint operations
285       try {
286           runView.sleep((timeToSleep>10) ? timeToSleep : 10);   //sleep ... ms  
287       }
288       catch (InterruptedException e){
289           if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep3 "+e);}
290           return;
291       }
292         }
293         else {
294       try {
295           runView.sleep(frameTime+20);   //sleep ... ms  
296       } 
297       catch (InterruptedException e) {
298           if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep3 "+e);}
299           return;
300       }
301         }
302     }
303     else {
304         try {
305       runView.sleep(deactiveTime);   //sleep ... ms  
306         } 
307         catch (InterruptedException e) {
308       if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep4 "+e);}
309       return;
310         }
311     }
312       }
313       else {
314     Dimension size=getSize();
315     if (size.width != oldSize.width || size.height != oldSize.height) {
316         //each time the parent window is resized, adapt the buffer image size
317         vImg=null;
318         if (BufferG2D != null) {
319       BufferG2D.dispose();
320       BufferG2D = null;
321         }
322         if (parent.parent.debug){System.out.println("Resizing JPanel: ("+oldSize.width+"x"+oldSize.height+") -> ("+size.width+"x"+size.height+")");}
323         oldSize=size;
324         updateAntialias=true;
325         updateFont=true;
326     }
327     if (vImg==null) {
328         GraphicsConfiguration gc=getGraphicsConfiguration();
329         vImg=gc.createCompatibleVolatileImage(size.width,size.height);
330         updateAntialias=true;
331         updateFont=true;
332     }
333     if (BufferG2D == null) {
334         BufferG2D = vImg.createGraphics();
335         BufferG2D.setFont(VirtualSpaceManager.mainFont);
336         updateAntialias=true;
337         updateFont=true;
338     }
339     if (updateFont) {BufferG2D.setFont(VirtualSpaceManager.mainFont);updateFont=false;}
340     if (updateAntialias){if (antialias){BufferG2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);} else {BufferG2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);}updateAntialias=false;}
341     g2d = BufferG2D;
342     //g2d.setClip(clipRect);
343     GraphicsConfiguration gc=this.getGraphicsConfiguration();
344     int valCode=vImg.validate(gc);
345     if (valCode==VolatileImage.IMAGE_INCOMPATIBLE){
346         vImg=gc.createCompatibleVolatileImage(size.width,size.height);
347     }
348     standardStroke=g2d.getStroke();
349     standardTransform=g2d.getTransform();
350     g2d.setPaintMode();
351     g2d.setColor(blankColor);
352     g2d.fillRect(0,0,getWidth(),getHeight());
353     repaint();
354     try {
355         runView.sleep(deactiveTime);   //sleep ... ms
356     }
357     catch (InterruptedException e){
358         if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep5 "+e);}
359         return;
360     }
361       }
362   }
363   if (g2d != null) {  
364       g2d.dispose();
365   }
366     }
367     
368     public void paint(Graphics g) {
369   synchronized (this) {
370       g2 = (Graphics2D) g;
371       if (vImg != null) {
372     g2.drawImage(vImg, 0, 0, this);
373       }
374         }
375     }
376 
377 }