Swing/AnimeIcon のバックアップ差分(No.19)
- バックアップ一覧
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- Swing/AnimeIcon へ行く。
- 1 (2007-03-26 (月) 00:29:10)
- 2 (2007-03-28 (水) 18:41:47)
- 3 (2007-04-10 (火) 15:45:54)
- 4 (2007-04-16 (月) 12:45:57)
- 5 (2007-04-17 (火) 18:27:40)
- 6 (2007-05-09 (水) 20:01:26)
- 7 (2007-07-11 (水) 23:49:44)
- 8 (2007-07-24 (火) 22:43:03)
- 9 (2007-07-25 (水) 01:39:27)
- 10 (2007-07-25 (水) 12:41:27)
- 11 (2009-11-26 (木) 15:53:44)
- 12 (2009-12-17 (木) 01:44:29)
- 13 (2009-12-17 (木) 11:07:18)
- 14 (2010-03-08 (月) 13:13:39)
- 15 (2010-12-12 (日) 23:20:10)
- 16 (2011-04-29 (金) 15:31:12)
- 17 (2013-03-13 (水) 15:39:14)
- 18 (2013-08-17 (土) 01:17:02)
- 19 (2013-08-17 (土) 05:01:00)
- 20 (2014-03-18 (火) 18:50:31)
- 21 (2015-01-20 (火) 15:44:29)
- 22 (2015-03-13 (金) 13:42:47)
- 23 (2016-05-26 (木) 14:28:17)
- 24 (2016-08-17 (水) 18:46:54)
- 25 (2017-03-29 (水) 19:36:44)
- 26 (2017-03-30 (木) 14:10:40)
- 27 (2017-10-18 (水) 13:38:25)
- 28 (2019-04-26 (金) 18:20:51)
- 29 (2019-05-11 (土) 15:55:26)
- 30 (2021-02-09 (火) 19:11:27)
- 31 (2024-02-02 (金) 11:37:11)
- 追加された行はこの色です。
- 削除された行はこの色です。
TITLE:Timerでアニメーションするアイコンを作成 #navi(../) #tags(Timer, Animation, Icon) RIGHT:Posted by &author(aterai); at 2006-03-13 *Timerでアニメーションするアイコンを作成 [#k26d808e] ``javax.swing.Timer``を使って、アニメーションするアイコンを作成します。 -&jnlp; -&jar; -&zip; //#screenshot #ref(http://lh4.ggpht.com/_9Z4BYR88imo/TQTHuI0XeDI/AAAAAAAAARo/CVs615Dtkqs/s800/AnimeIcon.png) **サンプルコード [#z490c564] #code(link){{ class AnimatedLabel extends JLabel implements ActionListener { private final javax.swing.Timer animator; private final AnimeIcon icon = new AnimeIcon(); public AnimatedLabel() { super(); animator = new javax.swing.Timer(100, this); setIcon(icon); } @Override public void actionPerformed(ActionEvent e) { icon.next(); repaint(); } public void startAnimation() { icon.setRunning(true); animator.start(); } public void stopAnimation() { icon.setRunning(false); animator.stop(); } } class AnimeIcon implements Icon { private static final Color cColor = new Color(0.5f,0.5f,0.5f); private final List<Shape> list = new ArrayList<Shape>(); private final Dimension dim; private boolean isRunning = false; public AnimeIcon() { super(); double r = 2.0d; double sx = 1.0d; double sy = 1.0d; list.add(new Ellipse2D.Double(sx+3*r, sy+0*r, 2*r, 2*r)); list.add(new Ellipse2D.Double(sx+5*r, sy+1*r, 2*r, 2*r)); list.add(new Ellipse2D.Double(sx+6*r, sy+3*r, 2*r, 2*r)); list.add(new Ellipse2D.Double(sx+5*r, sy+5*r, 2*r, 2*r)); list.add(new Ellipse2D.Double(sx+3*r, sy+6*r, 2*r, 2*r)); list.add(new Ellipse2D.Double(sx+1*r, sy+5*r, 2*r, 2*r)); list.add(new Ellipse2D.Double(sx+0*r, sy+3*r, 2*r, 2*r)); list.add(new Ellipse2D.Double(sx+1*r, sy+1*r, 2*r, 2*r)); dim = new Dimension((int)(r*8+sx*2), (int)(r*8+sy*2)); } @Override public int getIconWidth() { return dim.width; } @Override public int getIconHeight() { return dim.height; } @Override public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2d = (Graphics2D) g; g2d.setPaint((c!=null)?c.getBackground():Color.WHITE); g2d.fillRect(x, y, getIconWidth(), getIconHeight()); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setColor(cColor); float alpha = 0.0f; g2d.translate(x, y); for(Shape s: list) { alpha = isRunning?alpha+0.1f:0.5f; g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); g2d.fill(s); } g2d.translate(-x, -y); } public void next() { if(isRunning) list.add(list.remove(0)); } public void setRunning(boolean isRunning) { this.isRunning = isRunning; } } }} **解説 [#md0e801a] 上記のサンプルでは、スタートボタンを押すと(``JTextArea``に表示している作業状況はダミーで、実際は``Thread.sleep()``で時間を稼いでいるだけ)アイコンが``FireFox``風にアニメーションします。 アニメーションは、``8``個の円からアイコンを生成して、それぞれのインデックスを順に変更することで行っています。 - アイコンの生成 -- リスト(``Vector``)に、座標の異なる円(``Ellipse2D.Double``)を8個生成して追加します。 -- リスト(``Vector``)に、座標の異なる円(``Ellipse2D.Double``)を``8``個生成して追加します。 - インデックスの変更 -- ``Timer``を使って、リストの先頭にある円を最後に移動します。 - 異なるアルファ値で円を描画 -- インデックスに応じたアルファ値でそれぞれの円を描画します。 円がいびつだったので、アンチエイリアスをかけていまが、``Java 1.6.0``では「小さな円(曲線)が円に見えなかった問題」が解消されているようです([http://www.02.246.ne.jp/~torutk/jvm/mustang.html#SEC26 参考])。 ---- 一々自分で座標を計算して``new Ellipse2D``を``8``個も並べるのが嫌だったり、もうすこし正確に円を配置したい場合は、``AffineTransform``などを使ってアイコンを生成する方法もあります。 #code{{ class AnimeIcon implements Icon { private static final Color cColor = new Color(0.5f,0.8f,0.5f); //private final Vector<Shape> list = new Vector<Shape>(); private final List<Shape> list = new ArrayList<Shape>(); private final Dimension dim; private boolean isRunning = false; //int rotate = 45; public AnimeIcon() { super(); int r = 4; Shape s = new Ellipse2D.Float(0, 0, 2*r, 2*r); for(int i=0;i<8;i++) { AffineTransform at = AffineTransform.getRotateInstance(i*2*Math.PI/8); at.concatenate(AffineTransform.getTranslateInstance(r, r)); list.add(at.createTransformedShape(s)); } //int d = (int)(r*2*(1+2*Math.sqrt(2))); int d = (int)r*2*(1+3); // 2*Math.sqrt(2) is nearly equal to 3. dim = new Dimension(d, d); } @Override public int getIconWidth() { return dim.width; } @Override public int getIconHeight() { return dim.height; } @Override public void paintIcon(Component c, Graphics g, int x, int y) { Graphics2D g2d = (Graphics2D) g; g2d.setPaint((c!=null)?c.getBackground():Color.WHITE); g2d.fillRect(x, y, getIconWidth(), getIconHeight()); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.setColor(cColor); float alpha = 0.0f; int xx = x + dim.width/2; int yy = y + dim.height/2; //AffineTransform at = AffineTransform.getRotateInstance(Math.toRadians(rotate), xx, yy); //at.concatenate(AffineTransform.getTranslateInstance(xx, yy)); g2d.translate(xx, yy); for(Shape s: list) { alpha = isRunning?alpha+0.1f:0.5f; g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); //g2d.fill(at.createTransformedShape(s)); g2d.fill(s); } } public void next() { if(isRunning) { list.add(list.remove(0)); //rotate = rotate<360?rotate+45:45; } } public void setRunning(boolean isRunning) { this.isRunning = isRunning; } } }} //**参考リンク **コメント [#o8846e0b] - 色の濃い円が時計回りに回転するように変更しました。 -- [[aterai]] &new{2006-03-15 (水) 11:12:08}; - ロードインジケータと呼ぶらしい。 -- [[aterai]] &new{2007-07-11 (水) 23:49:44}; - %%このサンプルでは、``Swing Tutorial``にあった古い``SwingWorker``を使用しているけど、%% [http://java.net/projects/swingworker Swingworker — Java.net] にある``JDK 1.6``からバックポートされた``org.jdesktop.swingworker.SwingWorker``を使用%%したほうがいいかも。そのうち修正する予定%% するように変更しました。 -- [[aterai]] &new{2009-12-17 (木) 01:44:29}; #comment