我們知道在Java中有一個名爲RadialGradientPaint
的類,我們可以使用它爲圓形繪製漸變繪畫。如何實施橢圓形漸變繪畫?
但我想要一個橢圓形(橢圓形)GradientPaint
。如何實施橢圓形GradientPaint
?
我們知道在Java中有一個名爲RadialGradientPaint
的類,我們可以使用它爲圓形繪製漸變繪畫。如何實施橢圓形漸變繪畫?
但我想要一個橢圓形(橢圓形)GradientPaint
。如何實施橢圓形GradientPaint
?
繪製RadialGradientPaint
時使用AffineTransform
。這將需要轉換的縮放實例。它最終可能會看起來像這樣:
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);
}
}
原圖:應用程序的原來的靜態(無聊)「屏幕截圖」。
RadialGradientPaint
提供兩種方式本身畫爲橢圓而非圓形:
建設後,你可以指定梯度變換。例如,如果您提供以下轉換:AffineTransform.getScaleInstance(0.5, 1)
,您的漸變將是一個直立的橢圓形(x維度將是y維度的一半)。
或者,您可以使用要求提供Rectangle2D
的構造函數。將創建適當的變換以使梯度橢圓邊界與提供的矩形邊界匹配。我發現類文檔有幫助:RadialGradientPaint API。尤其請參閱this constructor的文檔。
+1爲美,以及幫助(模板?)評論。 – trashgod
@trashgod是的,這是一個'幾乎模板'(1)我爲Netbeans設計的。我根本無法容忍在沒有提出任何評論的情況下爲SSCCE幀做所有這些陳述。 1)還沒有想到如何使用它來複制粘貼文本和更改類名稱。 –
創建:'工具>模板>添加';編輯:'工具>模板>在編輯器中打開「;使用:'File> New File',新的模板應該與它添加到的相同類別中;打開現有的元件以查看元符號,例如$ {package}和'$ {name}'。 – trashgod