概要
GlassPane
を使用して、Lightbox
風にアニメーションしながら画像を表示します。
Screenshot
Advertisement
サンプルコード
class LightboxGlassPane extends JPanel {
private final ImageIcon image = new ImageIcon(
LightboxGlassPane.class.getResource("test.png"));
private final AnimeIcon animatedIcon = new AnimeIcon();
private float alpha;
private int w;
private int h;
private final Rectangle rect = new Rectangle();
private Timer animator;
private Handler handler;
@Override public void updateUI() {
removeMouseListener(handler);
removeHierarchyListener(handler);
super.updateUI();
setOpaque(false);
super.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
if (handler == null) {
handler = new Handler();
}
addMouseListener(handler);
addHierarchyListener(handler);
}
private class Handler extends MouseAdapter implements HierarchyListener {
@Override public void mouseClicked(MouseEvent me) {
me.getComponent().setVisible(false);
}
@Override public void hierarchyChanged(HierarchyEvent e) {
if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0
&& !e.getComponent().isDisplayable() && animator != null) {
animator.stop();
}
}
}
@Override public void setVisible(boolean isVisible) {
boolean oldVisible = isVisible();
super.setVisible(isVisible);
JRootPane rootPane = getRootPane();
if (rootPane != null && isVisible() != oldVisible) {
rootPane.getLayeredPane().setVisible(!isVisible);
}
boolean b = animator == null || !animator.isRunning();
if (isVisible && b) {
w = 40;
h = 40;
alpha = 0f;
animator = new Timer(10, new ActionListener() {
@Override public void actionPerformed(ActionEvent e) {
animatedIcon.next();
repaint();
}
});
animator.start();
} else {
if (animator != null) {
animator.stop();
}
}
animatedIcon.setRunning(isVisible);
}
@Override protected void paintComponent(Graphics g) {
JRootPane rootPane = getRootPane();
if (rootPane != null) {
rootPane.getLayeredPane().print(g);
}
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (h < image.getIconHeight() + 5 + 5) {
h += image.getIconHeight() / 16;
} else if (w < image.getIconWidth() + 5 + 5) {
h = image.getIconHeight() + 5 + 5;
w += image.getIconWidth() / 16;
} else if (alpha < 1f) {
w = image.getIconWidth() + 5 + 5;
alpha = alpha + .1f;
} else {
animatedIcon.setRunning(false);
animator.stop();
}
rect.setSize(w, h);
Rectangle screen = getBounds();
rect.setLocation(screen.x + screen.width / 2 - rect.width / 2,
screen.y + screen.height / 2 - rect.height / 2);
g2d.setColor(new Color(100, 100, 100, 100));
g2d.fill(screen);
g2d.setColor(new Color(255, 255, 255, 200));
g2d.fill(rect);
if (alpha > 0) {
if (alpha > 1f) {
alpha = 1f;
}
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
g2d.drawImage(image.getImage(), rect.x + 5, rect.y + 5,
image.getIconWidth(),
image.getIconHeight(), this);
} else {
animatedIcon.paintIcon(
this, g2d,
screen.x + screen.width / 2 - animatedIcon.getIconWidth() / 2,
screen.y + screen.height / 2 - animatedIcon.getIconHeight() / 2);
}
g2d.dispose();
}
}
View in GitHub: Java, Kotlin解説
上記のサンプルでは、JFrame
にGlassPane
を設定して、このGlassPane
の中央にインジケータ、高さ幅がアニメーションしながら拡大する矩形、画像を順番に表示しています。
- 任意の場所のクリックで画像を非表示にするため、
GlassPane
にマウスリスナーを追加してGlassPane#setVisible(false)
を実行