javafx canvas 绘制与 java.awt.graphics2d 绘制相比
javafx canvas draw compared to java.awt.graphics2d draw
我想展示比较长的图表。我曾经使用 javafx canvas,但是当绘制的值太多时,有时会出现缓冲区溢出异常。我正在寻找一种不同的方法,并找到了一种使用 java.awt.graphics2d 绘制图表的方法。 graphics2d 的优点是性能提高了,我没有例外。缺点是图表的质量。使用 graphics2d 时,图表看起来不像 javafx.canvas 中的图表那样平滑。
这里有两个测试应用程序(一个使用 javafx canvas,另一个使用 java.awt.graphics2d),其中绘制了正弦波。
如何提高 graphics2d 示例的质量,使其看起来像 canvas 示例?
还是有其他我没有想到的方法可以解决我的问题?
Canvas 示例
public class CanvasDraw extends Application
{
private static final int PANEL_WIDTH = 400, PANEL_HEIGHT = 100;
public static void main(String[] args)
{
launch(args);
}
@Override
public void start(Stage stage)
{
stage.setTitle("CanvasDraw");
StackPane root = new StackPane();
Scene scene = new Scene(root);
root.getChildren().add(createCanvas());
stage.setScene(scene);
stage.show();
}
private Canvas createCanvas()
{
Canvas canvas = new Canvas(PANEL_WIDTH, PANEL_HEIGHT);
GraphicsContext gc = canvas.getGraphicsContext2D();
drawSinus(gc);
return canvas;
}
private void drawSinus(GraphicsContext gc)
{
double height = 50;
double xFactor = 0.5;
double yFactor = 50;
for (int index = 0; index < 720; index++)
{
double x = index * xFactor;
double y = Math.sin(Math.toRadians(index)) * yFactor + height;
if (index == 0)
{
gc.moveTo(x, y);
}
else
{
gc.lineTo(x, y);
}
}
gc.stroke();
}
}
新的 Graphics2D 示例
public class Graphics2DDraw extends Application
{
private static final int PANEL_WIDTH = 400, PANEL_HEIGHT = 100;
public static void main(String[] args)
{
launch(args);
}
@Override
public void start(Stage stage)
{
stage.setTitle("Graphics2DDraw");
StackPane root = new StackPane();
Scene scene = new Scene(root);
root.getChildren().add(createImageView());
stage.setScene(scene);
stage.show();
}
private ImageView createImageView()
{
BufferedImage bi = new BufferedImage(PANEL_WIDTH, PANEL_HEIGHT, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
g.setColor(Color.BLACK);
BasicStroke bs = new BasicStroke(1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g.setStroke(bs);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
drawSinus(g);
return new ImageView(SwingFXUtils.toFXImage(bi, null));
}
private void drawSinus(Graphics2D g)
{
double height = 50;
double xFactor = 0.5;
double yFactor = 50;
int length = 720;
int lastX = 0;
int lastY = 0;
GeneralPath path = new GeneralPath();
for (int index = 0; index < length; index++)
{
double x3 = index * xFactor;
double y3 = Math.sin(Math.toRadians(index)) * yFactor + height;
if (index == 0)
{
path.moveTo(x3, y3);
}
else
{
path.lineTo(x3, y3);
}
}
g.draw(path);
g.dispose();
}
}
编辑
这是缓冲区溢出异常的样子:
java.nio.BufferOverflowException
at com.sun.javafx.sg.prism.GrowableDataBuffer.ensureReadCapacity(GrowableDataBuffer.java:317)
at com.sun.javafx.sg.prism.GrowableDataBuffer.getInt(GrowableDataBuffer.java:527)
at com.sun.javafx.sg.prism.GrowableDataBuffer.getFloat(GrowableDataBuffer.java:563)
at com.sun.javafx.sg.prism.NGCanvas.renderStream(NGCanvas.java:960)
at com.sun.javafx.sg.prism.NGCanvas.renderContent(NGCanvas.java:609)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:477)
at com.sun.javafx.tk.quantum.ViewPainter.paintImpl(ViewPainter.java:330)
at com.sun.javafx.tk.quantum.UploadingPainter.run(UploadingPainter.java:134)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
at java.lang.Thread.run(Thread.java:748)
java.lang.IllegalArgumentException: ALPHA color component is out of range
at com.sun.pisces.PiscesRenderer.checkColorRange(PiscesRenderer.java:113)
at com.sun.pisces.PiscesRenderer.setColor(PiscesRenderer.java:105)
at com.sun.prism.sw.SWPaint.setColor(SWPaint.java:76)
at com.sun.prism.sw.SWPaint.setPaintBeforeDraw(SWPaint.java:118)
at com.sun.prism.sw.SWPaint.setPaintFromShape(SWPaint.java:86)
at com.sun.prism.sw.SWGraphics.paintShape(SWGraphics.java:493)
at com.sun.prism.sw.SWGraphics.drawLine(SWGraphics.java:545)
at com.sun.javafx.sg.prism.NGCanvas.handleRenderOp(NGCanvas.java:1219)
at com.sun.javafx.sg.prism.NGCanvas.renderStream(NGCanvas.java:1103)
at com.sun.javafx.sg.prism.NGCanvas.renderContent(NGCanvas.java:609)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:477)
at com.sun.javafx.tk.quantum.ViewPainter.paintImpl(ViewPainter.java:330)
at com.sun.javafx.tk.quantum.UploadingPainter.run(UploadingPainter.java:134)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
at java.lang.Thread.run(Thread.java:748)
编辑 2:我找到了提高 graphics2d 绘图质量的方法。通过为 graphics2d 对象设置渲染提示(感谢 Hylian Pickachu 的建议),正弦曲线看起来更平滑。它不像 canvas 示例中的正弦曲线那么尖锐,但我想我现在可以接受结果了。
提高 Graphics2D 质量的一种方法是使用 RenderingHints。 RenderingHints 允许您设置渲染质量与渲染性能之间的平衡,这是一个需要考虑的权衡,正如您所说,您确实喜欢使用 Graphics2D 而不是 Canvas 带来的性能提升。但是,这种方法将允许您继续使用 Graphics2D 并避免崩溃。
我想展示比较长的图表。我曾经使用 javafx canvas,但是当绘制的值太多时,有时会出现缓冲区溢出异常。我正在寻找一种不同的方法,并找到了一种使用 java.awt.graphics2d 绘制图表的方法。 graphics2d 的优点是性能提高了,我没有例外。缺点是图表的质量。使用 graphics2d 时,图表看起来不像 javafx.canvas 中的图表那样平滑。
这里有两个测试应用程序(一个使用 javafx canvas,另一个使用 java.awt.graphics2d),其中绘制了正弦波。
如何提高 graphics2d 示例的质量,使其看起来像 canvas 示例? 还是有其他我没有想到的方法可以解决我的问题?
Canvas 示例
public class CanvasDraw extends Application
{
private static final int PANEL_WIDTH = 400, PANEL_HEIGHT = 100;
public static void main(String[] args)
{
launch(args);
}
@Override
public void start(Stage stage)
{
stage.setTitle("CanvasDraw");
StackPane root = new StackPane();
Scene scene = new Scene(root);
root.getChildren().add(createCanvas());
stage.setScene(scene);
stage.show();
}
private Canvas createCanvas()
{
Canvas canvas = new Canvas(PANEL_WIDTH, PANEL_HEIGHT);
GraphicsContext gc = canvas.getGraphicsContext2D();
drawSinus(gc);
return canvas;
}
private void drawSinus(GraphicsContext gc)
{
double height = 50;
double xFactor = 0.5;
double yFactor = 50;
for (int index = 0; index < 720; index++)
{
double x = index * xFactor;
double y = Math.sin(Math.toRadians(index)) * yFactor + height;
if (index == 0)
{
gc.moveTo(x, y);
}
else
{
gc.lineTo(x, y);
}
}
gc.stroke();
}
}
新的 Graphics2D 示例
public class Graphics2DDraw extends Application
{
private static final int PANEL_WIDTH = 400, PANEL_HEIGHT = 100;
public static void main(String[] args)
{
launch(args);
}
@Override
public void start(Stage stage)
{
stage.setTitle("Graphics2DDraw");
StackPane root = new StackPane();
Scene scene = new Scene(root);
root.getChildren().add(createImageView());
stage.setScene(scene);
stage.show();
}
private ImageView createImageView()
{
BufferedImage bi = new BufferedImage(PANEL_WIDTH, PANEL_HEIGHT, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = bi.createGraphics();
g.setColor(Color.BLACK);
BasicStroke bs = new BasicStroke(1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
g.setStroke(bs);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
drawSinus(g);
return new ImageView(SwingFXUtils.toFXImage(bi, null));
}
private void drawSinus(Graphics2D g)
{
double height = 50;
double xFactor = 0.5;
double yFactor = 50;
int length = 720;
int lastX = 0;
int lastY = 0;
GeneralPath path = new GeneralPath();
for (int index = 0; index < length; index++)
{
double x3 = index * xFactor;
double y3 = Math.sin(Math.toRadians(index)) * yFactor + height;
if (index == 0)
{
path.moveTo(x3, y3);
}
else
{
path.lineTo(x3, y3);
}
}
g.draw(path);
g.dispose();
}
}
编辑 这是缓冲区溢出异常的样子:
java.nio.BufferOverflowException
at com.sun.javafx.sg.prism.GrowableDataBuffer.ensureReadCapacity(GrowableDataBuffer.java:317)
at com.sun.javafx.sg.prism.GrowableDataBuffer.getInt(GrowableDataBuffer.java:527)
at com.sun.javafx.sg.prism.GrowableDataBuffer.getFloat(GrowableDataBuffer.java:563)
at com.sun.javafx.sg.prism.NGCanvas.renderStream(NGCanvas.java:960)
at com.sun.javafx.sg.prism.NGCanvas.renderContent(NGCanvas.java:609)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:477)
at com.sun.javafx.tk.quantum.ViewPainter.paintImpl(ViewPainter.java:330)
at com.sun.javafx.tk.quantum.UploadingPainter.run(UploadingPainter.java:134)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
at java.lang.Thread.run(Thread.java:748)
java.lang.IllegalArgumentException: ALPHA color component is out of range
at com.sun.pisces.PiscesRenderer.checkColorRange(PiscesRenderer.java:113)
at com.sun.pisces.PiscesRenderer.setColor(PiscesRenderer.java:105)
at com.sun.prism.sw.SWPaint.setColor(SWPaint.java:76)
at com.sun.prism.sw.SWPaint.setPaintBeforeDraw(SWPaint.java:118)
at com.sun.prism.sw.SWPaint.setPaintFromShape(SWPaint.java:86)
at com.sun.prism.sw.SWGraphics.paintShape(SWGraphics.java:493)
at com.sun.prism.sw.SWGraphics.drawLine(SWGraphics.java:545)
at com.sun.javafx.sg.prism.NGCanvas.handleRenderOp(NGCanvas.java:1219)
at com.sun.javafx.sg.prism.NGCanvas.renderStream(NGCanvas.java:1103)
at com.sun.javafx.sg.prism.NGCanvas.renderContent(NGCanvas.java:609)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.sg.prism.NGGroup.renderContent(NGGroup.java:235)
at com.sun.javafx.sg.prism.NGRegion.renderContent(NGRegion.java:577)
at com.sun.javafx.sg.prism.NGNode.doRender(NGNode.java:2053)
at com.sun.javafx.sg.prism.NGNode.render(NGNode.java:1945)
at com.sun.javafx.tk.quantum.ViewPainter.doPaint(ViewPainter.java:477)
at com.sun.javafx.tk.quantum.ViewPainter.paintImpl(ViewPainter.java:330)
at com.sun.javafx.tk.quantum.UploadingPainter.run(UploadingPainter.java:134)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at com.sun.javafx.tk.RenderJob.run(RenderJob.java:58)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
at java.lang.Thread.run(Thread.java:748)
编辑 2:我找到了提高 graphics2d 绘图质量的方法。通过为 graphics2d 对象设置渲染提示(感谢 Hylian Pickachu 的建议),正弦曲线看起来更平滑。它不像 canvas 示例中的正弦曲线那么尖锐,但我想我现在可以接受结果了。
提高 Graphics2D 质量的一种方法是使用 RenderingHints。 RenderingHints 允许您设置渲染质量与渲染性能之间的平衡,这是一个需要考虑的权衡,正如您所说,您确实喜欢使用 Graphics2D 而不是 Canvas 带来的性能提升。但是,这种方法将允许您继续使用 Graphics2D 并避免崩溃。