Как нарисовать прямоугольники на панели JPanel? - PullRequest
0 голосов
/ 12 июля 2020

Я пытаюсь создать программу, которая генерирует прямоугольники с помощью ползунка. Пользователь должен иметь возможность перемещать ползунок, и прямоугольники должны появляться на панели JPanel над ползунком со случайными позициями. Я пробовал запустить программу, но все равно ничего не могу отобразить, я перемещаю ползунок, но на экране ничего не появляется. Я пробовал кодировать эту программу, используя примеры из книги, но я застрял, когда дело доходит до рисования прямоугольников. Я могу создавать и изменять макеты, а также отображать ползунок и несколько ярлыков, но мне не удается отобразить прямоугольники на панели JPanel. Вот мой код:

import java.util.*;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JLabel;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Dimension;
import java.lang.Object;

public class RectangleFrame extends JFrame
{
    private static final int FRAME_WIDTH = 600;
    private static final int FRAME_HEIGHT = 500;
    
    private JPanel RectanglePanel;
    private JSlider RectangleSlider;
    
    int x = 0;
    int y = 0;
    
    /**Creates a new Rectangle frame objects.
     Creates control panel and sets the size.*/
    public RectangleFrame()
    {
        RectanglePanel = new JPanel();
        RectanglePanel.setPreferredSize(new Dimension(600, 300));
        
        add(RectanglePanel, BorderLayout.CENTER);
        createControlPanel();
        setRectangles();
        setSize(FRAME_WIDTH,FRAME_HEIGHT);
    }
    
    
    class RectangleListener  implements ChangeListener
    {
        public void stateChanged(ChangeEvent event)
        {
            setRectangles();
        }
    }
    
    
    /**Creates the Panel where the user can slide and generate rectangles. */
    public void createControlPanel()
    {
        ChangeListener listener = new RectangleListener();
        
        RectangleSlider = new JSlider(JSlider.HORIZONTAL, 1, 20, 1);
        RectangleSlider.addChangeListener(listener);
        
        JPanel controlPanel = new JPanel();
        controlPanel.setLayout(new GridLayout(1,3));
        
        controlPanel.add(new JLabel("Fewer"));
        controlPanel.add(RectangleSlider);
        controlPanel.add(new JLabel("More"));
        
        add(controlPanel, BorderLayout.SOUTH);
        
    }
    
    public void setRectangles()
    {
        
        
        Random random = new Random();

        
        //Read slider value
        int numberOfRectangles = RectangleSlider.getValue();
        
        for(int i = 0; i < numberOfRectangles; i++)
        {
            x = random.nextInt(540);
            y = random.nextInt(290);
            
            
        }

    }
    
    
    protected void paintComponent(Graphics g) 
    {
        super.paintComponents(g);
        
        g.setColor(Color.BLACK);
        g.drawRect(x, y, 60, 10);
    }  
}

Я попытался нарисовать один простой прямоугольник, но даже не тот, который отображается на панели JPanel, не говоря уже о нескольких. Мы также будем очень признательны за любые ресурсы для дальнейшего изучения этого вопроса.

1 Ответ

1 голос
/ 12 июля 2020

Вы не можете рисовать прямо поверх JFrame. Для «нестандартной окраски» (как это называется) вам необходимо создать подкласс компонента, который переопределяет метод paintComponent. Например, JPanel:

class RectanglePanel extends JPanel {

    int numberOfRectangles = 2;

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.setColor(Color.BLACK);
        Random random = new Random(42);

        for (int i = 0; i < numberOfRectangles; i++) {
            x = random.nextInt(540);
            y = random.nextInt(290);
            g.drawRect(x, y, 60, 10);
        }

    }
}

Вы используете этот пользовательский компонент так же, как и JPanel:

    rectanglePanel = new RectanglePanel();
    rectanglePanel.setPreferredSize(new Dimension(600, 300));
    add(rectanglePanel, BorderLayout.CENTER);

Чтобы нарисовать меньше или больше прямоугольников, самое простое, что вы можете сделать это изменить numberOfRectangles настраиваемого компонента, а затем попросить его перерисовать себя.

int numberOfRectangles = RectangleSlider.getValue();
rectanglePanel.numberOfRectangles = numberOfRectangles;
rectanglePanel.repaint();

Обратите внимание, что это упрощенная демонстрация и не демонстрирует «хорошие практики», такие как инкапсуляция. Более продвинутый метод заключается в использовании шаблона модель-представление-контроллер и создании объекта «модель», который инкапсулирует то, что предполагается рисовать. Вы можете узнать больше о том, как это работает, например здесь: Паттерн MVC и Swing

...