2013-01-05 52 views
4

我們知道在Java中有一個名爲RadialGradientPaint的類,我們可以使用它爲圓形繪製漸變繪畫。如何實施橢圓形漸變繪畫?

但我想要一個橢圓形(橢圓形)GradientPaint。如何實施橢圓形GradientPaint

回答

13

繪製RadialGradientPaint時使用AffineTransform。這將需要轉換的縮放實例。它最終可能會看起來像這樣:

OvalGradientPaint

import java.awt.*; 
import java.awt.MultipleGradientPaint.CycleMethod; 
import java.awt.geom.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.border.EmptyBorder; 

public class OvalGradientPaint { 

    public static void main(String[] args) { 
     Runnable r = new Runnable() { 

      @Override 
      public void run() { 
       // the GUI as seen by the user (without frame) 
       JPanel gui = new JPanel(new BorderLayout()); 
       gui.setBorder(new EmptyBorder(2, 3, 2, 3)); 

       gui.add(new OvalGradientPaintSurface()); 
       gui.setBackground(Color.WHITE); 

       JFrame f = new JFrame("Oval Gradient Paint"); 
       f.add(gui); 
       f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       // See http://stackoverflow.com/a/7143398/418556 for demo. 
       f.setLocationByPlatform(true); 

       // ensures the frame is the minimum size it needs to be 
       // in order display the components within it 
       f.pack(); 
       // should be done last, to avoid flickering, moving, 
       // resizing artifacts. 
       f.setVisible(true); 
      } 
     }; 
     // Swing GUIs should be created and updated on the EDT 
     // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html 
     SwingUtilities.invokeLater(r); 
    } 
} 

class OvalGradientPaintSurface extends JPanel { 

    public int yScale = 150; 
    public int increment = 1; 
    RadialGradientPaint paint; 
    AffineTransform moveToOrigin; 

    OvalGradientPaintSurface() { 
     Point2D center = new Point2D.Float(100, 100); 
     float radius = 90; 
     float[] dist = {0.05f, .95f}; 
     Color[] colors = {Color.RED, Color.MAGENTA.darker()}; 
     paint = new RadialGradientPaint(center, radius, dist, colors,CycleMethod.REFLECT); 
     moveToOrigin = AffineTransform. 
       getTranslateInstance(-100d, -100d); 
     ActionListener listener = new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent ae) { 
       if (increment < 0) { 
        increment = (yScale < 50 ? -increment : increment); 
       } else { 
        increment = (yScale > 150 ? -increment : increment); 
       } 
       yScale += increment; 
       repaint(); 
      } 
     }; 

     Timer t = new Timer(15, listener); 
     t.start(); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2 = (Graphics2D)g; 
     AffineTransform moveToCenter = AffineTransform. 
       getTranslateInstance(getWidth()/2d, getHeight()/2d); 
     g2.setPaint(paint); 
     double y = yScale/100d; 
     double x = 1/y; 
     AffineTransform at = AffineTransform.getScaleInstance(x, y); 

     // We need to move it to the origin, scale, and move back. 
     // Counterintutitively perhaps, we concatentate 'in reverse'. 
     moveToCenter.concatenate(at); 
     moveToCenter.concatenate(moveToOrigin); 
     g2.setTransform(moveToCenter); 

     // fudge factor of 3 here, to ensure the scaling of the transform 
     // does not leave edges unpainted. 
     g2.fillRect(-getWidth(), -getHeight(), getWidth()*3, getHeight()*3); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return new Dimension(500, 200); 
    } 
} 

原圖:應用程序的原來的靜態(無聊)「屏幕截圖」。

OvalGradientPaint

+1

+1爲美,以及幫助(模板?)評論。 – trashgod

+0

@trashgod是的,這是一個'幾乎模板'(1)我爲Netbeans設計的。我根本無法容忍在沒有提出任何評論的情況下爲SSCCE幀做所有這些陳述。 1)還沒有想到如何使用它來複制粘貼文本和更改類名稱。 –

+1

創建:'工具>模板>添加';編輯:'工具>模板>在編輯器中打開「;使用:'File> New File',新的模板應該與它添加到的相同類別中;打開現有的元件以查看元符號,例如$ {package}和'$ {name}'。 – trashgod

0

RadialGradientPaint提供兩種方式本身畫爲橢圓而非圓形:

  1. 建設後,你可以指定梯度變換。例如,如果您提供以下轉換:AffineTransform.getScaleInstance(0.5, 1),您的漸變將是一個直立的橢圓形(x維度將是y維度的一半)。

  2. 或者,您可以使用要求提供Rectangle2D的構造函數。將創建適當的變換以使梯度橢圓邊界與提供的矩形邊界匹配。我發現類文檔有幫助:RadialGradientPaint API。尤其請參閱this constructor的文檔。