【问题标题】:How do I fade an image in swing?如何在摇摆中淡化图像?
【发布时间】:2010-02-09 11:45:19
【问题描述】:

我有一个继承自 JPanel 的类,上面有一个图像,我想设置一个小动画来显示面板/图像,然后在事件触发时将其淡出。

我大概设置了一个线程并触发动画,但我该如何实际进行淡入淡出?

【问题讨论】:

    标签: java swing animation fade


    【解决方案1】:

    您可以自己进行线程处理,但使用Trident 库来处理它可能更容易。如果您在您的类上创建一个名为(例如,setOpacity)的设置器,您可以要求 trident 在特定时间段内将“不透明度”字段从 1.0 插入到 0.0(这里是 some of the docs 关于如何使用 Trident)。

    当您绘制图像时,您可以使用 AlphaComposite 来设置透明度,使用合成的 alpha 参数的更新“不透明度”值。有一个 Sun 教程,其中包含一个 alpha composite example

    【讨论】:

    • @Ash:+1,我打算建议使用 AlphaComposite。
    • Trident 是否也对插值进行“缓动”?
    • 我相信它会进行线性插值(主要是?),基于 Trident 的作者的这篇博文(倒数第二段):pushing-pixels.org/?p=1599
    • 我相信这样的不透明度不会对淡出 jlabel 的图像起作用,很难。它会给出一个异常......是的,JLabelFader 异常。
    【解决方案2】:

    这是一个使用 Alpha 透明度的示例。您可以使用this composite tool 查看使用不同颜色、模式和 alpha 的结果。

    import java.awt.*;
    import java.awt.event.*;
    import java.awt.event.ActionListener;
    import javax.swing.*;
    
    public class AlphaTest extends JPanel implements ActionListener {
    
        private static final Font FONT = new Font("Serif", Font.PLAIN, 32);
        private static final String STRING = "Mothra alert!";
        private static final float DELTA = -0.1f;
        private static final Timer timer = new Timer(100, null);
        private float alpha = 1f;
    
        AlphaTest() {
            this.setPreferredSize(new Dimension(256, 96));
            this.setOpaque(true);
            this.setBackground(Color.black);
            timer.setInitialDelay(1000);
            timer.addActionListener(this);
            timer.start();
        }
    
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.setFont(FONT);
            int xx = this.getWidth();
            int yy = this.getHeight();
            int w2 = g.getFontMetrics().stringWidth(STRING) / 2;
            int h2 = g.getFontMetrics().getDescent();
            g2d.fillRect(0, 0, xx, yy);
            g2d.setComposite(AlphaComposite.getInstance(
                AlphaComposite.SRC_IN, alpha));
            g2d.setPaint(Color.red);
            g2d.drawString(STRING, xx / 2 - w2, yy / 2 + h2);
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            alpha += DELTA;
            if (alpha < 0) {
                alpha = 1;
                timer.restart();
            }
            repaint();
        }
    
        static public void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    JFrame f = new JFrame();
                    f.setLayout(new GridLayout(0, 1));
                    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    f.add(new AlphaTest());
                    f.add(new AlphaTest());
                    f.add(new AlphaTest());
                    f.pack();
                    f.setVisible(true);
                }
            });
        }
    }
    

    【讨论】:

    • 为了比较,请看这个example,它改变了背景颜色的饱和度。
    【解决方案3】:

    有一些描述图像透明度的有用信息here

    你的方法是这样的:

    • 定义一个 Swing Timer 以每 N 毫秒在 Event Dispatch 线程上触发一个 ActionEvent
    • ActionListener 添加到Timer,它应该在包含ImageComponent 上调用repaint()
    • 覆盖ComponentpaintComponent(Graphics) 方法以执行以下操作:
      • Graphics 对象转换为Graphics2D
      • 使用setCompositeGraphics2D 上设置AlphaComposite。这控制透明度级别。
      • 绘制图像。

    对于淡出动画的每次迭代,您都将更改 AlphaComposite 的值以使图像更加透明。

    【讨论】:

    • 我的组件是一个子组件,当我使用paintComponent时,它在JPanel内绘制了整个父组件,覆盖了paint(Graphics g)而不是修复了它。对吗?
    猜你喜欢
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 2011-08-10
    • 2012-07-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-01
    • 1970-01-01
    相关资源
    最近更新 更多