/*
Copyright (c) 2003-2009 ITerative Consulting Pty Ltd. All Rights Reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted
provided that the following conditions are met:
o Redistributions of source code must retain the above copyright notice, this list of conditions and
the following disclaimer.
o Redistributions in binary form must reproduce the above copyright notice, this list of conditions
and the following disclaimer in the documentation and/or other materials provided with the distribution.
o This jcTOOL Helper Class software, whether in binary or source form may not be used within,
or to derive, any other product without the specific prior written permission of the copyright holder
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package DisplayProject.controls;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import DisplayProject.Constants;
import DisplayProject.GridCell;
import DisplayProject.GridField;
import DisplayProject.UIutils;
import DisplayProject.actions.AppData;
import DisplayProject.actions.HeightPolicy;
import DisplayProject.actions.WidgetSelected;
import DisplayProject.actions.WidthPolicy;
import DisplayProject.factory.GraphicFactory;
import Framework.CloneHelper;
import Framework.ImageData;
import com.sun.java.swing.plaf.windows.WindowsLabelUI;
/**
* simple JLable wrapper to implement PictureGraphic
*
*/
@SuppressWarnings("serial")
public class PictureGraphic extends JLabel implements Graphic {
private int imageGravity = Constants.CG_DEFAULT;
private int frameColor = 0;
private int frameWeight = 0;
private int imageSizePolicy = 0;
private ImageData imageValue = null;
private boolean negative = false;
public PictureGraphic() {
// TF:15/12/2009:DET-141:Set this up to allow inheriting of popup menu
this.setInheritsPopupMenu(true);
}
public Object getAppData() {
return AppData.get(this);
}
public boolean isSelected() {
return WidgetSelected.is(this);
}
public boolean isTransparent() {
return !this.isOpaque();
}
public void setAppData(Object appData) {
AppData.set(this, appData);
}
public void setSelected(boolean selected) {
WidgetSelected.set(this, selected);
}
public void setTransparent(boolean transparent) {
this.setOpaque(!transparent);
}
private void refreshImage() {
if ((this.imageValue == null) && (this.getIcon() != null)) {
this.imageValue = new ImageData((ImageIcon) this.getIcon());
}
ImageIcon icon = new ImageIcon(imageValue.getValue());
// TF:9/12/07:Added safety check
if (getWidth() > 0 && getHeight() > 0) {
switch (this.imageSizePolicy) {
case Constants.IS_NATURAL:
icon = new ImageIcon(this.imageValue.getValue());
break;
case Constants.IS_FIELD:
icon = new ImageIcon(this.imageValue.getValue()
.getScaledInstance(getWidth(), getHeight(),
Image.SCALE_DEFAULT));
break;
case Constants.IS_FIELDHEIGHT:
icon = new ImageIcon(this.imageValue.getValue()
.getScaledInstance(/* (w * getHeight()/h) - MARGIN */-1,
getHeight(), Image.SCALE_DEFAULT));
break;
case Constants.IS_FIELDWIDTH:
icon = new ImageIcon(this.imageValue.getValue()
.getScaledInstance(getWidth(), /*
* (h * getWidth()/w) -
* MARGIN
*/
-1, Image.SCALE_DEFAULT));
break;
}
}
this.setIcon(icon);
switch (this.imageGravity) {
case Constants.CG_BOTTOMCENTER:
this.setVerticalAlignment(SwingConstants.BOTTOM);
this.setHorizontalAlignment(SwingConstants.CENTER);
break;
case Constants.CG_BOTTOMLEFT:
this.setVerticalAlignment(SwingConstants.BOTTOM);
this.setHorizontalAlignment(SwingConstants.LEFT);
break;
case Constants.CG_BOTTOMRIGHT:
this.setVerticalAlignment(SwingConstants.BOTTOM);
this.setHorizontalAlignment(SwingConstants.RIGHT);
break;
case Constants.CG_CENTER:
this.setVerticalAlignment(SwingConstants.CENTER);
this.setHorizontalAlignment(SwingConstants.CENTER);
break;
case Constants.CG_DEFAULT:
this.setVerticalAlignment(SwingConstants.TOP);
this.setHorizontalAlignment(SwingConstants.LEFT);
break;
case Constants.CG_MIDDLELEFT:
this.setVerticalAlignment(SwingConstants.CENTER);
this.setHorizontalAlignment(SwingConstants.LEFT);
break;
case Constants.CG_MIDDLERIGHT:
this.setVerticalAlignment(SwingConstants.TOP);
this.setHorizontalAlignment(SwingConstants.RIGHT);
break;
case Constants.CG_TOPCENTER:
this.setVerticalAlignment(SwingConstants.TOP);
this.setHorizontalAlignment(SwingConstants.CENTER);
break;
case Constants.CG_TOPLEFT:
this.setVerticalAlignment(SwingConstants.TOP);
this.setHorizontalAlignment(SwingConstants.LEFT);
break;
case Constants.CG_TOPRIGHT:
this.setVerticalAlignment(SwingConstants.TOP);
this.setHorizontalAlignment(SwingConstants.RIGHT);
break;
}
revalidate();
}
/**
* In Forte, the minimum size of a button is a fraction bigger than the ones
* in Java, so we'll adjust this here.
*/
@Override
public Dimension getMinimumSize() {
GridCell cell = GridField.getConstraints(this);
Dimension d = new Dimension();
// If we're natural or to_parent then the minimum size is
// the UI minimum size
// TF:8/11/07: The above rule applies only to explicit size, not parent
// size
// as we can actually shrink the widget if we need to.
if (cell.getWidthPolicy() == Constants.SP_NATURAL /*
* ||
* cell.getWidthPolicy() ==
* Constants.SP_TO_PARENT
*/) {
d.width = this.getIcon().getIconWidth();
} else if (cell.getWidthPolicy() == Constants.SP_EXPLICIT) {
// Must be the same as the current size
d.width = getWidth();
} else {
d.width = 0;
}
if (cell.getHeightPolicy() == Constants.SP_NATURAL /*
* ||
* cell.getHeightPolicy() ==
* Constants.SP_TO_PARENT
*/) {
d.height = this.getIcon().getIconHeight();
} else if (cell.getHeightPolicy() == Constants.SP_EXPLICIT) {
// Must be the same as the current size
d.height = getHeight();
} else {
d.height = 0;
}
return d;
}
/**
* @return Returns the frameWeight.
*/
public int getFrameWeight() {
return this.frameWeight;
}
/**
* @param pFrameWeight
* The frameWeight to set.
*/
public void setFrameWeight(int pFrameWeight) {
this.frameWeight = pFrameWeight;
}
/**
* @return Returns the imageGravity.
*/
public int getImageGravity() {
return this.imageGravity;
}
/**
* @param pImageGravity
* The imageGravity to set.
*/
public void setImageGravity(int pImageGravity) {
this.imageGravity = pImageGravity;
refreshImage();
}
/**
* @return Returns the imageSizePolicy.
*/
public int getImageSizePolicy() {
return this.imageSizePolicy;
}
/**
* @param pImageSizePolicy
* The imageSizePolicy to set.
*/
public void setImageSizePolicy(int pImageSizePolicy) {
this.imageSizePolicy = pImageSizePolicy;
refreshImage();
}
/**
* @return Returns the imageValue.
*/
public ImageData getImageValue() {
return this.imageValue;
}
/**
* Set the image to display to the value passed
*
* @param pImageValue
* The imageValue to set.
*/
public void setImageValue(ImageData pImageValue) {
// TF:27/03/2009:Added check for self assignment
if (pImageValue != this.imageValue) {
this.imageValue = pImageValue;
refreshImage();
}
}
/**
* Set the bounds of the method. We cannot use setWidth or setHeight as
* these don't exist on the superclass.
*/
@Override
public void setBounds(int x, int y, int width, int height) {
Dimension minSize = this.getMinimumSize();
if (minSize != null && minSize.width > width) {
width = minSize.width;
}
if (minSize != null && minSize.height > height) {
height = minSize.height;
}
super.setBounds(x, y, width, height);
refreshImage();
}
public int getFrameColor() {
return this.frameColor;
}
public void setFrameColor(int pFrameColor) {
this.frameColor = pFrameColor;
}
/**
* Set the width policy for the picture graphic. This method is not
* thread-safe and should only be called at construction time or on the EDT.
* <p>
* <p>
* Due to the algorithm used to compute the minimum size of an image with an
* explicit size whose size is smaller than the actual image, this method
* must be called PRIOR to setting the size of the image.
*
* @param pWidthPolicy
*/
public void setWidthPolicy(int pWidthPolicy) {
GridCell gbc = GridField.getConstraints(this);
gbc.setWidthPolicy(pWidthPolicy);
if (getParent() != null) {
getParent().invalidate();
getParent().validate();
}
}
/**
* Get the height policy of this control
*/
public int getWidthPolicy() {
GridCell gbc = GridField.getConstraints(this);
return gbc.getWidthPolicy();
}
/**
* Set the height policy for the picture graphic. This method is not
* thread-safe and should only be called at construction time or on the EDT.
* <p>
* <p>
* Due to the algorithm used to compute the minimum size of an image with an
* explicit size whose size is smaller than the actual image, this method
* must be called PRIOR to setting the size of the image.
*
* @param pHeightPolicy
*/
public void setHeightPolicy(int pHeightPolicy) {
GridCell gbc = GridField.getConstraints(this);
gbc.setHeightPolicy(pHeightPolicy);
if (getParent() != null) {
getParent().invalidate();
getParent().validate();
}
}
/**
* Get the height policy of this control
*/
public int getHeightPolicy() {
GridCell gbc = GridField.getConstraints(this);
return gbc.getHeightPolicy();
}
@Override
public void doLayout() {
ImageIcon icon = (ImageIcon) this.getIcon();
int w = 0;
int h = 0;
if (WidthPolicy.get(this) == Constants.SP_NATURAL)
w = icon.getIconWidth();
else
w = getWidth();
if (HeightPolicy.get(this) == Constants.SP_NATURAL)
h = icon.getIconHeight();
else
h = getHeight();
Dimension dim = new Dimension(w, h);
this.setMinimumSize(dim);
super.doLayout();
}
public PictureGraphic cloneComponent() {
PictureGraphic clone = GraphicFactory.newPictureGraphic(getName(),
getImageGravity());
CloneHelper.cloneComponent(this, clone, new String[] { "imageValue",
"parent" });
return clone;
}
@Override
public void updateUI() {
setUI(new PictureGraphicUI());
invalidate();
}
public class PictureGraphicUI extends WindowsLabelUI {
private Rectangle paintIconR = new Rectangle();
private Rectangle paintTextR = new Rectangle();
private Rectangle paintViewR = new Rectangle();
@Override
public void paint(Graphics g, JComponent c) {
PictureGraphic label = (PictureGraphic) c;
String text = label.getText();
Icon icon = (label.isEnabled()) ? label.getIcon() : label
.getDisabledIcon();
if ((icon == null) && (text == null)) {
return;
}
// AGD:18/3/2008 The below line does not work for Java 1.6 recoded
// it to the next line. SwingUtilities2 should not be relied on.
// FontMetrics fm = SwingUtilities2.getFontMetrics(label, g);
FontMetrics fm = label.getFontMetrics(g.getFont());
paintIconR.x = paintIconR.y = paintIconR.width = paintIconR.height = 0;
layoutCL(label, fm, text, icon, paintViewR, paintIconR, paintTextR);
if (icon != null) {
Insets ins = PictureGraphic.this.getInsets();
int width = icon.getIconWidth();
// PM:28/07/2008:
if (width < 0)
width = PictureGraphic.this.getWidth() - ins.left - ins.right;
int height = icon.getIconHeight();
if (height < 0)
height = PictureGraphic.this.getHeight() - ins.top - ins.bottom;
BufferedImage buf = new BufferedImage(width, height,
BufferedImage.TYPE_INT_ARGB);
icon.paintIcon(label, buf.createGraphics(), 0, 0);
if (label.negative) {
buf = UIutils.invert(buf);
} else if (!label.isOpaque()) {
/*
* for transparent pictures
*/
//PM:25/4/08 move code to common method
UIutils.transparentImage(buf, label.getBackground());
}
ImageIcon img = new ImageIcon(buf);
img.paintIcon(c, g, 0, 0);
}
}
}
public boolean isNegative() {
return negative;
}
public void setNegative(boolean negative) {
this.negative = negative;
}
}