/*
* TransparentPane.java
*
* Created on 18 September 2006, 13:14
*/
package uk.co.bytemark.vm.enigma.inquisition.gui.quiz;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.*;
import java.io.Serializable;
import javax.swing.*;
/**
* A transparent <tt>JPanel</tt> that draws a translucent image at the requested position.
*/
public class TransparentPane extends JPanel implements ActionListener {
private final static float TRANSPARENCY = 0.75f;
private final static int DELAY = 15;
private final static int STEPS = 15;
private Point position;
private Point originalPosition;
private BufferedImage image;
private AlphaComposite alphaComposite;
private Timer timer;
private double deltaX;
private double deltaY;
private double precisionX;
private double precisionY;
private int steps;
private Callback callback;
public TransparentPane() {
alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, TRANSPARENCY);
setOpaque(false);
}
void setTransparency(float transparency) {
alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, transparency);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (image == null)
return;
((Graphics2D) g).setComposite(alphaComposite);
int x = (int) (position.getX() - image.getWidth() / 2.0);
int y = (int) (position.getY() - image.getHeight() / 2.0);
((Graphics2D) g).drawImage(image, x, y, null);
}
void setPosition(Point position) {
this.position = position;
}
void activate(Point p, BufferedImage anImage) {
this.image = anImage;
setPosition(p);
originalPosition = p;
setVisible(true);
}
// TODO: do this overloading the other way round
void sendBackToOrigin(Callback aCallback, Point originPoint, BufferedImage anImage) {
this.image = anImage;
sendBackToOrigin(aCallback, originPoint);
}
void sendBackToOrigin(Callback aCallback, Point originPoint) {
originalPosition = originPoint;
sendBackToOrigin(aCallback);
}
/**
* Animate the fragment returning back to the bin
*/
void sendBackToOrigin(Callback aCallback) {
this.callback = aCallback;
precisionX = position.x;
precisionY = position.y;
int targetX = originalPosition.x;
int targetY = originalPosition.y;
steps = STEPS;
deltaX = (targetX - precisionX) / steps;
deltaY = (targetY - precisionY) / steps;
if (Math.abs(deltaX + deltaY) < 4) {
endAnimation();
return;
}
// System.out.println(deltaX + " " + deltaY + " " + steps);
timer = new Timer(DELAY, this);
timer.start();
}
private void endAnimation() {
// System.out.println("Ending animation");
// if (callback != null) {
callback.returnedToOrigin();
// }
setVisible(false);
}
public void actionPerformed(ActionEvent e) {
// TODO: eh? ...
// Hack to re-show the transparent pane if it gets turned off by mistake
if (!isVisible())
setVisible(true);
precisionX += deltaX;
precisionY += deltaY;
setPosition(new Point((int) precisionX, (int) precisionY));
repaint();
steps -= 1;
if (steps <= 0) {
timer.stop();
endAnimation();
}
}
interface Callback extends Serializable {
void returnedToOrigin();
}
}