2017-08-10 214 views
0

我想为JPanel设置一个动画渐变背景。效果起作用,但我希望在重新开始时顺利过渡。以下是我目前的实施。当xvalue2达到极限集时,我交换颜色并重新开始。平滑渐变背景动画java

public class GradientAnimation { 
static class GradientPanel extends JPanel { 
    private static final long serialVersionUID = -4185583782901846967L; 
    private Timer timer; 
    private float Xend; 
    private final float MAXVALUE = 800f; 
    private Color color1 = new Color(128,62,153,255); 
    private Color color2 = new Color(192,201,200,255); 

    GradientPanel() { 
     Xend = 0f; 
     setOpaque(true); 
     ActionListener action = new ActionListener(){ 

      @Override 
      public void actionPerformed(ActionEvent evt){ 
       if (Xend < MAXVALUE) Xend+=2f; 
       else{ 
        Color aux = color1; 
        color1 = color2; 
        color2 = aux; 
        Xend = 0f; 
       } 

       revalidate(); 
       repaint(); 
      } 
     }; 
     timer = new Timer(5, action); 
     timer.start(); 
    } 
    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     Graphics2D g2d = (Graphics2D) g; 
     final BufferedImage image = new BufferedImage(
       getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB); 
     g2d = image.createGraphics(); 
     GradientPaint prim = new GradientPaint(0f, 0f, color1, 
       Xend, 0f, color2); 

     g2d.setPaint(prim); 
     g2d.fillRect(0, 0, getWidth(), getHeight()); 

     g.drawImage(image, 0, 0, null); 
    } 
} 

private static void createAndShowUI() { 
    try { 
     JFrame frame = new JFrame("Gradient Animation"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocationRelativeTo(null); 
     frame.setResizable(false); 

     GradientPanel imagePanel = new GradientPanel(); 

     frame.add(imagePanel); 
     frame.setSize(400, 400); 
     frame.setVisible(true); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

public static void main(String[] args) { 

    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowUI(); 
     } 
    }); 
    } 
} 

再一次,我想隐藏一段时间,我交换颜色有一个完美的梯度动画循环。如果代码看起来正确,请告诉我,我如何提高质量。

+0

请不要为填料张贴废话作为击败限制的目的,而不是玩公平与我们的志愿者谁还会帮你。相反,请告诉你的问题的细节,代码的作用,它应该做什么。 –

+0

是的,我明白了。但是与代码相比,我的解释太短了,我想发布一个工作代码而不是代码片段,因此可以对其进行测试。抱歉。 –

+0

因此,添加更多的解释,而不是废话。帮助我们理解你写的代码,描述它。再一次,你的帮助我们只会帮助你。 –

回答

4

在下面的变型中,

  • 使用Color.getHSBColor()循环通过可用色调;因为色调值环绕,所以通过光谱的转变是平滑的。或者,在终点处更改delta的符号。

  • 重写getPreferredSize()以建立初始面板几何。

  • 不要缓冲不必要的渲染。

  • 不要重新验证组件不必要的。

image

我将如何适应它通过所有的颜色,以避免骑自行车吗?

无尽的变化是可能的;关键问题是避免突然的变化。在这里,HUE_MINHUE_MAX被缩小到频谱的一部分,delta的符号在端点处发生变化,其他HSB组件得到更新。

private static final float HUE_MIN = 4f/6; 
private static final float HUE_MAX = 5f/6; 
… 
    @Override 
    public void actionPerformed(ActionEvent evt) { 
     hue += delta; 
     if (hue > HUE_MAX) { 
      hue = HUE_MAX; 
      delta = -delta; 
     } 
     if (hue < HUE_MIN) { 
      hue = HUE_MIN; 
      delta = -delta; 
     } 
     color1 = Color.getHSBColor(hue, 1, 1); 
     color2 = Color.getHSBColor(hue, 3f/4 + delta, 3f/4 + delta); 
     repaint(); 
    } 

image

代码:

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.GradientPaint; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

/** @see https://stackoverflow.com/q/45603312/230513 */ 
public class GradientAnimation { 

    static class GradientPanel extends JPanel { 

     private static final int WIDE = 640; 
     private static final int HIGH = 240; 
     private static final float HUE_MIN = 0; 
     private static final float HUE_MAX = 1; 
     private final Timer timer; 
     private float hue = HUE_MIN; 
     private Color color1 = Color.white; 
     private Color color2 = Color.black; 
     private float delta = 0.01f; 

     GradientPanel() { 
      ActionListener action = new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent evt) { 
        hue += delta; 
        if (hue > HUE_MAX) { 
         hue = HUE_MIN; 
        } 
        color1 = Color.getHSBColor(hue, 1, 1); 
        color2 = Color.getHSBColor(hue + 16 * delta, 1, 1); 
        repaint(); 
       } 
      }; 
      timer = new Timer(10, action); 
      timer.start(); 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g; 
      GradientPaint p = new GradientPaint(
       0, 0, color1, getWidth(), 0, color2); 
      g2d.setPaint(p); 
      g2d.fillRect(0, 0, getWidth(), getHeight()); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(WIDE, HIGH); 
     } 
    } 

    private static void createAndShowUI() { 
     JFrame frame = new JFrame("Gradient Animation"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     GradientPanel imagePanel = new GradientPanel(); 
     frame.add(imagePanel); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 

     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 
+0

这工作得很好,我将如何适应它以避免骑自行车穿越所有颜色?两种基本颜色,而不是全光谱。 –

+0

@SantiagoRosales:我提出了上面的一种方法。 – trashgod