如何在 JPanel 上绘制矩形?

How can you draw rectangles on a JPanel?

我正在尝试创建一个使用滑块生成矩形的程序。 用户应该能够移动滑块,并且矩形应该以随机位置出现在滑块上方的 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 上,更不用说多个了。任何进一步调查此问题的资源也将受到高度赞赏。

您不能直接在 JFrame 上绘制。对于 "custom painting"(如此称呼),您需要创建一个覆盖 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();

请注意,这是一个简化的演示,并未演示封装等“良好做法”。一种更高级的技术是使用模型-视图-控制器模式,并创建一个“模型”对象来封装应该绘制的内容。您可以在此处阅读更多有关其工作原理的信息:The MVC pattern and Swing