import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
public class AniSheetableJFrame extends JFrame
implements ActionListener {
public static final int INCOMING = 1;
public static final int OUTGOING = -1;
public static final float ANIMATION_DURATION = 1000f;
public static final int ANIMATION_SLEEP = 50;
JComponent sheet;
JPanel glass;
AnimatingSheet animatingSheet;
boolean animating;
int animationDirection;
Timer animationTimer;
long animationStart;
BufferedImage offscreenImage;
public AniSheetableJFrame (String name) {
super(name);
glass = (JPanel) getGlassPane();
glass.setLayout (new GridBagLayout());
animatingSheet = new AnimatingSheet();
animatingSheet.setBorder (new LineBorder(Color.black, 1));
}
public JComponent showJDialogAsSheet (JDialog dialog) {
sheet = (JComponent) dialog.getContentPane();
sheet.setBorder (new LineBorder(Color.black, 1));
glass.removeAll();
animationDirection = INCOMING;
startAnimation();
return sheet;
}
public void hideSheet() {
animationDirection = OUTGOING;
startAnimation();
// glass.setVisible(false);
}
private void startAnimation() {
glass.repaint();
// clear glasspane and set up animatingSheet
animatingSheet.setSource (sheet);
glass.removeAll();
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTH;
glass.add (animatingSheet, gbc);
gbc.gridy=1;
gbc.weighty = Integer.MAX_VALUE;
glass.add (Box.createGlue(), gbc);
glass.setVisible(true);
// start animation timer
animationStart = System.currentTimeMillis();
if (animationTimer == null)
animationTimer = new Timer (ANIMATION_SLEEP, this);
animating = true;
animationTimer.start();
}
private void stopAnimation() {
animationTimer.stop();
animating = false;
}
// used by the Timer
public void actionPerformed (ActionEvent e) {
if (animating) {
// calculate height to show
float animationPercent =
(System.currentTimeMillis() - animationStart) /
ANIMATION_DURATION;
animationPercent = Math.min (1.0f, animationPercent);
int animatingHeight = 0;
if (animationDirection == INCOMING) {
animatingHeight =
(int) (animationPercent * sheet.getHeight());
} else {
animatingHeight =
(int) ((1.0f - animationPercent) * sheet.getHeight());
}
// clip off that much from sheet and blit it
// into animatingSheet
animatingSheet.setAnimatingHeight (animatingHeight);
animatingSheet.repaint();
if (animationPercent >= 1.0f) {
stopAnimation();
if (animationDirection == INCOMING) {
finishShowingSheet();
} else {
glass.removeAll();
glass.setVisible(false);
}
}
}
}
private void finishShowingSheet() {
glass.removeAll();
GridBagConstraints gbc = new GridBagConstraints();
gbc.anchor = GridBagConstraints.NORTH;
glass.add (sheet, gbc);
gbc.gridy=1;
gbc.weighty = Integer.MAX_VALUE;
glass.add (Box.createGlue(), gbc);
// glass.setVisible(true);
glass.revalidate();
glass.repaint();
}
class AnimatingSheet extends JPanel {
Dimension animatingSize = new Dimension (0, 1);
JComponent source;
BufferedImage offscreenImage;
public AnimatingSheet () {
super();
setOpaque(true);
}
public void setSource (JComponent source) {
this.source = source;
animatingSize.width = source.getWidth();
makeOffscreenImage(source);
}
public void setAnimatingHeight (int height) {
animatingSize.height = height;
setSize (animatingSize);
}
private void makeOffscreenImage(JComponent source) {
GraphicsConfiguration gfxConfig =
GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
offscreenImage =
gfxConfig.createCompatibleImage(source.getWidth(),
source.getHeight());
Graphics2D offscreenGraphics =
(Graphics2D) offscreenImage.getGraphics();
source.paint (offscreenGraphics);
}
public Dimension getPreferredSize() { return animatingSize; }
public Dimension getMinimumSize() { return animatingSize; }
public Dimension getMaximumSize() { return animatingSize; }
public void paint (Graphics g) {
// get the bottommost n pixels of source and
// paint them into g, where n is height
BufferedImage fragment =
offscreenImage.getSubimage (0,
offscreenImage.getHeight() - animatingSize.height,
source.getWidth(),
animatingSize.height);
g.drawImage (fragment, 0, 0, this);
}
}
}
|