【问题标题】:Adding an array of JComponent extended objects to a JFrame将 JComponent 扩展对象数组添加到 JFrame
【发布时间】:2018-04-11 09:39:56
【问题描述】:

我从 JFrame 开始,我正在尝试制作一个 StarField,目前我正在将 Star JComponent 添加到 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]);
        }       
    }
}

问题在于它只打印一颗星,我认为它是最后一颗星,坐标工作正常,所以我认为错误出在 JComponent 或 JFrame 实现中,我自己-学习,所以也许我的代码不是使用swing的正确方法。

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

【问题讨论】:

  • 最好看看LayoutManager。如果我没记错的话,默认的LayoutBorderLayout,它允许在 5 个不同的位置总共有 5 个组件。 this.add(stars[i]); 覆盖之前添加的每个组件,因为您只能在 BorderLayout.CENTER 处拥有一个组件(这是默认设置,因此会神奇地附加到您的 add 调用中,因此它实际上是 this.add(stars[i], BorderLayout.CENTER);
  • 对 OP 改进自定义组件的建议:1) 不要对颜色进行硬编码。相反,您可以使用 setForeground(...) 方法为椭圆设置颜色,然后在绘制时使用 getForeground()。然后每个椭圆可以是不同的颜色。 2)不要硬编码大小。将此作为参数。然后每个椭圆可以是不同的大小。 3) 实现getPreferredSize() 方法。这将基于 2 中建议的参数。布局管理器使用它来确定组件的大小。

标签: java swing jframe jcomponent


【解决方案1】:

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

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());
        }
    }
}

【讨论】:

  • (1+) 用于解决布局问题并改进了绘画代码,以便始终在 (0, 0) 处完成绘画。
  • In your case you cannot use a layout manager - 仅供参考。您可以考虑使用Drag Layout。它允许您将组件放置在随机位置,同时仍然提供一些布局功能,例如设置组件的大小和确定面板的首选大小,因此它仍然可以在滚动窗格中工作。此类将假定 getPreferredSize() 已按照我对原始问题的评论中的建议正确实施。
  • @camickr 感谢您的信息。可能我会在某个地方使用它。再次感谢 WrapLayout ;)
猜你喜欢
  • 1970-01-01
  • 2023-04-04
  • 2012-11-21
  • 2021-02-11
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 2017-09-26
相关资源
最近更新 更多