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

Quick Search    Search Deep

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


1   /*   FILE: AppletViewPanel.java
2    *   DATE OF CREATION:   Jul 04 2002
3    *   AUTHOR :            Emmanuel Pietriga (emmanuel.pietriga@xrce.xerox.com)
4    *   MODIF:              Tue Aug 05 14:56:46 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 - for use in JApplet only
34   * @author Emmanuel Pietriga
35   */
36  public class AppletViewPanel 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 AppletViewPanel(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(drawnGlyphs){
157               drawnGlyphs.removeAllElements();
158               uncoef=(float)((cams[nbcam].focal+cams[nbcam].altitude)/cams[nbcam].focal);
159               viewW=this.getSize().width;//compute region's width and height
160               viewH=this.getSize().height;
161               viewWHu=(long)(cams[nbcam].posx+this.getSize().width/2*uncoef);//compute region seen from this view
162               viewHHu=(long)(cams[nbcam].posy+this.getSize().height/2*uncoef);//through camera
163               viewWLu=(long)(cams[nbcam].posx-this.getSize().width/2*uncoef);
164               viewHLu=(long)(cams[nbcam].posy-this.getSize().height/2*uncoef);
165               if (parent.detectMultipleFullFills){//if detect multiple fills option is ON
166             for (Enumeration en=cams[nbcam].parentSpace.getVisibleGlyphs().elements();en.hasMoreElements();){
167                 gl=(Glyph)(en.nextElement());
168                 if (gl.drawMe(viewWHu,viewHHu,viewWLu,viewHLu,camIndex)){
169               cams[nbcam].parentSpace.drewGlyph(gl,camIndex);
170               gl.project(cams[nbcam],this);
171                 }
172             }
173             //drawnGlyphs=cams[nbcam].parentSpace.getDrawnGlyphs(camIndex);
174             beginAt=0;
175             for (int j=drawnGlyphs.size()-1;j>=0;j--){//glyphs must have been projected because fillsView uses
176                 if (((Glyph)drawnGlyphs.elementAt(j)).fillsView(viewW,viewH,cams[nbcam].getIndex())){//projected coords
177               beginAt=j;
178               break;
179                 }
180             }
181             for (int j=beginAt;j<drawnGlyphs.size();j++){
182                 gl=(Glyph)drawnGlyphs.elementAt(j);
183                 if (gl.isVisible()){
184               gl.draw(g2d,size.width,size.height,cams[nbcam].getIndex(),standardStroke,standardTransform);
185                 }
186             }
187               }
188               else {//if detect multiple fills option is OFF
189             for (Enumeration en=cams[nbcam].parentSpace.getVisibleGlyphs().elements();en.hasMoreElements();){
190                 gl=(Glyph)(en.nextElement());
191                 if (gl.drawMe(viewWHu,viewHHu,viewWLu,viewHLu,camIndex)){
192               //if glyph is at least partially visible in the reg. seen from this view, display
193               synchronized(gl){
194                   gl.project(cams[nbcam],this);
195                   if (gl.isVisible()){
196                 gl.draw(g2d,size.width,size.height,cams[nbcam].getIndex(),standardStroke,standardTransform);
197                   }
198               }
199               cams[nbcam].parentSpace.drewGlyph(gl,camIndex);
200                 }
201             }
202               }
203           }
204             }
205         }
206         if (inside){//deal with mouse glyph only if mouse cursor is inside this window
207             try {
208           parent.mouse.unProject(cams[activeLayer],this); //we project the mouse cursor wrt the appropriate coord sys
209           if (computeListAtEachRepaint && parent.mouse.isSensitive()){
210               parent.mouse.computeMouseOverList(evH,cams[activeLayer]);
211           }
212             }
213             catch (NullPointerException ex) {if (parent.parent.debug){System.err.println("viewpanel.run.drawdrag "+ex);}}
214             g2d.setColor(parent.mouse.color);
215             if (drawDrag){g2d.drawLine(origDragx,origDragy,parent.mouse.mx,parent.mouse.my);}
216             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));}
217             if (drawOval){
218           if (circleOnly){
219               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));
220           }
221           else {
222               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));
223           }
224             }
225             if (drawVTMcursor){
226           synchronized(this){
227               g2d.setXORMode(backColor);
228               parent.mouse.draw(g2d);
229               oldX=parent.mouse.mx;
230               oldY=parent.mouse.my;
231           }
232             }
233         }
234         //end drawing here
235         if (g2d == BufferG2D) {
236             repaint();
237         }
238         d2=System.currentTimeMillis();
239         timeToSleep=frameTime-d2+d1;   //40-(d2-d1)  = wanted refresh rate - time needed to do the actual repaint operations
240           }
241       }
242       catch (NullPointerException ex0){if (parent.parent.debug){System.err.println("viewpanel.run (probably due to buffImg.createGraphics()) "+ex0);}}
243       //either we do - BETTER UNDER Win32
244       try {
245           runView.sleep((timeToSleep>10) ? timeToSleep : 10);   //sleep ... ms  
246       } 
247       catch (InterruptedException e) {
248           if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep2 "+e);}
249           return;
250       }
251       //or this   both seem to work well (have to test on several config) - BETTER UNDER SOLARIS
252       //Thread.yield();
253         }
254         else if (updateMouseOnly){
255       updateMouseOnly=false;//do this first as the thread can be interrupted inside this branch and we want to catch new requests for repaint
256       d1=System.currentTimeMillis();
257       try {
258           parent.mouse.unProject(cams[activeLayer],this); //we project the mouse cursor wrt the appropriate coord sys
259           if (computeListAtEachRepaint && parent.mouse.isSensitive()){parent.mouse.computeMouseOverList(evH,cams[activeLayer]);}
260       }
261       catch (NullPointerException ex) {if (parent.parent.debug){System.err.println("viewpanel.run.drawdrag "+ex);}}
262       if (drawVTMcursor){
263           synchronized(this){
264         try {
265             g2d.setXORMode(backColor);
266             g2d.setColor(parent.mouse.color);
267             g2d.drawLine(oldX-10,oldY,oldX+10,oldY);
268             g2d.drawLine(oldX,oldY-10,oldX,oldY+10);
269             g2d.drawLine(parent.mouse.mx-10,parent.mouse.my,parent.mouse.mx+10,parent.mouse.my);
270             g2d.drawLine(parent.mouse.mx,parent.mouse.my-10,parent.mouse.mx,parent.mouse.my+10);
271             oldX=parent.mouse.mx;
272             oldY=parent.mouse.my;
273         }//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
274         catch (NullPointerException ex47){if (parent.parent.debug){System.err.println("viewpanel.run.runview.drawVTMcursor "+ex47);}}
275           }
276       }
277       repaint();
278       d2=System.currentTimeMillis(); 
279       timeToSleep=frameTime-d2+d1;   //40-(d2-d1)  = wanted refresh rate - time needed to do the actual repaint operations
280       try {
281           runView.sleep((timeToSleep>10) ? timeToSleep : 10);   //sleep ... ms  
282       }
283       catch (InterruptedException e) {
284           if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep3 "+e);}
285           return;
286       }
287         }
288         else {
289       try {
290           runView.sleep(frameTime+20);   //sleep ... ms  
291       }
292       catch (InterruptedException e) {
293           if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep4 "+e);}
294           return;
295       }
296         }
297     }
298     else {
299         try {
300       runView.sleep(deactiveTime);   //sleep ... ms  
301         } 
302         catch (InterruptedException e) {
303       if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep5 "+e);}
304       return;
305         }
306     }
307       }
308       else {
309     Dimension size=getSize();
310     if (size.width != oldSize.width || size.height != oldSize.height) {
311         //each time the parent window is resized, adapt the buffer image size
312         buffImg=null;
313         if (BufferG2D!=null) {
314       BufferG2D.dispose();
315       BufferG2D=null;
316         }
317         if (parent.parent.debug){System.out.println("Resizing JPanel in blank mode: ("+oldSize.width+"x"+oldSize.height+") -> ("+size.width+"x"+size.height+")");}
318         oldSize=size;
319         updateAntialias=true;
320         updateFont=true;
321     }
322     if (buffImg==null) {
323         buffImg=(BufferedImage) createImage(size.width,size.height);
324         updateAntialias=true;
325         updateFont=true;
326     }
327     if (BufferG2D == null) {
328         BufferG2D = buffImg.createGraphics();
329         updateAntialias=true;
330         updateFont=true;
331     }
332     if (updateFont){BufferG2D.setFont(VirtualSpaceManager.mainFont);updateFont=false;}
333     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;}
334     g2d = BufferG2D;
335     standardStroke=g2d.getStroke();
336     standardTransform=g2d.getTransform();
337     g2d.setPaintMode();
338     g2d.setColor(blankColor);
339     g2d.fillRect(0,0,getWidth(),getHeight());
340     repaint();
341     try {
342         runView.sleep(deactiveTime);   //sleep ... ms  
343     } 
344     catch (InterruptedException e) {
345         if (parent.parent.debug){System.err.println("viewpanel.run.runview.sleep5 "+e);}
346         return;
347     }
348       }
349   }
350   if (g2d != null) {
351       g2d.dispose();
352   }
353     }
354 
355     public void paint(Graphics g) {
356   synchronized (this) {
357       g2 = (Graphics2D) g;
358       if (buffImg != null) {
359     g2.drawImage(buffImg, null, 0, 0);
360       }
361         }
362     }
363 
364 }