2017-10-16 58 views
0

所以我一直在这个问题上停留了一段时间,而且我非常渴望获得帮助。请帮帮我。我有3个类:在Java GUI中创建实例的画圆

圆形只是假设在由Frame创建的框架中随机起始位置(并定义半径)绘制一个圆。

框架是addCircle(),bounce(),start(),stop(),run()(移动圆圈)和quit()方法的主类。这个类还创建了圆圈添加到的框架。

Interfa只是现在一个界面框架,我定义了半径,圆圈数量和框架大小。

无论我怎么努力,我不能添加两个以上的圆(一个是彩色的,一个是不是):

的“递归的方式”:

private static void addCircle(int n){ 
    Circle[] circles = new Circle[n+10]; 
    if (n > 0){ 
     circles[circleAdd] = new Circle(); 
     frame.add(circles[circleAdd]); 
     circleAdd = circleAdd + 1; 
     addCircle(n-1); 
    } 
    } 

普通itterative方式

private static void addCircles(int n){ 
    ArrayList<Circle> circles = new ArrayList<Circle>(); 
    for(int i = 0; i<=n;i++){ 
    circles.add(new Circle()); 
    frame.add(circles.get(i)); 
    } 
} 

这就是我如何创建我的框架:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.util.*; 

public Class Frame{ 

    private static JFrame frame; 
    private static int circleAdd = 0; 
    private static JPanel fra; 

    public static void mainFrame(){ 
    frame = new JFrame(); 
    frame.setSize(500,500); 
    frame.setVisible(true); 
    fra = new JPanel(); 
    frame.add(fra); 
... 
//addCircle and addCircles 
... 
public static void main.. 
    } 
} 

这是我的圈子:

import java.awt.*; 
import javax.swing.*; 
import java.util.Random; 

public class Circle extends JPanel{ 
    private Random random = new Random(); 

    public void paint(Graphics g){ 

    int randX = random.nextInt(250)+50; 
    int randY = random.nextInt(250)+50; 
    g.drawOval(randX,randY,50,50); 
    g.setColor(Color.ORANGE); 
    g.fillOval(100,100,50,50); 
    } 

} 
+0

我认为您使用的是错误的gui框架。您应该切换到Swing的继任者[JavaFX](https://docs.oracle.com/javase/8/javafx/get-started-tutorial/index.html)。你会在那里找到['Circle'](https://docs.oracle.com/javase/8/javafx/api/javafx/scene/shape/Circle.html)类,还有很多类可以帮助你在它周围做动画。 –

回答

2

我建议你一般的做法是错误的。而不是使用JPanel作为元素,你应该有一个JPanel能够绘制任意数量的“圆圈”。 Graphics2D API能够绘制复杂的形状(包括椭圆形)。

我能看到的主要问题是:

  • JFrame默认使用BorderLayout,这种只允许一个单一的组件被放置在每五个可用位置
  • 布局管理器依靠的preferred/minimum/maximumSize提示以确定组件的大小。他们还负责决定组件的放置位置。在当前的实现,这将意味着,它可能为你绘制超出部分
  • 重写paint不推荐的可见光范围内,并没有打电话给super.paint可能会导致一些意外和难以诊断的问题
  • 绘画可以发生在任何时间,所以在paint方法使用随机值会造成用户界面不断地改变

相反,你可以定义自己的Circle类需要你想要的位置和大小,并简单地充当货柜

public class Circle { 
    private int x; 
    private int y; 
    private int radius; 

    private Ellipse2D shape; 

    public Circle(int x, int y, int radius) { 
     this.x = x; 
     this.y = y; 
     this.radius = radius; 

     this.shape = new Ellipse2D.Double(x, y, radius * 2, radius * 2); 
    } 

    public int getX() { 
     return x; 
    } 

    public int getY() { 
     return y; 
    } 

    public int getRadius() { 
     return radius; 
    } 

    public Rectangle getBounds() { 
     return shape.getBounds(); 
    } 

    public void paint(Graphics2D g2d) { 
     g2d.setColor(Color.ORANGE); 
     g2d.fill(shape); 
    } 
} 

这只是一个容器类,它代表需要产生所需结果的信息。它有一个说服方法,它能够绘制形状本身。

你会那么需要创建这些形状的List并绘制到您的组件

public class TestPane extends JPanel { 

    private List<Circle> circles = new ArrayList<>(10); 
    private Dimension size; 

    public TestPane() { 
     Random random = new Random(); 
     int maxX = 0; 
     int maxY = 0; 
     for (int index = 0; index < 10; index++) { 
      int randX = random.nextInt(250) + 50; 
      int randY = random.nextInt(250) + 50; 
      circles.add(new Circle(randX, randY, 25)); 

      maxX = Math.max(maxX, randX + 50); 
      maxY = Math.max(maxY, randY + 50); 
     } 
     size = new Dimension(maxX, maxY); 
    } 

    @Override 
    public Dimension getPreferredSize() { 
     return size; 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     for (Circle circle : circles) { 
      Graphics2D g2d = (Graphics2D) g.create(); 
      circle.paint(g2d); 
      g2d.dispose(); 
     } 
    } 

} 

你们其中一人似乎缺乏理解的事情是如何画实际上是在Swing工作。

首先查看Performing Custom PaintingPainting in AWT and Swing了解更多详情。

更深入理解布局管理器和组件层次结构如何工作也不会造成伤害