Добавление массива расширенных объектов jcomponent в jframe

Я начинаю с 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. Если я правильно помню, Layout по умолчанию - это BorderLayout, что позволяет использовать 5 компонентов в 5 разных точках. this.add(stars[i]); перезаписывает каждый ранее добавленный компонент, так как у вас может быть только один компонент на BorderLayout.CENTER (который используется по умолчанию и, следовательно, будет волшебным образом добавлен к вашему вызову add, так что на самом деле это this.add(stars[i], BorderLayout.CENTER);)

XtremeBaumer 11.04.2018 11:45

Предложения OP по улучшению пользовательского компонента: 1) не кодируйте цвет жестко. Вместо этого вы можете использовать метод setForeground (...), чтобы установить цвет для овала, а затем использовать getForeground () при рисовании. Тогда каждый овал может быть разного цвета. 2) Не указывайте размер жестко. Сделайте это параметром. Тогда каждый овал может быть разного размера. 3) реализовать метод getPreferredSize(). Это будет основано на параметре, предложенном в 2. Он используется менеджерами по компоновке для определения размера компонента.

camickr 11.04.2018 16:23
1
2
82
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В вашем случае вы не можете использовать диспетчер компоновки и вам нужно сбросить его до нуля. См. Мой код ниже

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).

camickr 11.04.2018 16:27
In your case you cannot use a layout manager - К вашему сведению. Вы можете рассмотреть возможность использования Перетащить макет. Он позволяет размещать компоненты в произвольном месте, при этом обеспечивая некоторые функциональные возможности макета, такие как установка размера компонента и определение предпочтительного размера панели, поэтому он по-прежнему будет работать в области прокрутки. Этот класс предполагает, что getPreferredSize () был реализован правильно, как предложение в моем комментарии к исходному вопросу.
camickr 11.04.2018 16:31

@camickr Спасибо за информацию. Наверное где-нибудь воспользуюсь. И еще раз большое спасибо за WrapLayout;)

Sergiy Medvynskyy 11.04.2018 17:14

Другие вопросы по теме