在JPanel或JComponent上绘制同心形状

时间:2012-12-02 15:39:19

标签: java swing jpanel paint jcomponent

我基本上是开始使用swing的新手。所以在这里忍受我。我可以在swing库中使用premade组件做简单的GUI。然而,现在它已经到了我试图弄清楚如何在JPanel上绘制基本形状的时候。在这种情况下,它是我已经递归收集的Square对象的集合,并且应该彼此同心地显示。

几个星期前,我们做了一个涉及绘制形状的小项目,除了这些形状直接绘制到JFrame上。现在我试图在JPanel或扩展JComponent的类中执行此操作,我遇到了太多绊脚石。此时,JPanel上没有显示任何内容。

这是我到目前为止的课程。

方形等级。这只是创建一个简单的Square

public class Square
{
    private int x, y, width, height;
    private Color theColor;

    public Square(int xS, int yS, int widthS, int heightS, Color squareColor)
    {
        x = xS;
        y = yS;
        width = widthS;
        height = heightS;
        theColor = squareColor;
    }

    public void draw(Graphics2D g2)
    {
        g2.setColor(theColor);
        Rectangle rectDraw = new Rectangle(x,y,width,height);
        g2.draw(rectDraw);
    }
}

GUI类

public class SquareGUI extends JFrame
{
    private JComboBox colorChoices, shapeChoices;
    private JTextArea numberOfTimes;
    private SquarePanel thisPanel;

    public SquareGUI()
    {
        thisPanel = new SquarePanel();
        JPanel northPanel = new JPanel(new FlowLayout());
        setSize(640, 480);
        setLayout(new BorderLayout());
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        ActionListener listener = new CommandListener();

        colorChoices = new JComboBox();
        shapeChoices = new JComboBox();
        numberOfTimes = new JTextArea(1,3);
        colorChoices.addItem("Black");
        colorChoices.addItem("Blue");
        colorChoices.addItem("Red");
        colorChoices.addItem("Green");
        shapeChoices.addItem("Square");
        shapeChoices.addItem("Circle");

        colorChoices.addActionListener(listener);
        shapeChoices.addActionListener(listener);



        northPanel.add(colorChoices);
        northPanel.add(shapeChoices);
        northPanel.add(new JLabel("Number of Shapes:"));
        northPanel.add(numberOfTimes);
        add(northPanel, BorderLayout.NORTH);

        add(thisPanel, BorderLayout.CENTER);

        setVisible(true);
    }

    public void addShapesRecursively(int x, int y, int width, int height, int times)
    {
        if (times == 0) { return; }
        Color colorChoice = null;
        switch (colorChoices.getSelectedIndex())
        {
            case 0: colorChoice = Color.BLACK; break;
            case 1: colorChoice = Color.BLUE; break;
            case 2: colorChoice = Color.RED; break;
            case 3: colorChoice = Color.GREEN; break;
        }
        if (shapeChoices.getSelectedIndex() == 0)
            thisPanel.add(new Square(x, y, width, height, colorChoice));
        else
            System.out.println("todo");

        addShapesRecursively(x-15, y-15, width + 15, height + 15, times - 1);
    }

    class CommandListener implements ActionListener
    {

        @Override
        public void actionPerformed(ActionEvent arg0) 
        {
            addShapesRecursively(getWidth()/2,getHeight()/2,20,20,Integer.parseInt(numberOfTimes.getText()));
        }

    }

    public static void main(String[]args)
    {
        new SquareGUI();
    }
}

我的JPanel类应该显示正方形。

public class SquarePanel extends JPanel
{

    private ArrayList<Square> squareList;
    public SquarePanel()
    {
        setBackground(Color.WHITE);
        squareList = new ArrayList<Square>();

    }

    protected void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D)g;

        for (int i = 0; i < squareList.size(); i++)
        {
            Square tempSquare = squareList.get(i);
            tempSquare.draw(g2);
        }
    }

    public void add(Square addSquare)
    {
        squareList.add(addSquare);
    }
}

我很抱歉没有评论等等。只是拉着我的头发试图让这个工作。我知道递归位有效,因为在运行后该ArrayList中有大量的Square对象。这只是在JPanel上绘制这些正方形的问题。

我首先尝试使用扩展JComponent的单独类,但是永远不会让覆盖的paintComponent永远触发它。所以我环顾四周,发现你可以覆盖JPanel中的paintComponent。所以它按预期射击,但JPanel本身没有任何东西出现。

我的整体问题是,如何正确显示方块?

1 个答案:

答案 0 :(得分:2)

您需要鼓励小组自行更新。

在面板的repaint方法中添加对add的调用...

public void add(Square addSquare) {
    squareList.add(addSquare);
    repaint();
}