package ch.werner_randelshofer.gui;/*Copyright (C) 1999 Werner Randelshoferwerner.randelshofer@mythen.chhttp://www.mythen.ch/w.randelshofer/    Permission to use this release of ViewImage is herebygranted without fee provided that the complete copyrightnotice and this permission notice appear in all copiesand in supporting documentation.*/import ch.werner_randelshofer.gui.image.ILBMDecoder;import ch.werner_randelshofer.util.PropertyModel;import java.awt.BorderLayout;import java.awt.CheckboxMenuItem;import java.awt.Color;import java.awt.Container;import java.awt.Frame;import java.awt.Image;import java.awt.Menu;import java.awt.MenuItem;import java.awt.MenuShortcut;import java.awt.Panel;import java.awt.event.ActionListener;import java.awt.event.ActionEvent;import java.awt.event.ItemListener;import java.awt.event.ItemEvent;import java.awt.event.KeyEvent;import java.awt.event.*;import java.awt.image.ImageProducer;import java.beans.PropertyChangeEvent;import java.beans.PropertyChangeListener;import java.io.ByteArrayOutputStream;import java.io.EOFException;import java.io.InputStream;import java.io.IOException;import java.util.Vector;import javax.activation.CommandObject;import javax.activation.DataHandler;/*A JavaBeansActivation aware GIF and JPG image viewer.@author	Werner Randelshofer, Staldenmattweg 2, CH-6405 Immensee, Switzerland@version	1999-03-09	Created.*/public class ViewImageextends Panelimplements CommandObject, PropertyChangeListener, ActionListener, ItemListener	{	protected ImagePanel imagePanel_;	protected PropertyModel model_;	private CheckboxMenuItem ignorePixelAspectItem_,multipliedPixelAspectItem_,exactPixelAspectItem_;	private CheckboxMenuItem ignoreImageScaleItem_, exactImageScaleItem_;	private CheckboxMenuItem showAdditionalControlsItem_;	private CheckboxMenuItem backgroundWhiteItem_, backgroundBlackItem_;			public ViewImage()		{		setLayout(new BorderLayout());		add(imagePanel_ = new ImagePanel());		}	public void addMenuItems(Menu m)		{		Menu m2;		MenuItem mi;		CheckboxMenuItem cmi;			mi = new MenuItem("Half Size");		mi.setShortcut(new MenuShortcut(KeyEvent.VK_0));		mi.setActionCommand("halfSize");		mi.addActionListener(this);		m.add(mi);		mi = new MenuItem("Normal Size");		mi.setShortcut(new MenuShortcut(KeyEvent.VK_1));		mi.setActionCommand("normalSize");		mi.addActionListener(this);		m.add(mi);		mi = new MenuItem("Double Size");		mi.setShortcut(new MenuShortcut(KeyEvent.VK_2));		mi.setActionCommand("doubleSize");		mi.addActionListener(this);		m.add(mi);		m.addSeparator();		int imageScalePolicy = imagePanel_.getImageScalePolicy();		m2 = new Menu("Image Aspect");		cmi = new CheckboxMenuItem("Ignore?");		//cmi.setActionCommand("ignoreImageScale");		cmi.setState(imageScalePolicy == ImagePanel.SCALE_TO_VIEW_SIZE);		cmi.setEnabled(imageScalePolicy != ImagePanel.SCALE_TO_VIEW_SIZE);		cmi.addItemListener(this);		ignoreImageScaleItem_ = cmi;		m2.add(cmi);		cmi = new CheckboxMenuItem("Exact?");		//cmi.setActionCommand("exactImageScale");		cmi.setState(imageScalePolicy == ImagePanel.SCALE_TO_IMAGE_ASPECT);		cmi.setEnabled(imageScalePolicy != ImagePanel.SCALE_TO_IMAGE_ASPECT);		cmi.addItemListener(this);		exactImageScaleItem_ = cmi;		m2.add(cmi);		m.add(m2);		int pixelAspectPolicy = imagePanel_.getPixelAspectPolicy();		m2 = new Menu("Pixel Aspect");		cmi = new CheckboxMenuItem("Ignore?");		//cmi.setActionCommand("ignorePixelAspect");		cmi.setState(pixelAspectPolicy == ImagePanel.IGNORE_PIXEL_ASPECT);		cmi.setEnabled(pixelAspectPolicy != ImagePanel.IGNORE_PIXEL_ASPECT);		cmi.addItemListener(this);		ignorePixelAspectItem_ = cmi;		m2.add(cmi);		cmi = new CheckboxMenuItem("Multiplied?");		//cmi.setActionCommand("multipliedPixelAspect");		cmi.setState(pixelAspectPolicy == ImagePanel.MULTIPLIED_PIXEL_ASPECT);		cmi.setEnabled(pixelAspectPolicy != ImagePanel.MULTIPLIED_PIXEL_ASPECT);		cmi.addItemListener(this);		multipliedPixelAspectItem_ = cmi;		m2.add(cmi);		cmi = new CheckboxMenuItem("Exact?");		//cmi.setActionCommand("exactPixelAspect");		cmi.setState(pixelAspectPolicy == ImagePanel.EXACT_PIXEL_ASPECT);		cmi.setEnabled(pixelAspectPolicy != ImagePanel.EXACT_PIXEL_ASPECT);		cmi.addItemListener(this);		exactPixelAspectItem_ = cmi;		m2.add(cmi);		m.add(m2);		int bgColor = 0;		if (imagePanel_.getBackground().equals(Color.white) )			{ bgColor = 1; }		m2 = new Menu("Background");		cmi = new CheckboxMenuItem("Black?");		//cmi.setActionCommand("ignoreImageScale");		cmi.setState(bgColor == 0);		cmi.setEnabled(bgColor != 0);		cmi.addItemListener(this);		backgroundBlackItem_ = cmi;		m2.add(cmi);		cmi = new CheckboxMenuItem("White?");		//cmi.setActionCommand("exactImageScale");		cmi.setState(bgColor == 1);		cmi.setEnabled(bgColor != 1);		cmi.addItemListener(this);		backgroundWhiteItem_ = cmi;		m2.add(cmi);		m.add(m2);		}			/** Sets the command context for the bean. The receiver loads	the image data provided by the data handler and displays it. */	public void setCommandContext(String verb, DataHandler dh)	throws IOException		{		flush();		if (dh != null)			{			InputStream in = null;			try {				in = dh.getInputStream();				ByteArrayOutputStream out = new ByteArrayOutputStream(in.available());				byte[] buf = new byte[512];				for (int count=in.read(buf); count != -1; count=in.read(buf))					{					out.write(buf,0,count);					}				imagePanel_.setImage( getToolkit().createImage( out.toByteArray() ) );				packParent();				}			finally				{				try {					if (in != null)						{ in.close(); }					}				catch (IOException e) {} // ignore				}			}		}	/**	Frees any resources that have been allocated by this viewer.	*/	public void flush()		{		Image image = imagePanel_.getImage();		imagePanel_.setImage(null);		if (image != null)			{ image.flush(); }		}		/** Notifies the receiver that it has no heavy-weight parent	view anymore. The bean flushes all resources that it has	allocated. */	public void removeNotify()		{		super.removeNotify();		flush();		}		/** Sets the model object for shared properties. */	public synchronized void setPropertyModel(PropertyModel m)		{		if (model_ != null)			{ model_.removePropertyChangeListener(this); }		model_ = m;		if (model_ != null)			{			model_.addPropertyChangeListener(this);			updateProperties();			packParent();			}		}	/** Gets the model object for shared properties. */	public PropertyModel getPropertyModel()		{		if (model_ == null)			{ setPropertyModel(new PropertyModel()); }		return model_;		}		public void propertyChange(PropertyChangeEvent event)		{		String key = event.getPropertyName();		Object newValue = event.getNewValue();		if (key.equals("scaleFactor"))			{ updateScaleFactor(); }		else if (key.equals("pixelAspect"))			{ updatePixelAspect(); }		else if (key.equals("imageAspect"))			{ updateImageAspect(); }		else if (key.equals("background"))			{ updateBackground(); }		}	private void updateScaleFactor()		{		String newValue = getPropertyModel().getProperty("scaleFactor");		try 			{			double sf = Double.valueOf(newValue).doubleValue();			imagePanel_.setScaleFactor(sf,sf);			packParent();			}		catch (NullPointerException e)			{			getPropertyModel().put("scaleFactor","1.0");			}		catch (NumberFormatException e)			{			getPropertyModel().put("scaleFactor","1.0");			}		}	private void updatePixelAspect()		{		String newValue = getPropertyModel().getProperty("pixelAspect");		try	{			int policy = Integer.decode(newValue).intValue();			imagePanel_.setPixelAspectPolicy(policy);			if (ignorePixelAspectItem_ != null)				{				ignorePixelAspectItem_.setState(policy == ImagePanel.IGNORE_PIXEL_ASPECT);				ignorePixelAspectItem_.setEnabled(policy != ImagePanel.IGNORE_PIXEL_ASPECT);				multipliedPixelAspectItem_.setState(policy == ImagePanel.MULTIPLIED_PIXEL_ASPECT);				multipliedPixelAspectItem_.setEnabled(policy != ImagePanel.MULTIPLIED_PIXEL_ASPECT);				exactPixelAspectItem_.setState(policy == ImagePanel.EXACT_PIXEL_ASPECT);				exactPixelAspectItem_.setEnabled(policy != ImagePanel.EXACT_PIXEL_ASPECT);				}			}		catch (NumberFormatException e)			{			getPropertyModel().put("pixelAspect",String.valueOf(ImagePanel.EXACT_PIXEL_ASPECT));			}		catch (IllegalArgumentException e)			{			getPropertyModel().put("pixelAspect",String.valueOf(ImagePanel.EXACT_PIXEL_ASPECT));			}		catch (NullPointerException e)			{			getPropertyModel().put("pixelAspect",String.valueOf(ImagePanel.EXACT_PIXEL_ASPECT));			}		}	private void updateImageAspect()		{		String newValue = getPropertyModel().getProperty("imageAspect");		try	{			int policy = Integer.decode(newValue).intValue();			imagePanel_.setImageScalePolicy(policy);			if (ignoreImageScaleItem_ != null)				{				ignoreImageScaleItem_.setState(policy == ImagePanel.SCALE_TO_VIEW_SIZE);				ignoreImageScaleItem_.setEnabled(policy != ImagePanel.SCALE_TO_VIEW_SIZE);				exactImageScaleItem_.setState(policy == ImagePanel.SCALE_TO_IMAGE_ASPECT);				exactImageScaleItem_.setEnabled(policy != ImagePanel.SCALE_TO_IMAGE_ASPECT);				}			}		catch (NumberFormatException e)			{			getPropertyModel().put("imageAspect",String.valueOf(ImagePanel.SCALE_TO_IMAGE_ASPECT));			}		catch (IllegalArgumentException e)			{			getPropertyModel().put("imageAspect",String.valueOf(ImagePanel.SCALE_TO_IMAGE_ASPECT));			}		catch (NullPointerException e)			{			getPropertyModel().put("imageAspect",String.valueOf(ImagePanel.SCALE_TO_IMAGE_ASPECT));			}		}	private void updateBackground()		{		String newValue = getPropertyModel().getProperty("background");		try	{			int policy = Integer.decode(newValue).intValue();			if (policy == 0)				{				imagePanel_.setBackground(Color.black);				imagePanel_.setForeground(Color.white);				}			else if (policy == 1)				{				imagePanel_.setBackground(Color.white);				imagePanel_.setForeground(Color.black);				}			else				{				throw new IllegalArgumentException();				}			if (backgroundBlackItem_ != null)				{				backgroundBlackItem_.setState(policy == 0);				backgroundBlackItem_.setEnabled(policy != 0);				backgroundWhiteItem_.setState(policy == 1);				backgroundWhiteItem_.setEnabled(policy != 1);				}			imagePanel_.repaint();			}		catch (NumberFormatException e)			{			getPropertyModel().put("background","0");			}		catch (IllegalArgumentException e)			{			getPropertyModel().put("background","0");			}		catch (NullPointerException e)			{			getPropertyModel().put("background","0");			}		}	protected void packParent()		{		Container container = getParent();		if (container != null)			{			while (container.getParent() != null)				{ container = container.getParent(); }			}		if (container != null && container instanceof Frame)			{			((Frame)container).pack();			}		}	private void updateProperties()		{		updateScaleFactor();		updatePixelAspect();		updateImageAspect();		updateBackground();		}		public void actionPerformed(ActionEvent event)		{		String actionCommand = event.getActionCommand();		PropertyModel model = getPropertyModel();				if (actionCommand.equals("halfSize"))			{ model.put("scaleFactor","0.5"); }		else if (actionCommand.equals("normalSize"))			{ model.put("scaleFactor","1.0"); }		else if (actionCommand.equals("doubleSize"))			{ model.put("scaleFactor","2.0"); }		updateScaleFactor();		}	public void itemStateChanged(ItemEvent event)		{		PropertyModel properties = getPropertyModel();				//if ( isProcessingEvent_)		//	{ return; }		Object source = event.getSource();				//if (source == showAdditionalControlsItem_)		//	{ applyShowAdditionalControls(showAdditionalControlsItem_.getState()); }		if (event.getStateChange() == ItemEvent.SELECTED)			{			/*else*/ if (source == ignorePixelAspectItem_)				{				properties.put("pixelAspect",String.valueOf(ImagePanel.IGNORE_PIXEL_ASPECT));				}			else if (source == multipliedPixelAspectItem_)				{				properties.put("pixelAspect",String.valueOf(ImagePanel.MULTIPLIED_PIXEL_ASPECT));				}			else if (source == exactPixelAspectItem_)				{				properties.put("pixelAspect",String.valueOf(ImagePanel.EXACT_PIXEL_ASPECT));				}			else if (source == ignoreImageScaleItem_)				{				properties.put("imageAspect",String.valueOf(ImagePanel.SCALE_TO_VIEW_SIZE));				}			else if (source == exactImageScaleItem_)				{				properties.put("imageAspect",String.valueOf(ImagePanel.SCALE_TO_IMAGE_ASPECT));				}			else if (source == backgroundBlackItem_)				{				properties.put("background","0");				}			else if (source == backgroundWhiteItem_)				{				properties.put("background","1");				}			/*				else if (source == scaleChoice_)				{				double scale = 100;				switch (scaleChoice_.getSelectedIndex())					{					case 0: scale = 0.1; break;					case 1: scale = 0.25; break;					case 2: scale = 0.50; break;					case 3: scale = 0.75; break;					case 4: scale = 1; break;					case 5: scale = 2; break;					case 6: scale = 3; break;					case 7: scale = 4; break;					}				imagePanel_.setScaleFactor(scale,scale);				}			*/			}		}	public String toString()		{		return "JPG/GIF Image";		}	}