/*
* GISToolkit - Geographical Information System Toolkit
* (C) 2002, Ithaqua Enterprises Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package gistoolkit.server.mapclient;
import java.util.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import gistoolkit.server.mapclient.images.ImageSource;
/**
* Class to display an image to the client.
*/
public class ImagePanel extends JPanel{
/** The image to display */
private Image myImage = null;
/** Draw the image to the size of the panel. */
private boolean myScaleImage = true;
/** Scale the image to the sizeof the panel. */
public void setScaleImage(boolean inScaleImage) {myScaleImage = inScaleImage;}
/** The double buffer image */
private Image myDoubleBufferImage = null;
/** Internal class to handle pixels when the arrive from the image sent in. */
private class ImagePanelImageObserver implements ImageObserver{
/** Prevents overrunning the processor on show machines with redraws */
private long myTime = 0;
public boolean imageUpdate(Image img, int flags, int x, int y, int w, int h) {
if ((flags & ALLBITS) != 0) {
setSizeToImageSize();
update(getGraphics());
repaint();
}
else {
long tempTime = new Date().getTime();
if ((tempTime - myTime) > 500) {
setSizeToImageSize();
update(getGraphics());
repaint();
myTime = new Date().getTime();;
}
}
return true;
}
int myW = 0;
int myH = 0;
/** Sets the preferred size and minimum size of this component. */
private void setSizeToImageSize(){
if (myImage != null){
int hbuf = 0;
int vbuf = 0;
if (getInsets() != null){
Insets i = getInsets();
hbuf = i.top + i.bottom;
vbuf = i.left + i.right;
}
int w = myImage.getWidth(this);
int h = myImage.getHeight(this);
if ((h > 0) && (w > 0) && (h != myH) && (w != myW)){
setSize(new Dimension(w+hbuf,h+vbuf));
setPreferredSize(new Dimension(w+hbuf,h+vbuf));
setMinimumSize(new Dimension(w+hbuf,h+vbuf));
getParent().invalidate();
myW = w;
myH = h;
}
}
}
}
/** Internal class to handle events from the component. */
private class ImagePanelComponentListener extends ComponentAdapter{
public void componentResized(ComponentEvent e){
if ((getWidth() > 0) && (getHeight() > 0)){
myDoubleBufferImage = createImage(getWidth(), getHeight());
update(getGraphics());
}
}
}
private ImagePanelComponentListener myComponentListener = new ImagePanelComponentListener();
/** Listen for image events from the image that was sent in. */
private ImagePanelImageObserver myImageObserver = new ImagePanelImageObserver();
/** Creates new ImagePanel */
public ImagePanel() {
super();
addComponentListener(myComponentListener);
}
/** set the image to display. */
public synchronized void setImage(Image inImage){
myImage = inImage;
myImageObserver.setSizeToImageSize();
update(getGraphics());
repaint();
}
/** Draw the image on the screen */
public void paint(Graphics inGraphics){
try{
inGraphics.drawImage(myDoubleBufferImage, 0, 0, this);
}
catch (Exception e){
System.out.println(e);
e.printStackTrace();
}
}
/** overload the draw method */
public void update(Graphics inGraphics){
if (myImage != null){
if ((getWidth() > 0) && (getHeight() > 0)){
int w = getWidth();
int h = getHeight();
if ((h>0) && (w>0)){
if (myDoubleBufferImage == null) myDoubleBufferImage = createImage(w, h);
if (myDoubleBufferImage != null){
Graphics g = myDoubleBufferImage.getGraphics();
super.paint(g);
Border b = getBorder();
if (b != null){
Insets i = b.getBorderInsets(this);
if (i != null){
w = w-(i.right+i.left);
h = h-(i.bottom+i.top);
g=g.create(i.left, i.top, w, h);
}
}
if (myDrawer == null){
if (myScaleImage){
g.drawImage(myImage, 0,0, w, h, getBackground(), myImageObserver);
}
else{
g.drawImage(myImage, 0,0, getBackground(), myImageObserver);
}
}
else {
g.setColor(getBackground());
myDrawer.draw(g, myImage, w, h, myImageObserver);
}
repaint();
}
}
}
}
}
/** Reference to the current drawer, it is able to change the way the picture is drawn */
private Drawer myDrawer = null;
/** Set the drawer into the image panel */
public void setDrawer(Drawer inDrawer){
if (myDrawer != null){
if (myDrawer instanceof MouseListener){
removeMouseListener((MouseListener)myDrawer);
}
if (myDrawer instanceof MouseMotionListener){
removeMouseMotionListener((MouseMotionListener) myDrawer);
}
if (myDrawer instanceof KeyListener){
removeKeyListener((KeyListener) myDrawer);
}
}
myDrawer = inDrawer;
if (inDrawer instanceof MouseListener){
addMouseListener((MouseListener) inDrawer);
}
if (inDrawer instanceof MouseMotionListener){
addMouseMotionListener((MouseMotionListener) inDrawer);
}
if (inDrawer instanceof KeyListener){
addKeyListener((KeyListener) inDrawer);
requestFocus();
}
}
/** Testing. */
public static void main(String[] inArgs){
JDialog tempDialog = new JDialog();
tempDialog.setModal(true);
ImagePanel tempImagePanel = new ImagePanel();
tempImagePanel.setImage(new ImageSource().getImage("g.png"));
tempImagePanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
tempDialog.setContentPane(tempImagePanel);
tempDialog.setSize(200,200);
tempDialog.setTitle("Testing the ImagePanel");
tempDialog.show();
System.exit(0);
}
}