Graphics2D.drawPolyline() 对比 Graphics2D.drawLine()
Graphics2D.drawPolyline() vs Graphics2D.drawLine()
调用 drawPolyline()
与迭代每一行并在 Graphics2D
class 中调用 drawLine()
有什么好处吗?
例如:
graphics2d.drawPolyline(xPoints, yPoints, nPoints);
对比:
for (MyBean line : myBeans) {
graphics2d.drawLine(line.getX1Point(), line.getY1Point(), line.getX2Point(), line.getY2Point());
}
第一个是第二个的便捷方法吗?
对 AWT 相当陌生。 (我意识到第一个可能更简洁。)
编辑:我调用BufferedImage.createGraphics()
执行Graphics2D
。
请记住 Graphics2D
是一个抽象 class,因此您不知道您正在使用哪个 具体 实现,我会使用无论哪种方法都可以使 您的 代码更清晰。
我很少使用 drawPolyline()
,因为将坐标放入数组以传递给方法通常很痛苦。但是您还应该考虑创建一个可以传递给 Graphics2D.draw(Shape)
方法的 GeneralPath
对象。对于 Graphics2D
的某些实现,绘制路径 可能 比绘制单独的线更有效。有时我也注意到,使用路径而不是单独的线条输出看起来稍微好一些,特别是如果线条颜色是部分透明的(有时你可以看到单独线条的端点重叠的暗点)。
是一个重要的区别:使用drawPolyline
您绘制的是一条折线。使用 drawLine
您正在绘制单独的线条。到目前为止,如此明显。但这是什么意思?
差异主要体现在为图形对象分配“非平凡的”Stroke
时——通常是某个 BasicStroke
。这在构造函数中接收几个参数。关于您的问题的重要一个是 join
参数。它可以是 JOIN_BEVEL
、JOIN_METER
和 JOIN_ROUND
。它决定了 two connected 行如何连接。显然,这只能在 已知 线路 连接 时应用,这仅在 drawPolyline
中是这种情况] 称呼。它根本不能用于个人 drawLine
调用。
以下是显示此差异的屏幕截图。它使用一个witdh为15和一个join=BasicStroke.JOIN_ROUND
的笔画。左边部分用drawPolyline
绘制,右边部分单独绘制:
但是你通常不应该不无论如何使用drawPolyline
...
... 因为它不知何故已经过时并且有几个缺点。首先,创建调用它所需的数组很麻烦。重要的是,它只接受 int[]
个数组。
整个 Java 2D 绘画基础设施最初专注于 int
坐标,就像 Graphics#drawLine(int,int,int,int)
中一样。这已经被推广,并且 Graphics2D
方法在这里允许更大的灵活性。因此,现在绘制多段线的常用方法是创建一个包含多段线的 Shape
对象。在大多数情况下,这将是一个 Path2D
实例:
Path2D path = new Path2D.Double();
path.moveTo(x0,y0);
path.lineTo(x1,y1);
path.lineTo(x2,y2);
...
graphics2D.draw(path);
但是,仅供参考,下面是用于创建上图的代码:
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DrawLineVsDrawPolyline
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame f = new JFrame("");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new BorderLayout());
class Line
{
int x1, y1, x2, y2;
Line(int x1, int y1, int x2, int y2)
{
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
public int getX1Point()
{
return x1;
}
public int getY1Point()
{
return y1;
}
public int getX2Point()
{
return x2;
}
public int getY2Point()
{
return y2;
}
}
int xPoints[] = new int[] { 100, 150, 200 };
int yPoints[] = new int[] { 100, 250, 100 };
int nPoints = xPoints.length;
List<Line> lines = new ArrayList<Line>();
for (int i0=0; i0<nPoints-1; i0++)
{
int i1 = i0+1;
int x1 = xPoints[i0];
int y1 = yPoints[i0];
int x2 = xPoints[i1];
int y2 = yPoints[i1];
lines.add(new Line(x1,y1,x2,y2));
}
JPanel panel = new JPanel()
{
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
g.setColor(Color.RED);
g.setStroke(new BasicStroke(20.0f,
BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND));
g.drawPolyline(xPoints, yPoints, nPoints);
g.translate(200, 0);
for (Line line : lines) {
g.drawLine(
line.getX1Point(), line.getY1Point(),
line.getX2Point(), line.getY2Point());
}
}
};
f.getContentPane().add(panel, BorderLayout.CENTER);
f.setSize(500,500);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
调用 drawPolyline()
与迭代每一行并在 Graphics2D
class 中调用 drawLine()
有什么好处吗?
例如:
graphics2d.drawPolyline(xPoints, yPoints, nPoints);
对比:
for (MyBean line : myBeans) {
graphics2d.drawLine(line.getX1Point(), line.getY1Point(), line.getX2Point(), line.getY2Point());
}
第一个是第二个的便捷方法吗?
对 AWT 相当陌生。 (我意识到第一个可能更简洁。)
编辑:我调用BufferedImage.createGraphics()
执行Graphics2D
。
请记住 Graphics2D
是一个抽象 class,因此您不知道您正在使用哪个 具体 实现,我会使用无论哪种方法都可以使 您的 代码更清晰。
我很少使用 drawPolyline()
,因为将坐标放入数组以传递给方法通常很痛苦。但是您还应该考虑创建一个可以传递给 Graphics2D.draw(Shape)
方法的 GeneralPath
对象。对于 Graphics2D
的某些实现,绘制路径 可能 比绘制单独的线更有效。有时我也注意到,使用路径而不是单独的线条输出看起来稍微好一些,特别是如果线条颜色是部分透明的(有时你可以看到单独线条的端点重叠的暗点)。
是一个重要的区别:使用drawPolyline
您绘制的是一条折线。使用 drawLine
您正在绘制单独的线条。到目前为止,如此明显。但这是什么意思?
差异主要体现在为图形对象分配“非平凡的”Stroke
时——通常是某个 BasicStroke
。这在构造函数中接收几个参数。关于您的问题的重要一个是 join
参数。它可以是 JOIN_BEVEL
、JOIN_METER
和 JOIN_ROUND
。它决定了 two connected 行如何连接。显然,这只能在 已知 线路 连接 时应用,这仅在 drawPolyline
中是这种情况] 称呼。它根本不能用于个人 drawLine
调用。
以下是显示此差异的屏幕截图。它使用一个witdh为15和一个join=BasicStroke.JOIN_ROUND
的笔画。左边部分用drawPolyline
绘制,右边部分单独绘制:
但是你通常不应该不无论如何使用drawPolyline
...
... 因为它不知何故已经过时并且有几个缺点。首先,创建调用它所需的数组很麻烦。重要的是,它只接受 int[]
个数组。
整个 Java 2D 绘画基础设施最初专注于 int
坐标,就像 Graphics#drawLine(int,int,int,int)
中一样。这已经被推广,并且 Graphics2D
方法在这里允许更大的灵活性。因此,现在绘制多段线的常用方法是创建一个包含多段线的 Shape
对象。在大多数情况下,这将是一个 Path2D
实例:
Path2D path = new Path2D.Double();
path.moveTo(x0,y0);
path.lineTo(x1,y1);
path.lineTo(x2,y2);
...
graphics2D.draw(path);
但是,仅供参考,下面是用于创建上图的代码:
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DrawLineVsDrawPolyline
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame f = new JFrame("");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new BorderLayout());
class Line
{
int x1, y1, x2, y2;
Line(int x1, int y1, int x2, int y2)
{
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
public int getX1Point()
{
return x1;
}
public int getY1Point()
{
return y1;
}
public int getX2Point()
{
return x2;
}
public int getY2Point()
{
return y2;
}
}
int xPoints[] = new int[] { 100, 150, 200 };
int yPoints[] = new int[] { 100, 250, 100 };
int nPoints = xPoints.length;
List<Line> lines = new ArrayList<Line>();
for (int i0=0; i0<nPoints-1; i0++)
{
int i1 = i0+1;
int x1 = xPoints[i0];
int y1 = yPoints[i0];
int x2 = xPoints[i1];
int y2 = yPoints[i1];
lines.add(new Line(x1,y1,x2,y2));
}
JPanel panel = new JPanel()
{
@Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D)gr;
g.setColor(Color.RED);
g.setStroke(new BasicStroke(20.0f,
BasicStroke.CAP_SQUARE, BasicStroke.JOIN_ROUND));
g.drawPolyline(xPoints, yPoints, nPoints);
g.translate(200, 0);
for (Line line : lines) {
g.drawLine(
line.getX1Point(), line.getY1Point(),
line.getX2Point(), line.getY2Point());
}
}
};
f.getContentPane().add(panel, BorderLayout.CENTER);
f.setSize(500,500);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}