我正在使用Swing在Java中创建一个小型GUI。我试图让它做的就是取ArrayList
Circle
个并绘制它们。我遇到了两个问题:
1)我必须在绘制圆圈之前反复调用draw
方法。如果我只是在没有任何反应时调用我的draw
方法,我会得到一张空白的图纸。如果我在一个运行时间小于30毫秒的循环中调用它,它只会绘制我想要绘制的两个圆圈中的第一个。最后,如果我将其调用超过30毫秒,则会绘制我想要绘制的两个圆圈。
和
2)当我移动其中一个圆圈时,我在图纸上出现“闪烁”。
我对Swing编程不太熟悉。我查看了示例代码并观看了一些视频 - 以及我对我的看法。但我认为我一定搞砸了,因为在我看过的视频中看起来并不像这样。
这是我的GUI
课程:
package gui;
import draw.*;
import java.util.List;
import javax.swing.*;
public class GUI extends JFrame {
private CirclePainter drawingBoard = new CirclePainter();
public GUI()
{
setSize(500, 500);
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setVisible(true);
this.add(drawingBoard);
drawingBoard.setVisible(true);
}
public void draw(List<Circle> circles)
{
drawingBoard.paintComponent(drawingBoard.getGraphics(), circles);
}
}
我的CirclePainter
班
package gui;
import draw.Circle;
import javax.swing.*;
import java.awt.*;
import java.util.List;
class CirclePainter extends JPanel
{
public void paintComponent(Graphics graphics, List<Circle> circles)
{
super.paintComponent(graphics);
for(Circle circle : circles)
graphics.fillOval(circle.getX(), circle.getY(), circle.getRadius() * 2, circle.getRadius() * 2);
}
}
编辑:编辑了一些代码,因为这是针对学校项目的。剩下的代码应该足以让将来访问的人仍然能够理解这个问题。
答案 0 :(得分:7)
paintComponent(...)
。repaint()
来建议绘制。getGraphics()
调用获得的Graphics对象进行绘制。而是使用paintComponent
方法中提供的Graphics对象进行绘制。while (true)
循环,因为您可能会占用Swing事件线程并冻结GUI。使用Swing Timer进行简单的动画制作。contains(Point p)
方法,可以帮助您确定鼠标点击是否落入您的圈内。g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
其中g2是您的Graphics2D对象。paintComponent
方法不是真正的paintComponent覆盖,因此无法正常工作。它应该是protected
方法,而不是public
,它应该有一个参数,Graphics
对象和n到第二个参数,您应该在上面放置@Override
注释它。例如,请查看我的this answer类似问题。
使用_x和_y将圆圈居中并使用渲染提示的paintComponent方法示例:
class CirclePainter extends JPanel implements Iterable<Circle> {
private static final int PREF_W = 500;
private static final int PREF_H = PREF_W;
private CircleList circleList = new CircleList();
@Override
protected void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
Graphics2D g2 = (Graphics2D) graphics;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
for (Circle circle : circleList) {
// if x and y are the center points, then you must subtract the radius.
int x = circle.getX() - circle.getRadius();
int y = circle.getY() - circle.getRadius();
int width = circle.getRadius() * 2;
int height = width;
g2.fillOval(x, y, width, height);
}
}
答案 1 :(得分:4)
在您的代码和Hovercraft Full Of Eels的建议的基础上,通过对GUI和CirclePainter类的这些修改,可以朝着正确的方向迈出一小步:
// GUI.draw
public void draw(List<Circle> circles)
{
// drawingBoard.paintComponent(drawingBoard.getGraphics(), circles);
drawingBoard.setCircles(circles);
drawingBoard.repaint();
}
class CirclePainter extends JPanel
{
// public void paintComponent(Graphics graphics, List<Circle> circles)
// {
// super.paintComponent(graphics);
// for(Circle circle : circles)
// graphics.fillOval(circle.getX(), circle.getY(), circle.getRadius() * 2, circle.getRadius() * 2);
// }
private List<Circle> circles;
public void setCircles(final List<Circle> circles) {
this.circles = circles;
}
@Override
protected void paintComponent(final Graphics graphics) {
super.paintComponent(graphics);
for (Circle circle : circles)
graphics.fillOval(circle.getX(), circle.getY(), circle.getRadius() * 2, circle.getRadius() * 2);
}
}
通过这种方式,您可能无法解决所有基本问题,但只需稍作修改即可使程序正常运行。 Swing是一个非常好的图书馆,可以非常有趣地了解更多信息。