//{HEADER
/**
* This class is part of jnex 'Nexirius Application Framework for Java'
*
* Copyright (C) Nexirius GmbH, CH-4450 Sissach, Switzerland (www.nexirius.ch)
*
* <p>This library is free software; you can redistribute it and/or<br>
* modify it under the terms of the GNU Lesser General Public<br>
* License as published by the Free Software Foundation; either<br>
* version 2.1 of the License, or (at your option) any later version.</p>
*
* <p>This library is distributed in the hope that it will be useful,<br>
* but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU<br>
* Lesser General Public License for more details.</p>
*
* <p>You should have received a copy of the GNU Lesser General Public<br>
* License along with this library; if not, write to the Free Software<br>
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</p>
* </blockquote>
*
* <p>
* Nexirius GmbH, hereby disclaims all copyright interest in<br>
* the library jnex' 'Nexirius Application Framework for Java' written<br>
* by Marcel Baumann.</p>
*/
//}HEADER
package com.nexirius.framework.dataviewer;
import com.nexirius.framework.datamodel.StringModel;
import com.nexirius.util.XString;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.ImageObserver;
import java.io.File;
import java.net.URL;
/**
* This viewer is designed to show image data
*
* @author Marcel Baumann
*/
public class ImageViewer extends DataViewer {
public static final String s_viewername = "ImageViewer";
protected ImageCanvas imageCanvas = null;
protected boolean autoFit = false;
protected boolean resizePanel = false;
protected MissingImageHandler missingImageHandler = null;
protected Dimension oldImageSize = new Dimension(0, 0);
/**
* @param model The StringModel is used as a file name or as a URL of the image file.
*/
public ImageViewer(StringModel model) {
super(model);
}
/**
* Returns the associated string model
*/
public StringModel getModel() {
return (StringModel) getDataModel();
}
/**
* The user can define its own missing image handler which is used to display something
* specific if the assotiated string model is not pointing to a readable image file.
* By default a gray square is shown instead.
*
* @param handler The new image handler (or null)
*/
public void setMissingImageHandler(MissingImageHandler handler) {
missingImageHandler = handler;
}
/**
* Returns the Swing JPanel which is used to draw the image.
*/
public JPanel getJPanel() {
return (JPanel) getJComponent();
}
/**
* Creates the actual JPanel
*/
public void create() {
JPanel panel = new JPanel(new BorderLayout());
panel.setBorder(new EtchedBorder());
setJComponent(panel);
imageCanvas = new ImageCanvas();
panel.add(BorderLayout.CENTER, imageCanvas);
imageCanvas.setPreferredSize(new Dimension(100, 100));
update();
}
/**
* When true then the image is stretched to the size of the bounding panel (default: true)
*/
public void setAutoFit(boolean on) {
autoFit = on;
}
/**
* When true then the image is stretched to the size of the bounding panel (default: true)
*/
public boolean getAutoFit() {
return autoFit;
}
/**
* When true then the images size changes the preferred size of the bounding panel (default: false)
* (This parameter is ignored when autoFit == true)
*/
public void setResizePanel(boolean on) {
resizePanel = on;
}
/**
* When true then the images size changes the preferred size of the bounding panel (default: false)
* (This parameter is ignored when autoFit == true)
*/
public boolean getResizePanel() {
return resizePanel;
}
/**
* Set the new size of the panel
*/
protected void resizePanel(Dimension size) {
if (oldImageSize.equals(size)) {
return;
}
if (isCreated()) {
if (resizePanel) {
imageCanvas.setSize(size);
}
oldImageSize = size;
Border border = getJComponent().getBorder();
if (border != null) {
Insets insets = border.getBorderInsets(getJComponent());
size = new Dimension(size.width + insets.left + insets.right, size.height + insets.top + insets.bottom);
}
getJComponent().setPreferredSize(size);
getJComponent().invalidate();
getJComponent().revalidate();
}
}
/**
* Use the new string value of the assotiated model as an existing file name or as a URL
* and load and paint the associated image.
*/
public void update() {
if (isCreated()) {
if (getModel().isExceptional() || getModel().getText().length() == 0) {
imageCanvas.setImage(null);
} else {
String name = getModel().getText();
ImageIcon icon = (ImageIcon) getFactory().getClientResource().getIcon(name);
if (icon != null) {
imageCanvas.setImage(icon.getImage());
} else {
try {
File f = new File(name);
Image img;
if (f.exists()) {
// // FIX Version 2.0 url = f.toURL();
// XString xs = new XString("file:/" + name);
//
// xs.replace("\\", "/");
// url = new URL(xs.toString());
img = ImageIO.read(f);
} else {
URL url = new URL(name);
img = imageCanvas.getToolkit().getImage(url);
}
imageCanvas.setImage(img);
//
//
// Image img = null;
//
// if (f.exists()) {
// img = imageCanvas.getToolkit().getImage(f.getPath());
// } else {
// URL url = null;
// url = new URL(name);
// img = imageCanvas.getToolkit().getImage(url);
// }
//
// imageCanvas.setImage(img);
} catch (Exception ex) {
ex.printStackTrace(); // FIX
imageCanvas.setImage(null);
}
}
}
}
}
/**
* Only for debugging
*/
public String getViewerName() {
return s_viewername;
}
/**
* Not implemented
*/
public void grabFocus() {
}
class ImageCanvas extends JPanel {
Image image = null;
ImageCanvas() {
setOpaque(true);
}
void setImage(Image image) {
this.image = image;
update();
}
void update() {
if (this.isShowing()) {
paint(getGraphics());
}
}
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
if ((infoflags & (ImageObserver.PROPERTIES | ImageObserver.ERROR)) != 0) {
synchronized (image) {
image.notify();
}
}
return super.imageUpdate(img, infoflags, x, y, width, height);
}
public void paint(Graphics g) {
if (g == null) {
return;
}
super.paint(g);
Dimension size = getSize();
if (image == null) {
if (missingImageHandler != null) {
missingImageHandler.paint(this, g);
} else {
g.setColor(Color.white);
g.fillRect(0
, 0
, size.width
, size.height);
g.setColor(Color.gray);
int frame = 10;
g.fillRect(frame
, frame
, size.width - 2 * frame
, size.height - 2 * frame);
}
} else {
MediaTracker tracker;
tracker = new MediaTracker(this);
tracker.addImage(image, 0);
new ImagePainter(tracker, g);
}
}
class ImagePainter implements Runnable {
Graphics g;
private MediaTracker tracker;
public ImagePainter(MediaTracker tracker, Graphics g) {
this.tracker = tracker;
this.g = g;
new Thread(this).run();
}
private void repaint() {
if (autoFit) {
Dimension size = getSize();
Dimension imageSize = new Dimension(size.width, size.height);
if (!imageSize.equals(size)) {
// reload image with new size
image = image.getScaledInstance(size.width, size.height, Image.SCALE_SMOOTH);
}
// repaint image
g.drawImage(image
, 0
, 0
, size.width
, size.height
, getBackground()
, new JLabel());
} else {
Dimension size = new Dimension(image.getWidth(null), image.getHeight(null));
if (resizePanel) {
resizePanel(size);
}
// repaint image
g.drawImage(image
, 0
, 0
, size.width
, size.height
, getBackground()
, new JLabel());
}
}
public void run() {
int timeout = 30000;
while (true) {
if (timeout <= 0) {
return;
}
int sleep = 200;
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
e.printStackTrace(); //TODO
}
timeout -= sleep;
if (tracker.statusID(0, true) == MediaTracker.COMPLETE) {
repaint();
return;
}
}
}
}
}
}