简体   繁体   English

如何在 JPanel 上绘制矩形?

[英]How can you draw rectangles on a JPanel?

I'm trying to create a program that generates rectangles using a slider.我正在尝试创建一个使用 slider 生成矩形的程序。 The user should be able to move the slider and rectangles should appear on the JPanel above the slider with random positions.用户应该能够移动 slider 并且矩形应该出现在 JPanel 上 slider 上方的随机位置。 I have tried running the program but I'm still unable to display anything, I move the slider but nothing appears on screen.我已经尝试运行该程序,但仍然无法显示任何内容,我移动了 slider 但屏幕上没有出现任何内容。 I have tried coding this program using examples from the book but im stuck when it comes to actually drawing the rectangles.我曾尝试使用书中的示例编写此程序,但在实际绘制矩形时我卡住了。 I am able to create and change the layouts as well as to display the slider and a few labels but i'm unable to get the rectangles to appear on the JPanel.我能够创建和更改布局以及显示 slider 和一些标签,但我无法让矩形出现在 JPanel 上。 Here is my code:这是我的代码:

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

I have tried drawing one simple rectangle but not even that appears on the JPanel, let alone multiple.我尝试过绘制一个简单的矩形,但 JPanel 上什至没有出现,更不用说多个了。 Any resources to further look into this would also bee highly appreciated.任何进一步研究此问题的资源也将受到高度赞赏。

You cannot draw directly on top of a JFrame.您不能直接在 JFrame 上绘图。 For "custom painting" (as this is called) you need to create a subclass of a component that overrides the paintComponent method.对于“自定义绘画” (称为),您需要创建一个覆盖paintComponent方法的组件的子类。 For example a JPanel:例如一个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);
        }

    }
}

You use this custom component the same way you would use a JPanel:您可以像使用 JPanel 一样使用此自定义组件:

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

To draw fewer or more rectangles, the simplest thing you can do is change the numberOfRectangles of the custom component and then ask it to repaint itself.要绘制更少或更多的矩形,您可以做的最简单的事情是更改自定义组件的numberOfRectangles ,然后要求它重新绘制自己。

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

Note that this is a simplified demo and does not demonstrate "good practices" such as encapsulation.请注意,这是一个简化的演示,并未演示封装等“良好实践”。 A more advanced technique is to using the model-view-controller pattern, and create a "model" object that encapsulates what is supposed to be drawn.更高级的技术是使用 model-view-controller 模式,并创建一个“模型” object 来封装应该绘制的内容。 You can read more about how that works for example here: The MVC pattern and Swing您可以在此处阅读有关其工作原理的更多信息: MVC 模式和 Swing

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM