如何实现椭圆GradientPaint?

我们知道在Java中有一个名为RadialGradientPaint的类,我们可以使用它来为圆形绘制渐变画。

但是我想要一个椭圆形(椭圆形) GradientPaint 。 如何实现椭圆GradientPaint

绘制AffineTransform时使用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

RadialGradientPaint提供了两种将自身绘制为椭圆而不是圆形的方法:

  1. 构造时,您可以为渐变指定变换。 例如,如果提供以下变换: AffineTransform.getScaleInstance(0.5, 1) ,则渐变将是直立椭圆(x维度将是y维度的一半)。

  2. 或者,您可以使用需要提供Rectangle2D的构造函数。 将创建适当的变换以使渐变椭圆边界与提供的矩形的边界匹配。 我发现类文档很有用: RadialGradientPaint API 。 特别是,请参阅此构造函数的文档。