用Java绘制并移动一个圆圈

Tho*_*kke 2 java user-interface swing jpanel jframe

我正在使用Swing在Java中创建一个小型GUI.所有我想要得到它做的是采取ArrayListCircleS和吸引他们.我遇到了两个问题:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我的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);
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑:编辑一些代码,因为这是一个学校项目.剩下的代码应该足以让将来访问的人仍然能够理解这个问题.

Hov*_*els 7

  1. 永远不要paintComponent(...)像你一样直接打电话.
  2. 而是repaint()在必要时通过调用组件来建议绘制.
  3. 不要使用通过getGraphics()组件调用获得的Graphics对象进行绘制.而是使用paintComponent方法中提供的Graphics对象进行绘制.
  4. 避免while (true)在Swing GUI中使用循环,因为您可能会占用Swing事件线程并冻结GUI.使用Swing Timer进行简单的动画制作.
  5. 您可能甚至不需要Swing Timer,因为您的动画可以由MouseListener/MouseMotionListener驱动.
  6. 重要的是 - 请阅读Swing绘画和其他教程,因为大部分信息都可以在那里找到.看起来你在猜测如何编写一些代码,在绘制或动画GUI时这是一件危险的事情.您可以在Swing信息链接中找到大多数教程.
  7. 考虑使用Shape对象来表示Circle,例如ellipse2D.这有助于它有一些非常有用的方法,包括一种contains(Point p)方法,可以帮助您确定鼠标点击是否落在您的圆圈内.
  8. 您需要决定_x和_y在哪里代表圆圈的中心点.如果是这样,那么你需要通过向左和向上移动_radius量来调整你的绘图.
  9. 考虑将Graphics对象转换为Graphics2D对象,以便使用其额外的方法和属性.
  10. 一个这样的属性是RenderingHings.设置你的Graphics2D RenderingHints以允许消除锯齿以摆脱你的图像"锯齿".这可以通过以下方式完成:g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);其中g2是您的Graphics2D对象.
  11. 您的paintComponent方法不是真正的paintComponent覆盖,因此将无法正常工作.它应该是一个protected方法,而不是public它应该有一个参数,一个Graphics对象,并且nto第二个参数,你应该将@Override注释放在它上面.

例如,请看一下类似问题的答案.

paintComponent方法的一个示例,它将圆圈居中于_x和_y并使用渲染提示:

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);
      }
   }
Run Code Online (Sandbox Code Playgroud)