Java 将JComponent扩展对象数组添加到JFrame

Java 将JComponent扩展对象数组添加到JFrame,java,swing,jframe,jcomponent,Java,Swing,Jframe,Jcomponent,我从JFrame开始,我正在尝试制作一个StarField,现在我正在将Star JC组件添加到StarField JFrame中: import java.awt.Color; import java.awt.Graphics; import javax.swing.JComponent; public class Star extends JComponent{ public int x; public int y; private final Color colo

我从JFrame开始,我正在尝试制作一个StarField,现在我正在将Star JC组件添加到StarField JFrame中:

import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JComponent;

public class Star extends JComponent{
    public int x;
    public int y;
    private final Color color = Color.YELLOW;

    public Star(int x, int y) {
       this.x = x;
       this.y = y;
    }

    public void paintComponent(Graphics g) {
       g.setColor(color);
       g.fillOval(x, y, 8, 8);
    }   
}
和StarField代码:

import javax.swing.*;

public class StarField extends JFrame{
    public int size = 400;
    public  Star[] stars = new Star[50];

    public static void main(String[] args) {
        StarField field = new StarField();
        field.setVisible(true);
    }

    public StarField() {
        this.setSize(size, size);
        for (int i= 0; i< stars.length; i++) {
            int x = (int)(Math.random()*size);
            int y = (int)(Math.random()*size);
            stars[i] = new Star(x,y);
            this.add(stars[i]);
        }       
    }
}
import javax.swing.*;
公共类StarField扩展JFrame{
公共整数大小=400;
公众明星[]明星=新星[50];
公共静态void main(字符串[]args){
星域=新星域();
字段设置为可见(true);
}
公共星场(){
此.setSize(大小,大小);
对于(int i=0;i
问题是它只打印一颗星,我认为这是最后一颗星,coords的工作方式就像他们应该做的那样,所以我认为错误在于JComponent或JFrame实现,我在自学,所以可能我的代码不是使用swing的正确方式


谢谢你,对不起我的英语,我已经尽我所能写了。

在你的情况下,你不能使用布局管理器,需要将其重置为空。请参阅下面的“我的代码”

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.WindowConstants;

public class StarField extends JFrame {
    public int size = 400;

    public Star[] stars = new Star[50];

    public static void main(String[] args) {
        StarField field = new StarField();
        field.setVisible(true);
    }

    public StarField() {
        this.setSize(size, size);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        // usually you should use a normal layout manager, but for your task we need null
        getContentPane().setLayout(null);
        for (int i = 0; i < stars.length; i++) {
            int x = (int) (Math.random() * size);
            int y = (int) (Math.random() * size);
            stars[i] = new Star(x, y);
            this.add(stars[i]);
        }
    }

    public class Star extends JComponent {

        private final Color color = Color.YELLOW;

        public Star(int x, int y) {
            // need to set the correct coordinates
            setBounds(x, y, 8, 8);
        }

        @Override
        public void paintComponent(Graphics g) {
            g.setColor(color);
            g.fillOval(0, 0, getWidth(), getHeight());
        }
    }
}
导入java.awt.Color;
导入java.awt.Graphics;
导入javax.swing.JComponent;
导入javax.swing.JFrame;
导入javax.swing.WindowConstants;
公共类StarField扩展JFrame{
公共整数大小=400;
公众明星[]明星=新星[50];
公共静态void main(字符串[]args){
星域=新星域();
字段设置为可见(true);
}
公共星场(){
此.setSize(大小,大小);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setLocationRelativeTo(空);
//通常您应该使用普通的布局管理器,但对于您的任务,我们需要null
getContentPane().setLayout(null);
对于(int i=0;i
最好看一看
LayoutManager
。如果我没记错的话,默认的
Layout
BorderLayout
,它允许在5个不同的点上总共有5个组件<代码>此。添加(星号[i])
覆盖以前添加的每个组件,因为您只能在
BorderLayout.CENTER
上有一个组件(这是默认设置,因此会神奇地附加到
add
调用,因此它实际上是
this.add(stars[i],BorderLayout.CENTER);
)建议OP改进自定义组件:1)不要硬编码颜色。相反,您可以使用setForeground(…)方法设置椭圆形的颜色,然后在绘制时使用getForeground()。然后每个椭圆形可以是不同的颜色。2) 不要硬编码尺寸。将此设置为参数。然后每个椭圆形可以是不同的大小。3) 实现
getPreferredSize()
方法。这将基于2中建议的参数。布局管理器使用它来确定组件的大小。(1+)用于解决布局问题和改进的绘制代码,以便始终在(0,0)处完成绘制。
在您的情况下,您不能使用布局管理器
-仅供参考。你可以考虑使用。它允许您将组件放置在随机位置,同时仍提供一些布局功能,如设置组件的大小和确定面板的首选大小,因此它仍可以在滚动窗格中工作。此类将假定getPreferredSize()已按照我对原始问题的评论中的建议正确实现。@camickr感谢您提供的信息。也许我会在什么地方用它。再次感谢您的演出;)