⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 myimageview.java

📁 Vyger offers a D & D and Rogue-like environment in a graphical online roleplay game.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package wotlas.utils;

import java.awt.*;
import java.awt.event.*;
import java.awt.image.ImageObserver;
import java.io.*;
import java.net.*;
import java.util.Dictionary;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.text.html.*;
import javax.swing.event.*;

/**
 *  Enhanced Image View for HTML documents. Thanks to JavaWorld for the tip.
 */

public class MyImageView extends View implements ImageObserver, MouseListener,
                                                 MouseMotionListener
{

    // --- Attribute Values ------------------------------------------
    
    public static final String
    	TOP = "top",
    	TEXTTOP = "texttop",
    	MIDDLE = "middle",
    	ABSMIDDLE = "absmiddle",
    	CENTER = "center",
    	BOTTOM = "bottom";
    

    // --- Construction ----------------------------------------------

    /**
     * Creates a new view that represents an IMG element.
     *
     * @param elem the element to create a view for
     */
    public MyImageView(Element elem) {
    	super(elem);
    	initialize(elem);
	StyleSheet sheet = getStyleSheet();
	attr = sheet.getViewAttributes(this);
    }
    
    
    private void initialize( Element elem ) {
	synchronized(this) {
	    loading = true;
	    fWidth = fHeight = 0;
	}
	int width = 0;
	int height = 0;
	boolean customWidth = false;
	boolean customHeight = false;
	try {
	    fElement = elem;
        
	    // Request image from document's cache:
	    AttributeSet attr = elem.getAttributes();
            if (isURL()) {
	      URL src = getSourceURL();

	      if( src != null ) {
		  Dictionary cache = (Dictionary) getDocument().getProperty(IMAGE_CACHE_PROPERTY);
		  if( cache != null )
		      fImage = (Image) cache.get(src);
		  else
		      fImage = Toolkit.getDefaultToolkit().getImage(src);
	      }
            }
            else {

              /******** Code to load from relative path *************/
              String src =
                (String) fElement.getAttributes().getAttribute
                   (HTML.Attribute.SRC);
              //System.out.println("before src: " + src);
              src = processSrcPath(src);

              fImage = Toolkit.getDefaultToolkit().getImage(src);
              
              if(fImage==null) {
                 URL imUrl = getClass().getResource(src);
                 fImage = Toolkit.getDefaultToolkit().getImage(imUrl);
              }
              
              if(fImage!=null)              
                 try { waitForImage(); }
                 catch (InterruptedException e) { fImage = null; }
              /******************************************************/

            }
	
	    // Get height/width from params or image or defaults:
	    height = getIntAttr(HTML.Attribute.HEIGHT,-1);
	    customHeight = (height>0);
	    if( !customHeight && fImage != null )
		height = fImage.getHeight(this);
	    if( height <= 0 )
		height = DEFAULT_HEIGHT;
		
	    width = getIntAttr(HTML.Attribute.WIDTH,-1);
	    customWidth = (width>0);
	    if( !customWidth && fImage != null )
		width = fImage.getWidth(this);
	    if( width <= 0 )
		width = DEFAULT_WIDTH;

	    // Make sure the image starts loading:
	    if( fImage != null )
		if( customWidth && customHeight )
		    Toolkit.getDefaultToolkit().prepareImage(fImage,height,
							     width,this);
		else
		    Toolkit.getDefaultToolkit().prepareImage(fImage,-1,-1,
							     this);
	
            /********************************************************
            // Rob took this out. Changed scope of src.
	    if( DEBUG ) {
		if( fImage != null )
		    System.out.println("ImageInfo: new on "+src+
				       " ("+fWidth+"x"+fHeight+")");
		else
		    System.out.println("ImageInfo: couldn't get image at "+
				       src);
		if(isLink())
		    System.out.println("           It's a link! Border = "+
				       getBorder());
		//((AbstractDocument.AbstractElement)elem).dump(System.out,4);
	    }
            ********************************************************/
	} finally {
	    synchronized(this) {
		loading = false;
		if (customWidth || fWidth == 0) {
		    fWidth = width;
		}
		if (customHeight || fHeight == 0) {
		    fHeight = height;
		}
	    }
	}
    }

    /** Determines if path is in the form of a URL */
    private boolean isURL() {
          return true;

/*  THIS CODE IS TOO RESTRICTIVE :
        String src =
          (String) fElement.getAttributes().getAttribute(HTML.Attribute.SRC);
        return src.toLowerCase().startsWith("file") ||
               src.toLowerCase().startsWith("http"); */
    }    

    /** Checks to see if the absolute path is availabe thru an application
        global static variable or thru a system variable. If so, appends
        the relative path to the absolute path and returns the String. */
    private String processSrcPath(String src) {
      String val = src; 

      File imageFile = new File(src);
      if (imageFile.isAbsolute()) return src;

      //try to get application images path...
      /*if (PicTest.ApplicationImagePath != null) {
        String imagePath = PicTest.ApplicationImagePath;
        val = (new File(imagePath, imageFile.getPath())).toString();
      }*/
      //try to get system images path...
      else {
        String imagePath = System.getProperty("system.image.path.key");
        if (imagePath != null) {
          val = (new File(imagePath, imageFile.getPath())).toString();
        }
      }

      //System.out.println("src before: " + src + ", src after: " + val);
      return val;
    }

    /** Added this guy to make sure an image is loaded - ie no broken 
        images. So far its used only for images loaded off the disk (non-URL). 
        It seems to work marvelously. By the way, it does the same thing as
        MediaTracker, but you dont need to know the component its being 
        rendered on. Rob */
    private void waitForImage() throws InterruptedException { 
      int w = fImage.getWidth(this);
      int h = fImage.getHeight(this);

      while (true) {
        int flags = Toolkit.getDefaultToolkit().checkImage(fImage, w, h, this);

        if ( ((flags & ERROR) != 0) || ((flags & ABORT) != 0 ) )
          throw new InterruptedException();
        else if ((flags & (ALLBITS | FRAMEBITS)) != 0) 
          return;
        Thread.sleep(10);
        //System.out.println("rise and shine...");
      }
    }

    
    /**
     * Fetches the attributes to use when rendering.  This is
     * implemented to multiplex the attributes specified in the
     * model with a StyleSheet.
     */
    public AttributeSet getAttributes() {
	return attr;
    }

    /** Is this image within a link? */
    boolean isLink( ) {
        //! It would be nice to cache this but in an editor it can change
        // See if I have an HREF attribute courtesy of the enclosing A tag:
	AttributeSet anchorAttr = (AttributeSet)
	    fElement.getAttributes().getAttribute(HTML.Tag.A);
	if (anchorAttr != null) {
	    return anchorAttr.isDefined(HTML.Attribute.HREF);
	}
	return false;
    }
    
    /** Returns the size of the border to use. */
    int getBorder( ) {
        return getIntAttr(HTML.Attribute.BORDER, isLink() ?DEFAULT_BORDER :0);
    }
    
    /** Returns the amount of extra space to add along an axis. */
    int getSpace( int axis ) {
    	return getIntAttr( axis==X_AXIS ?HTML.Attribute.HSPACE :HTML.Attribute.VSPACE,
    			   0 );
    }
    
    /** Returns the border's color, or null if this is not a link. */
    Color getBorderColor( ) {
    	StyledDocument doc = (StyledDocument) getDocument();
        return doc.getForeground(getAttributes());
    }
    
  /** Returns the image's vertical alignment.
   */
  float getVerticalAlignment() {
	  String align = (String) fElement.getAttributes().getAttribute(HTML.Attribute.ALIGN);
	  if ( align != null ) {
	    align = align.toLowerCase();
	    if ( align.equals(TOP) || align.equals(TEXTTOP) )
	      return 0.0f;
	    else if ( align.equals(this.CENTER) || align.equals(MIDDLE) || align.equals(ABSMIDDLE) )
	      return 0.5f;
	  }
	  return 1.0f;		// default alignment is bottom
  }
    
  /**
   */
  boolean hasPixels( ImageObserver obs ) {
    return fImage != null && fImage.getHeight(obs)>0 && fImage.getWidth(obs)>0;
  }
    

  /** Return a URL for the image source, 
   * or null if it could not be determined.
   */
  private URL getSourceURL( ) {
 	  String src = (String) fElement.getAttributes().getAttribute(HTML.Attribute.SRC);
 	  if ( src==null ) return null;

	  URL reference = ((HTMLDocument)getDocument()).getBase();

         try {
 	    URL u = new URL(reference,src);
	    return u;
         } catch (MalformedURLException e) {
	    return null;
         }
  }
    
  /** Look up an integer-valued attribute. <b>Not</b> recursive.
   */
  private int getIntAttr(HTML.Attribute name, int deflt ) {
    AttributeSet attr = fElement.getAttributes();
    if ( attr.isDefined(name) ) {		// does not check parents!
      int i;
 	    String val = (String) attr.getAttribute(name);
 	    if ( val == null )
 	    	i = deflt;
 	    else
 	    	try {
 	        i = Math.max(0, Integer.parseInt(val));
 	    	} catch( NumberFormatException x ) {
 	    	i = deflt;
 	    }
	    return i;
	  } else
	    return deflt;
  }
    

  /** Establishes the parent view for this view.
   * Seize this moment to cache the AWT Container I'm in.
   */
  public void setParent(View parent) {
	  super.setParent(parent);
	  fContainer = parent!=null ?getContainer() :null;
	  if ( parent==null && fComponent!=null ) {
	    fComponent.getParent().remove(fComponent);
	    fComponent = null;
	  }
  }

  /** My attributes may have changed.
   */
  public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f) {
    if (DEBUG)
      System.out.println("ImageView: changedUpdate begin...");
    super.changedUpdate(e,a,f);
    float align = getVerticalAlignment();
    	
    int height = fHeight;
    int width  = fWidth;
    	
    initialize(getElement());
    	
    boolean hChanged = fHeight!=height;
    boolean wChanged = fWidth!=width;
    if( hChanged || wChanged || getVerticalAlignment()!=align ) {
      if (DEBUG)
        System.out.println("ImageView: calling preferenceChanged");
    	getParent().preferenceChanged(this,hChanged,wChanged);
    }

    if (DEBUG)
      System.out.println("ImageView: changedUpdate end; valign="+getVerticalAlignment());
  }


  // --- Painting --------------------------------------------------------

  /** Paints the image.
   *
   * @param g the rendering surface to use
   * @param a the allocated region to render into
   * @see View#paint
   */
  public void paint(Graphics g, Shape a) {
	  Color oldColor = g.getColor();
	  fBounds = a.getBounds();
    int border = getBorder();
	  int x = fBounds.x + border + getSpace(X_AXIS);
	  int y = fBounds.y + border + getSpace(Y_AXIS);
	  int width = fWidth;
	  int height = fHeight;
	  int sel = getSelectionState();
	
	  // Make sure my Component is in the right place:
    /*
	  if ( fComponent == null ) {
	    fComponent = new Component() { };
	    fComponent.addMouseListener(this);
	    fComponent.addMouseMotionListener(this);
	    fComponent.setCursor(Cursor.getDefaultCursor());	// use arrow cursor
	    fContainer.add(fComponent);
	  }
	  fComponent.setBounds(x,y,width,height);
	  */
	
	  // If no pixels yet, draw gray outline and icon:
	  if ( ! hasPixels(this) ) {
	    g.setColor(Color.lightGray);
	    g.drawRect(x,y,width-1,height-1);
	    g.setColor(oldColor);
	    loadIcons();
	    Icon icon = fImage==null ?sMissingImageIcon :sPendingImageIcon;
	    if ( icon != null )
	      icon.paintIcon(getContainer(), g, x, y);
	  }
		    
	  // Draw image:
	  if ( fImage != null ) {
	    g.drawImage(fImage,x, y,width,height,this);
	    // Use the following instead of g.drawImage when
	    // BufferedImageGraphics2D.setXORMode is fixed (4158822).

	    //  Use Xor mode when selected/highlighted.
	    //! Could darken image instead, but it would be more expensive.
      /*
	    if( sel > 0 )
	    	g.setXORMode(Color.white);
	    g.drawImage(fImage,x,y,width,height,this);
	    if( sel > 0 )
	        g.setPaintMode();
      */
	  }
	
	  // If selected exactly, we need a black border & grow-box:
	  Color bc = getBorderColor();
	  if ( sel == 2 ) {
	    // Make sure there's room for a border:
	    int delta = 2-border;
	    if ( delta > 0 ) {
	    	x += delta;
	    	y += delta;
	    	width -= delta<<1;
	    	height -= delta<<1;
	    	border = 2;
	    }
	    bc = null;
	    g.setColor(Color.black);
	    // Draw grow box:
	    g.fillRect(x+width-5,y+height-5,5,5);
	  }

	  // Draw border:
	  if ( border > 0 ) {
	    if ( bc != null )
	      g.setColor(bc);
	    // Draw a thick rectangle:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -