我是 Java 編程的新手,我希望是否有辦法在 Java 中的 JPanel 中設計希臘波。我附上一張圖片來更好地解釋我所說的希臘波浪:

我嘗試使用for回圈,因為一個波足以設計,但我只使用 QuadCurve2D.Double,因為我無法實作其他方法。有什么建議或幫助嗎?提前致謝。這是我到目前為止所做的:

PS抱歉沒有顯示照片,stackoverflow不允許我這樣做。
uj5u.com熱心網友回復:
Sooo,這是一個漫長而艱難的旅程......
首先,我將您的影像匯入矢量影像編輯器。我花了很多時間創建基本形狀,然后確定創建單個“重復”形狀的最佳選擇,這讓我想到了......

然后我使用
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class GreekWave extends Path2D.Double {
public GreekWave() {
moveTo(97.5, 21.0);
curveTo(97.5, 31.0, 86.56, 39.14, 78.5, 39.0);
curveTo(66.97, 38.91, 73.5, 24.0, 69.5, 25.0);
curveTo(60.42, 25.44, 49.75, 35.5, 50.5, 47.0);
curveTo(52.0, 65.0, 65.35, 68.16, 72.5, 68.0);
curveTo(81.97, 66.26, 90.26, 61.16, 98.0, 54.49);
curveTo(98.0, 69.47, 98.0, 82.35, 98.0, 85.0);
lineTo(0.0, 85.0);
curveTo(0.0, 82.35, 0.0, 69.47, 0.0, 54.49);
curveTo(0.26, 54.26, 0.53, 54.03, 0.79, 53.8);
curveTo(23.75, 33.61, 42.07, 0.0, 72.5, 0.0);
curveTo(92.5, 1.0, 97.5, 11.0, 97.5, 21.0);
closePath();
}
public Dimension getSize() {
return new Dimension(98, 85);
}
}
public class TestPane extends JPanel {
private GreekWave greekWave = new GreekWave();
public TestPane() {
}
@Override
public Dimension getPreferredSize() {
return greekWave.getSize();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
Rectangle bounds = greekWave.getBounds();
int width = bounds.x bounds.width;
int height = bounds.y bounds.height;
int x = (getWidth() - width) / 2;
int y = (getHeight() - height) / 2;
g2d.translate(x, y);
g2d.draw(greekWave);
g2d.dispose();
}
}
}
Now, you "could" try and simply "rubber stamping" the shape to create a repeating pattern, but this will create an issue. The basic shape is closed, so any kind of "fill pattern" is probably going to end up looking weird.
Instead, we want to create a single, repeating, shape. Remember what I said about the "shapes API"? Basically, we can translate the core shape and "append" them to another, for example...

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class GreekWave extends Path2D.Double {
public GreekWave() {
moveTo(97.5, 21.0);
curveTo(97.5, 31.0, 86.56, 39.14, 78.5, 39.0);
curveTo(66.97, 38.91, 73.5, 24.0, 69.5, 25.0);
curveTo(60.42, 25.44, 49.75, 35.5, 50.5, 47.0);
curveTo(52.0, 65.0, 65.35, 68.16, 72.5, 68.0);
curveTo(81.97, 66.26, 90.26, 61.16, 98.0, 54.49);
curveTo(98.0, 69.47, 98.0, 82.35, 98.0, 85.0);
lineTo(0.0, 85.0);
curveTo(0.0, 82.35, 0.0, 69.47, 0.0, 54.49);
curveTo(0.26, 54.26, 0.53, 54.03, 0.79, 53.8);
curveTo(23.75, 33.61, 42.07, 0.0, 72.5, 0.0);
curveTo(92.5, 1.0, 97.5, 11.0, 97.5, 21.0);
closePath();
}
public Dimension getSize() {
return new Dimension(98, 85);
}
}
public class TestPane extends JPanel {
private Area repeatedShape;
public TestPane() {
repeatedShape = new Area();
GreekWave greekWave = new GreekWave();
for (int index = 0; index < 10; index ) {
Shape translatedShape = greekWave.createTransformedShape(AffineTransform.getTranslateInstance(index * greekWave.getSize().width, 0));
repeatedShape.add(new Area(translatedShape));
}
}
@Override
public Dimension getPreferredSize() {
Rectangle bounds = repeatedShape.getBounds();
int width = bounds.x bounds.width;
int height = bounds.y bounds.height;
return new Dimension(width, height);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
Rectangle bounds = repeatedShape.getBounds();
int width = bounds.x bounds.width;
int height = bounds.y bounds.height;
int x = (getWidth() - width) / 2;
int y = (getHeight() - height) / 2;
g2d.translate(x, y);
g2d.draw(repeatedShape);
g2d.dispose();
}
}
}
Now, I have to admit, that ended up better then I though it would, now we can fill it.
You could just replace g2d.draw(repeatedShape); with g2d.fill(repeatedShape); (don't forget to specify a color first), but where's the fun in that.
You could make use of GradientPait or even a TexturePaint (see 
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class GreekWave extends Path2D.Double {
public GreekWave() {
moveTo(97.5, 21.0);
curveTo(97.5, 31.0, 86.56, 39.14, 78.5, 39.0);
curveTo(66.97, 38.91, 73.5, 24.0, 69.5, 25.0);
curveTo(60.42, 25.44, 49.75, 35.5, 50.5, 47.0);
curveTo(52.0, 65.0, 65.35, 68.16, 72.5, 68.0);
curveTo(81.97, 66.26, 90.26, 61.16, 98.0, 54.49);
curveTo(98.0, 69.47, 98.0, 82.35, 98.0, 85.0);
lineTo(0.0, 85.0);
curveTo(0.0, 82.35, 0.0, 69.47, 0.0, 54.49);
curveTo(0.26, 54.26, 0.53, 54.03, 0.79, 53.8);
curveTo(23.75, 33.61, 42.07, 0.0, 72.5, 0.0);
curveTo(92.5, 1.0, 97.5, 11.0, 97.5, 21.0);
closePath();
}
public Dimension getSize() {
return new Dimension(98, 85);
}
}
public class TestPane extends JPanel {
private Area repeatedShape;
public TestPane() {
repeatedShape = new Area();
GreekWave greekWave = new GreekWave();
for (int index = 0; index < 10; index ) {
Shape translatedShape = greekWave.createTransformedShape(AffineTransform.getTranslateInstance(index * greekWave.getSize().width, 0));
repeatedShape.add(new Area(translatedShape));
}
}
@Override
public Dimension getPreferredSize() {
Rectangle bounds = repeatedShape.getBounds();
int width = bounds.x bounds.width;
int height = bounds.y bounds.height;
return new Dimension(width, height);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
Rectangle bounds = repeatedShape.getBounds();
int width = bounds.x bounds.width;
int height = bounds.y bounds.height;
int x = (getWidth() - width) / 2;
int y = (getHeight() - height) / 2;
g2d.translate(x, y);
g2d.draw(repeatedShape);
g2d.setClip(repeatedShape);
for (x = 0; x < getWidth(); x = 4) {
g2d.drawLine(x, 0, x, getHeight());
}
g2d.dispose();
}
}
}
Or, if you don't want the outline, remove g2d.draw(repeatedShape);...

So, when I tell you that the shapes API is REALLY important and REALLY powerful, I'm not exaggerate.
Now, this is has taken me the better part of half the day, so, before you start posting more comments, spend the time going through the 2D Graphics trail and supporting JavaDocs ??
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/454107.html
