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

📄 resourceimagemanager.java

📁 Novocode的 SWT 控件框架 丰富了MDI功能
💻 JAVA
字号:
/*******************************************************************************
 * Copyright (c) 2004 Stefan Zeiger and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.novocode.com/legal/epl-v10.html
 * 
 * Contributors:
 *     Stefan Zeiger (szeiger@novocode.com) - initial API and implementation
 *******************************************************************************/

package com.novocode.naf.gui.image;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.*;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

import com.novocode.naf.LogSettings;
import com.novocode.naf.app.*;


/**
 * Manages a pool of shared images which are loaded as resources.
 * 
 * @author Stefan Zeiger (szeiger@novocode.com)
 * @since Nov 26, 2003
 */

public final class ResourceImageManager implements IImageManager
{
  private final Map<String, IManagedImage> images;
  private final Display display;
  private final boolean autoDispose;
  private final URL baseURL;


  private final class RefCountImage implements IManagedImage
  {
    private final String resname;
    private Image image;
    private int references;
    
    RefCountImage(String resname, Image image)
    {
      this.resname = resname;
      this.image = image;
    }

    public String getName() { return resname; }

    public synchronized Image acquire() throws NAFException
    {
      if(image == null) throw new NAFException("Can't acquire image: Image has already been disposed");
      references++;
      return image;
    }

    synchronized void release(boolean dispose) throws NAFException
    {
      if(references == 0) throw new NAFException("Can't return image: No references left");
      references--;
      if(autoDispose && references == 0 && dispose) dispose(true);
    }

    public synchronized void release() throws NAFException
    {
      release(true);
    }
    
    synchronized void dispose(boolean removeFromManager)
    {
      if(image == null) return;
      if(LogSettings.IMAGEMANAGER_DEBUG_STDOUT) System.out.println("ImageManager: Disposing of image "+resname);
      if(removeFromManager)
      {
        synchronized(ResourceImageManager.this)
        {
          images.remove(resname);
        }
      }
      image.dispose();
      image = null;
    }
  }


  private final class SystemImage implements IManagedImage
  {
    private final String resname;
    private final Image image;
    
    SystemImage(String resname, Image image)
    {
      this.resname = resname;
      this.image = image;
    }

    public String getName() { return resname; }

    public Image acquire() { return image; }

    public void release() {}
  }


  /**
   * Create a new ImageManager.
   */

  public ResourceImageManager(URL baseURL, Display display, boolean autoDispose)
  {
    this.baseURL = baseURL;
    this.images = new HashMap<String, IManagedImage>();
    this.display = display;
    this.autoDispose = autoDispose;
    
    display.addListener(SWT.Dispose, new Listener()
    {
      public void handleEvent(Event event)
      {
        disposeAll();
      }
    });
  }


  public synchronized IManagedImage getImage(String resURI) throws NAFException
  {
    IManagedImage mi = images.get(resURI);
    if(mi == null)
    {
      if(resURI.endsWith("#mask"))
      {
        boolean dispose = true;
        IManagedImage base = getImage(resURI.substring(0, resURI.length()-5));
        try
        {
          Image baseImage = base.acquire();
          ImageData baseData = baseImage.getImageData();
          int ttype = baseData.getTransparencyType();
          if(ttype == SWT.TRANSPARENCY_MASK || ttype == SWT.TRANSPARENCY_NONE)
          {
            dispose = false;
            return base;
          }
          ImageData maskData;
          if(ttype == SWT.TRANSPARENCY_PIXEL) maskData = baseData.getTransparencyMask();
          else /* TRANSPARENCY_ALPHA */ maskData = createMaskFromAlphaChannel(baseImage);
          if(maskData == null) return base;
          mi = new RefCountImage(resURI, new Image(display, baseData, maskData));
        }
        finally { if(base instanceof RefCountImage) ((RefCountImage)base).release(dispose); }
      }
      else if(resURI.endsWith("#alpha"))
      {
        boolean dispose = true;
        IManagedImage base = getImage(resURI.substring(0, resURI.length()-6));
        try
        {
          Image baseImage = base.acquire();
          ImageData baseData = baseImage.getImageData();
          if(baseData.getTransparencyType() == SWT.TRANSPARENCY_ALPHA)
          {
            dispose = false;
            return base;
          }
          ImageData maskData = baseData.getTransparencyMask();
          if(maskData == null) return base;
          mi = new RefCountImage(resURI, new Image(display, baseData, maskData));
        }
        finally { if(base instanceof RefCountImage) ((RefCountImage)base).release(dispose); }
      }
      else if(resURI.endsWith("#gray"))
      {
        IManagedImage base = getImage(resURI.substring(0, resURI.length()-5));
        try
        {
          Image baseImage = base.acquire();
          mi = new RefCountImage(resURI, new Image(display, baseImage, SWT.IMAGE_GRAY));
        }
        finally { base.release(); }
      }
      else if(resURI.startsWith("sysimage:")) // system image
      {
        String specialName = resURI.substring(9);
        Image img;
        if(specialName.equals("error")) img = display.getSystemImage(SWT.ICON_ERROR);
        else if(specialName.equals("information")) img = display.getSystemImage(SWT.ICON_INFORMATION);
        else if(specialName.equals("warning")) img = display.getSystemImage(SWT.ICON_WARNING);
        else if(specialName.equals("question")) img = display.getSystemImage(SWT.ICON_QUESTION);
        else if(specialName.equals("working")) img = display.getSystemImage(SWT.ICON_WORKING);
        else throw new NAFException("Unknown system image name \""+specialName+"\"");
        if(img == null) mi = new RefCountImage(resURI, new Image(display, 0, 0));
        else mi = new SystemImage(resURI, img);
      }
      else
      {
        InputStream in = null;
        try
        {
          in = new URL(baseURL, resURI).openStream();
          mi = new RefCountImage(resURI, new Image(display, in));
        }
        catch(MalformedURLException ex)
        {
          throw new NAFException("Error creating URL object for image resource URL \""+resURI+"\"", ex);
        }
        catch(IOException ex)
        {
          throw new NAFException("Error loading image resource \""+resURI+"\"", ex);
        }
        finally
        {
          if(in != null) try { in.close(); } catch(IOException ignored) {}
        }
      }
      images.put(resURI, mi);
    }
    return mi;
  }


  public synchronized IManagedImage getAlphaRemappedImage(String resname) throws NAFException
  {
    if(resname.indexOf("#alpha") == -1) resname = resname + "#alpha";
    return getImage(resname);
  }


  public synchronized IManagedImage getMaskRemappedImage(String resname) throws NAFException
  {
    if(resname.indexOf("#mask") == -1) resname = resname + "#mask";
    return getImage(resname);
  }


  public synchronized IManagedImage getAlphaRemappedGrayImage(String resname) throws NAFException
  {
    if(resname.indexOf("#alpha") == -1) resname = resname + "#alpha";
    if(resname.indexOf("#gray") == -1) resname = resname + "#gray";
    return getImage(resname);
  }


  public synchronized IManagedImage getMaskRemappedGrayImage(String resname) throws NAFException
  {
    if(resname.indexOf("#mask") == -1) resname = resname + "#mask";
    if(resname.indexOf("#gray") == -1) resname = resname + "#gray";
    return getImage(resname);
  }


  private static ImageData createMaskFromAlphaChannel(Image img)
  {
    Rectangle bounds = img.getBounds();
    ImageData imgData = img.getImageData();
    PaletteData palette = new PaletteData(new RGB[] { new RGB(255,255,255), new RGB(0,0,0) });
    ImageData alphaData = new ImageData(bounds.width, bounds.height, 1, palette);
    for(int x=0; x<bounds.width; x++)
    {
      for(int y=0; y<bounds.height; y++)
      {
        int alpha = imgData.getAlpha(x, y);
        if(alpha > 127) alphaData.setPixel(x, y, 0xFFFFFF);
      }
    }
    return alphaData;
  }


  /*private static ImageData createGrayImage(Image img)
  {
    Rectangle bounds = img.getBounds();
    ImageData imgData = img.getImageData();
    ImageData mask = imgData.getTransparencyMask();
    System.out.println("Mask: "+mask);
    PaletteData palette = new PaletteData(0xff0000, 0x00ff00, 0x0000ff);
    ImageData grayData = new ImageData(bounds.width, bounds.height, 32, palette);
    for(int x=0; x<bounds.width; x++)
    {
      for(int y=0; y<bounds.height; y++)
      {
        int pixel = imgData.getPixel(x, y);
        int r = (pixel & 0xff0000) >> 16;
        int g = (pixel & 0x00ff00) >> 8;
        int b = (pixel & 0x0000ff);
        int v = (r+g+b)/3;
        pixel = (v << 16) + (v << 8) + v;
        grayData.setPixel(x, y, pixel);
        int alpha = mask != null ? (mask.getPixel(x, y) == 1 ? 255: 0) : imgData.getAlpha(x, y);
        System.out.println(alpha);
        grayData.setAlpha(x, y, alpha);
      }
    }
    return grayData;
  }*/


  public synchronized void disposeUnallocatedImages()
  {
    for(Iterator<IManagedImage> it = images.values().iterator(); it.hasNext();)
    {
      IManagedImage mi = it.next();
      if(mi instanceof RefCountImage)
      {
        RefCountImage rci = (RefCountImage)mi;
        if(rci.references == 0)
        {
          rci.dispose(false);
          it.remove();
        }
      }
    }
  }


  public synchronized void disposeAll()
  {
    for(IManagedImage mi : images.values())
      if(mi instanceof RefCountImage) ((RefCountImage)mi).dispose(false);
    images.clear();
  }
  
  
  public static String absoluteURIFor(URL baseURL, String uri) throws NAFException
  {
    if(uri.startsWith("sysimage:")) return uri;
    try
    {
      return new URL(baseURL, uri).toExternalForm();
    }
    catch(MalformedURLException ex)
    {
      throw new NAFException("Error creating URL object for image URI \""+uri+"\"", ex);
    }
  }
}

⌨️ 快捷键说明

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