package gmgen.gui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.IOException;
import java.util.Collections;
import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JPanel;
import javax.swing.UIManager;
import pcgen.core.PlayerCharacter;
import pcgen.io.PCGFile;
import pcgen.io.PCGIOHandler;
import pcgen.system.LanguageBundle;
/**
* A panel for previewing graphics in a file chooser. This includes previewing
* a character portrait referenced in a PCG file.
*
* TODO Support PCG portraits
*/
public final class ImagePreview
extends JPanel
implements PropertyChangeListener
{
private static final int SIZE = 200;
private static final String in_notAnImage
= LanguageBundle.getString("in_ImagePreview_notAnImage");
private static final String in_noCharacterPortrait
= LanguageBundle.getString("in_ImagePreview_noCharacterPortrait");
private final JFileChooser jfc;
private PlayerCharacter aPC;
private Image image;
/**
* Constructor
* @param jfc
*/
private ImagePreview(final JFileChooser jfc)
{
this.jfc = jfc;
jfc.addPropertyChangeListener(this);
jfc.setAccessory(this);
setPreferredSize(new Dimension(SIZE, SIZE));
}
/**
* Decorates a Swing file chooser with an image previewer.
*
* @param jfc the file chooser
*
* @return the file chooser
*/
public static JFileChooser decorateWithImagePreview(final JFileChooser jfc)
{
new ImagePreview(jfc); // hooks everything up
return jfc;
}
@Override
public void propertyChange(final PropertyChangeEvent evt)
{
try
{
updateImage(jfc.getSelectedFile());
}
catch (final IOException e)
{
e.printStackTrace(); // TODO: ack, suckage!
}
}
/**
* Update the image
* @param file
* @throws IOException
*/
private void updateImage(final File file)
throws IOException
{
if (file == null || !file.exists())
{
image = null;
return;
}
if (PCGFile.isPCGenCharacterFile(file))
{
aPC = new PlayerCharacter(Collections.emptyList());
new PCGIOHandler().readForPreview(aPC, file.getAbsolutePath());
final String portraitPath = aPC.getDisplay().getPortraitPath();
image = ImagePreview.isNullOrEmpty(portraitPath)
? null
: ImageIO.read(new File(portraitPath));
}
else
{
aPC = null;
image = ImageIO.read(file);
}
repaint();
}
@Override
protected void paintComponent(final Graphics g)
{
g.setColor(UIManager.getColor("Panel.background"));
g.fillRect(0, 0, getWidth(), getHeight());
final int textX = ImagePreview.getFontHeightHint(g);
final int textY = ImagePreview.SIZE - ImagePreview.getFontHeightHint(g);
if (image != null)
{
final int width = image.getWidth(null);
final int height = image.getHeight(null);
final int side = Math.max(width, height);
final double scale = SIZE / (double) side;
g.drawImage(image, 0, 0, (int) (scale * width),
(int) (scale * height), null);
// Annotate with original dimensions. Overlay black on white so
// the values are visible against most possible image backgrounds.
final String dim = width + " x " + height;
g.setColor(Color.black);
g.drawString(dim, textX, textY);
g.setColor(Color.white);
g.drawString(dim, textX - 1, textX - 1);
}
else
{
g.setColor(UIManager.getColor("Panel.foreground"));
// TODO: I18N
g.drawString(aPC == null ? ImagePreview.in_notAnImage : ImagePreview.in_noCharacterPortrait,
textX, textY);
}
}
private static boolean isNullOrEmpty(final String s)
{
return s == null || s.isEmpty();
}
private static int getFontHeightHint(final Graphics g) {
return g.getFontMetrics().getHeight();
}
}