使用Graphics方法drawPolygon()渲染轮廓,使用fillPolygon()填充其内部;两者都有所需的签名,如图here。
因为“绘制图形轮廓的操作通过使用像素大小的笔遍历像素之间的无限细路径来操作”,将图形上下文转换为 Graphics2D,以便您可以使用 draw() 和 fill()在相应的Shape 上。这将允许您使用setStroke() 指定轮廓,图示为here。
我需要它具有自定义厚度……我也不想使用Graphics2D。
Graphics API不支持自定义厚度。正如here 所建议的那样,paintComponent() 收到的实际图形上下文是Graphics2D 的一个实例,它确实支持自定义笔触几何形状。
事情是老师没有教我Graphics2D,所以我不应该使用它。
然后简单地绘制较大的三角形,然后绘制较小的三角形。如果这不起作用,那么您在计算较大的三角形时出错,您应该编辑您的问题以包含complete example。
我正在寻找一种不使用Graphics2D 的方法……有人在comment 中正确解释了这个问题。
作为@Marco13 observes,您需要一个比原始三角形大borderThickness 的三角形。您可以使用AffineTransform 进行缩放。虽然Graphics 不能fill() 任意Shape,例如由AffineTransform 创建的@,但它可以根据需要剪辑 渲染。在下面的示例中,单位三角形被平移并缩放到 N x N 面板的中心;副本放大delta。请注意渲染是如何首先裁剪到较大的背景图,然后再裁剪到较小的前景图。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* @see https://stackoverflow.com/a/39812618/230513
*/
public class GraphicsBorder {
private static class GraphicsPanel extends JPanel {
private static final int N = 256;
private static final Color FILL = new Color(0x990099);
private static final Color BORDER = new Color(0x66FFB2);
private final Shape fore;
private final Shape back;
public GraphicsPanel(Polygon polygon, int delta) {
AffineTransform a1 = new AffineTransform();
a1.translate(N / 2, N / 2);
a1.scale(N / 3, N / 3);
fore = a1.createTransformedShape(polygon);
AffineTransform a2 = new AffineTransform();
a2.translate(N / 2, N / 2 - delta / 3);
a2.scale(N / 3 + delta, N / 3 + delta);
back = a2.createTransformedShape(polygon);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(BORDER);
g.setClip(back);
g.fillRect(0, 0, N, N);
g.setColor(FILL);
g.setClip(fore);
g.fillRect(0, 0, N, N);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(N, N);
}
}
private void display() {
JFrame f = new JFrame("GraphicsBorder");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Polygon p = new Polygon();
p.addPoint(0, -1);
p.addPoint(1, 1);
p.addPoint(-1, 1);
f.add(new GraphicsPanel(p, 16));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new GraphicsBorder()::display);
}
}