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

Quick Search    Search Deep

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


1   /*   FILE: StdViewPanel.java
2    *   DATE OF CREATION:   Jul 11 2000
3    *   AUTHOR :            Emmanuel Pietriga (emmanuel.pietriga@xrce.xerox.com)
4    *   MODIF:              Tue Aug 05 14:54:52 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   * @author Emmanuel Pietriga
35   */
36  public class StdViewPanel extends ViewPanel implements Runnable {
37  
38      /**for Double Buffering*/
39      BufferedImage buffImg;
40  
41      //get the BufferedImage or VolatileImage for this view
42      protected BufferedImage getImage(){
43    return this.buffImg;
44      }
45  
46      public StdViewPanel(Vector cameras,View v) {
47    addHierarchyListener(
48        new HierarchyListener() {
49           public void hierarchyChanged(HierarchyEvent e) {
50         if (isShowing()) {
51             start();
52         } else {
53             stop();
54         }
55           }
56       }
57    );
58    parent=v;
59    //init of camera array
60    cams=new Camera[cameras.size()];  //array of Camera
61    for (int nbcam=0;nbcam<cameras.size();nbcam++){
62        cams[nbcam]=(Camera)(cameras.get(nbcam));
63    }
64    //init other stuff
65    setBackground(Color.lightGray);
66    this.addMouseListener(this);
67    this.addMouseMotionListener(this);
68    start();
69  //   for (int i=0;i<cams.length;i++){
70  //       System.out.println(cams[i].toString());
71  //   }
72    // BufferedImage cImage=new BufferedImage(1,1,BufferedImage.TYPE_INT_ARGB); //create a BufferedImage with transparent background
73  //   try {//this buffer represents the mouse cursor shape  (it does not appear since it is transparent)
74  //       awtCursor=Toolkit.getDefaultToolkit().createCustomCursor(cImage,new Point(0,0),"myCursor");
75  //       this.setCursor(awtCursor);
76  //   }
77  //   catch(IndexOutOfBoundsException e){if (parent.parent.debug){System.err.println("Error while creating custom cursor "+e);setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));}}
78    setAWTCursor(Cursor.CUSTOM_CURSOR);  //custom cursor means VTM cursor
79    if (parent.parent.debug){System.out.println("View refresh time set to "+frameTime+"ms");}
80      }
81  
82      public void start(){
83    Dimension size = getSize();
84    runView = new Thread(this);
85    runView.setPriority(Thread.NORM_PRIORITY);
86    runView.start();
87      }
88  
89      public synchronized void stop() {
90    runView = null;
91    notify();
92      }
93  
94      public void run() {
95    Thread me = Thread.currentThread();
96    while (getSize().width <= 0) {  //Wait until the window actually exists
97        try {
98      runView.sleep(500);
99        } 
100       catch (InterruptedException e) {
101     if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep "+e);}
102     return;
103       }
104         }
105   Graphics2D g2d = null;
106   Graphics2D BufferG2D = null;
107   Dimension oldSize=getSize();
108   //clipRect=new Rectangle(0,0,oldSize.width,oldSize.height);
109   while (runView==me) {
110        if (notBlank){
111     if (active){
112         if (repaintNow){
113       try {
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         buffImg=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 (buffImg==null) {
132         buffImg=(BufferedImage) createImage(size.width,size.height);
133         updateAntialias=true;
134         updateFont=true;
135           }
136           if (BufferG2D == null) {
137         BufferG2D = buffImg.createGraphics();
138         updateAntialias=true;
139         updateFont=true;
140           }
141           if (updateFont){BufferG2D.setFont(VirtualSpaceManager.mainFont);updateFont=false;}
142           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;}
143           g2d = BufferG2D;
144           standardStroke=g2d.getStroke();
145           standardTransform=g2d.getTransform();
146           //parent.parent.constMgr.updateAttribsFromMvars();
147           synchronized(this){
148         g2d.setPaintMode();
149         g2d.setBackground(backColor);
150         g2d.clearRect(0,0,getWidth(),getHeight());
151         //begin actual drawing here
152         for (int nbcam=0;nbcam<cams.length;nbcam++){
153             if ((cams[nbcam]!=null) && (cams[nbcam].enabled) && ((cams[nbcam].eager) || (cams[nbcam].shouldRepaint()))){
154           camIndex=cams[nbcam].getIndex();
155           drawnGlyphs=cams[nbcam].parentSpace.getDrawnGlyphs(camIndex);
156           //synchronized(cams[nbcam].parentSpace.getDrawnGlyphs(camIndex)){
157           synchronized(drawnGlyphs){
158               //cams[nbcam].parentSpace.getDrawnGlyphs(camIndex).removeAllElements();
159               drawnGlyphs.removeAllElements();
160               uncoef=(float)((cams[nbcam].focal+cams[nbcam].altitude)/cams[nbcam].focal);
161               viewW=this.getSize().width;//compute region's width and height
162               viewH=this.getSize().height;
163               viewWHu=(long)(cams[nbcam].posx+this.getSize().width/2*uncoef);//compute region seen from this view
164               viewHHu=(long)(cams[nbcam].posy+this.getSize().height/2*uncoef);//through camera
165               viewWLu=(long)(cams[nbcam].posx-this.getSize().width/2*uncoef);
166               viewHLu=(long)(cams[nbcam].posy-this.getSize().height/2*uncoef);
167               if (parent.detectMultipleFullFills){//if detect multiple fills option is ON
168             for (Enumeration en=cams[nbcam].parentSpace.getVisibleGlyphs().elements();en.hasMoreElements();){
169                 gl=(Glyph)(en.nextElement());
170                 if (gl.drawMe(viewWHu,viewHHu,viewWLu,viewHLu,camIndex)){
171               cams[nbcam].parentSpace.drewGlyph(gl,camIndex);
172               gl.project(cams[nbcam],this);
173                 }
174             }
175             //drawnGlyphs=cams[nbcam].parentSpace.getDrawnGlyphs(camIndex);
176             beginAt=0;
177             for (int j=drawnGlyphs.size()-1;j>=0;j--){//glyphs must have been projected because fillsView uses
178                 if (((Glyph)drawnGlyphs.elementAt(j)).fillsView(viewW,viewH,cams[nbcam].getIndex())){//projected coords
179               beginAt=j;
180               break;
181                 }
182             }
183             for (int j=beginAt;j<drawnGlyphs.size();j++){
184               gl=(Glyph)drawnGlyphs.elementAt(j);
185               if (gl.isVisible()){
186                   gl.draw(g2d,size.width,size.height,cams[nbcam].getIndex(),standardStroke,standardTransform);
187               }
188             }
189               }
190               else {//if detect multiple fills option is OFF
191             for (Enumeration en=cams[nbcam].parentSpace.getVisibleGlyphs().elements();en.hasMoreElements();){
192                 gl=(Glyph)(en.nextElement());
193                 if (gl.drawMe(viewWHu,viewHHu,viewWLu,viewHLu,camIndex)){
194               //if glyph is at least partially visible in the reg. seen from this view, display
195               synchronized(gl){
196                   gl.project(cams[nbcam],this);
197                   if (gl.isVisible()){
198                 gl.draw(g2d,size.width,size.height,cams[nbcam].getIndex(),standardStroke,standardTransform);
199                 cams[nbcam].parentSpace.drewGlyph(gl,camIndex);
200                   }
201               }
202                 }
203             }
204               }
205           }
206             }
207         }
208         if (inside){//deal with mouse glyph only if mouse cursor is inside this window
209             try {
210           parent.mouse.unProject(cams[activeLayer],this); //we project the mouse cursor wrt the appropriate coord sys
211           if (computeListAtEachRepaint && parent.mouse.isSensitive()){
212               parent.mouse.computeMouseOverList(evH,cams[activeLayer]);
213           }
214             }
215             catch (NullPointerException ex) {if (parent.parent.debug){System.err.println("viewpanel.run.drawdrag "+ex);}}
216             g2d.setColor(parent.mouse.color);
217             if (drawDrag){g2d.drawLine(origDragx,origDragy,parent.mouse.mx,parent.mouse.my);}
218             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));}
219             if (drawOval){
220           if (circleOnly){
221               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));
222           }
223           else {
224               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));
225           }
226             }
227             if (drawVTMcursor){
228           synchronized(this){
229               g2d.setXORMode(backColor);
230               parent.mouse.draw(g2d);
231               oldX=parent.mouse.mx;
232               oldY=parent.mouse.my;
233           }
234             }
235         }
236         //end drawing here
237         if (g2d == BufferG2D) {
238             repaint();
239         }
240         d2=System.currentTimeMillis();
241         timeToSleep=frameTime-d2+d1;   //40-(d2-d1)  = wanted refresh rate - time needed to do the actual repaint operations
242           }
243       }
244       catch (NullPointerException ex0){if (parent.parent.debug){System.err.println("viewpanel.run (probably due to buffImg.createGraphics()) "+ex0);}}
245       //either we do - BETTER UNDER Win32
246       try {
247           //if (waitingForCapture){runView.yield();}
248           //else {runView.sleep((timeToSleep>10) ? timeToSleep : 10);}   //sleep ... ms  
249           runView.sleep((timeToSleep>10) ? timeToSleep : 10);
250       } 
251       catch (InterruptedException e) {
252           if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep2 "+e);}
253           return;
254       }
255       //or this   both seem to work well (have to test on several config) - BETTER UNDER SOLARIS
256       //Thread.yield();
257         }
258         else if (updateMouseOnly){
259       updateMouseOnly=false;//do this first as the thread can be interrupted inside this branch and we want to catch new requests for repaint
260       d1=System.currentTimeMillis();
261       try {
262           parent.mouse.unProject(cams[activeLayer],this); //we project the mouse cursor wrt the appropriate coord sys
263           if (computeListAtEachRepaint && parent.mouse.isSensitive()){parent.mouse.computeMouseOverList(evH,cams[activeLayer]);}
264       }
265       catch (NullPointerException ex) {if (parent.parent.debug){System.err.println("viewpanel.run.drawdrag "+ex);}}
266       if (drawVTMcursor){
267           synchronized(this){
268         try {
269             g2d.setXORMode(backColor);
270             g2d.setColor(parent.mouse.color);
271             g2d.drawLine(oldX-10,oldY,oldX+10,oldY);
272             g2d.drawLine(oldX,oldY-10,oldX,oldY+10);
273             g2d.drawLine(parent.mouse.mx-10,parent.mouse.my,parent.mouse.mx+10,parent.mouse.my);
274             g2d.drawLine(parent.mouse.mx,parent.mouse.my-10,parent.mouse.mx,parent.mouse.my+10);
275             oldX=parent.mouse.mx;
276             oldY=parent.mouse.my;
277         }//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
278         catch (NullPointerException ex47){if (parent.parent.debug){System.err.println("viewpanel.run.runview.drawVTMcursor "+ex47);}} 
279           }
280       }
281       repaint();
282       d2=System.currentTimeMillis();
283       timeToSleep=frameTime-d2+d1;   //40-(d2-d1)  = wanted refresh rate - time needed to do the actual repaint operations
284       try {
285           //if (waitingForCapture){runView.yield();}
286           //else {runView.sleep((timeToSleep>10) ? timeToSleep : 10);}   //sleep ... ms  
287           runView.sleep((timeToSleep>10) ? timeToSleep : 10);
288       }
289       catch (InterruptedException e) {
290           if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep3 "+e);}
291           return;
292       }
293         }
294         else {
295       try {
296           runView.sleep(frameTime+20);   //sleep ... ms  
297       }
298       catch (InterruptedException e) {
299           if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep4 "+e);}
300           return;
301       }
302         }
303     }
304     else {
305         try {
306       runView.sleep(deactiveTime);   //sleep ... ms  
307         } 
308         catch (InterruptedException e) {
309       if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep5 "+e);}
310       return;
311         }
312     }
313       }
314       else {
315     Dimension size=getSize();
316     if (size.width != oldSize.width || size.height != oldSize.height) {
317         //each time the parent window is resized, adapt the buffer image size
318         buffImg=null;
319         if (BufferG2D!=null) {
320       BufferG2D.dispose();
321       BufferG2D=null;
322         }
323         if (parent.parent.debug){System.out.println("Resizing JPanel in blank mode: ("+oldSize.width+"x"+oldSize.height+") -> ("+size.width+"x"+size.height+")");}
324         oldSize=size;
325         updateAntialias=true;
326         updateFont=true;
327     }
328     if (buffImg==null) {
329         buffImg=(BufferedImage) createImage(size.width,size.height);
330         updateAntialias=true;
331         updateFont=true;
332     }
333     if (BufferG2D == null) {
334         BufferG2D = buffImg.createGraphics();
335         updateAntialias=true;
336         updateFont=true;
337     }
338     if (updateFont){BufferG2D.setFont(VirtualSpaceManager.mainFont);updateFont=false;}
339     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;}
340     g2d = BufferG2D;
341     standardStroke=g2d.getStroke();
342     standardTransform=g2d.getTransform();
343     g2d.setPaintMode();
344     g2d.setColor(blankColor);
345     g2d.fillRect(0,0,getWidth(),getHeight());
346     repaint();
347     try {
348         runView.sleep(deactiveTime);   //sleep ... ms  
349     } 
350     catch (InterruptedException e) {
351         if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep5 "+e);}
352         return;
353     }
354       }
355   }
356   if (g2d != null) {
357       g2d.dispose();
358   }
359     }
360 
361     public void paint(Graphics g) {
362   synchronized (this) {
363       g2 = (Graphics2D) g;
364       if (buffImg != null) {
365     g2.drawImage(buffImg, null, 0, 0);
366       }
367         }
368     }
369 
370 }