我的问题如下:我的实际项目(下面的代码是简化版本)涉及许多同心圆(每个都有不同的颜色)和利用Timer的动画。使用 drawOval 方法绘制圆圈。
我的问题是,当绘制这些同心圆时,这些圆的轮廓中似乎存在大量的间隙,我猜这与圆由像素和线组成的事实有关。是任何形状,所以圆的外观是一种幻觉。我这样说是因为当我为 drawRect 交换 drawOval 方法时,这幅画看起来就像你期望的那样。
当搞乱其他人的代码时,我看到使用RenderingHints以某种方式解决了这个问题,但是动画速度超出了我觉得可以接受的程度。
下面是绘制内容的屏幕截图。我们没有看到一个坚固的不透明圆圈(因为在这个例子中绘制的所有圆圈都具有相同的颜色),我们看到了:
这是我的简化代码:
Test10
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class Test10 extends JPanel {
Circle[] circles;
public static void main(String[] args) {
new Test10().go();
}
void go() {
JFrame frame = new JFrame("Circle Test");
frame.getContentPane().add(this);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
circles = new Circle[200];
for (int i = 0; i < 200; i++) {
circles[i] = new Circle(i, ((2 * ( 200 - i) + 1)));
}
repaint();
frame.setPreferredSize(new Dimension(500,500));
frame.pack();
frame.setVisible(true);
}
public void paintComponent(Graphics g) {
for (Circle circle : circles ) {
circle.draw(g);
}
}
}
环
import java.awt.Graphics;
public class Circle {
int topLeft;
int diameter;
public Circle(int topLeft, int diameter) {
this.topLeft = topLeft;
this.diameter = diameter;
}
void draw(Graphics g) {
g.drawOval(topLeft, topLeft, diameter, diameter);
}
}
有人可以向我解释a)为什么这种情况发生,b)如何克服这个问题。
的更新
尝试了各种方法,包括从最外圈开始并使用 fillOval 而不是 drawOval ,并使用更高的笔画值,我仍然发现我有某些人工制品出现的问题类似于Pavel发布的截图。这是我运行动画的完整应用程序的截图,如果你仔细观察,你会发现大多数给定圆圈的颜色不一致,导致这些奇怪的结果。它们的分布实际上遵循与上面发布的屏幕截图相同的模式,因此这些选项无法解决基本问题。这是我的屏幕截图:
答案 0 :(得分:2)
画出完美的圆圈是不可能的。
尝试使用以下方法
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(2));
int i = 0;
for (Circle circle : circles ) {
Shape circle2 = new Ellipse2D.Double(i++, i, circle.diameter, circle.diameter);
g2d.draw(circle2);
}
}
你说你试过RenderingHints
,它减慢了你的动画,但你没有给我们任何动画代码,所以也许尝试我的代码(看看动画实现会很好)。它看起来更好,但仍然不是你想要的。将笔划设置为另一个值将解决此问题(设置为至少2)。另一个是使用.fill()
而不是.draw()
。我知道它并不完美,但你可以尝试一下。
另一个想法
我想,也许你可以为你的图像添加一些模糊,所以这些文物是不可见的? 我之前没有这样做过,但我找到了这个(found HERE):
private class BlurGlass extends JComponent {
private JFrame f;
public BlurGlass(JFrame f) {
this.f = f;
setOpaque(false);
setFocusable(false);
}
public void paintComponent(Graphics g) {
int w = f.getWidth();
int h = f.getHeight();
setLocation(0, 0);
setSize(w, h);
g.setColor(new Color(0, 0, 0, 0.3f));
g.fillRect(0, 0, w, h);
}
}
现在在go()
方法:
frame.setGlassPane(new BlurGlass(frame));
frame.getGlassPane().setVisible(true);
对我来说看起来好多了。使用此GlassPane颜色播放一下(尝试将.3f更改为其他值)。
答案 1 :(得分:1)
您可能希望Stroke更大。在类似于你的情况下我已经幸运了
答案 2 :(得分:0)
您可以尝试在Circle函数中添加此行:draw函数:
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
//and draw the Oval on g2
另一种解决方案可能是填充圈子:
Ellipse2D.Double circle = new Ellipse2D.Double(x, y, diameter, diameter);
g2.fill(circle);
答案 3 :(得分:0)
答案 4 :(得分:0)
请你试试fillOval方法而不是drawOval。
g.fillOval(topLeft, topLeft, diameter, diameter);
答案 5 :(得分:0)
扭转你的想法。从最外面的圆开始,然后绘制内圆等,以最小的圆圈结束。您应该在此过程中使用fillOval
。
答案 6 :(得分:0)
通常对圆圈/椭圆形有用的其他渲染提示是
g.setRenderingHint( RenderingHints. KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);