如何将 2 java 个摆动元素放在彼此之上?

How can I put 2 java swing elements on top of each other?

所以我有一个正在做的项目,它绘制一个圆和一个正方形,并通过按钮调整它们的大小。一切都很好,但是我必须做的是将圆圈放在正方形内,这样圆圈就被刻上了,我似乎无法弄清楚如何将两个摆动元素放在一起。 这是当前情况的图片:

这里是它应该是什么样子的 photoshop 版本:

这是我的圈子class:

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;

public class Picture extends Canvas implements VetoableChangeListener, PropertyChangeListener {
    private final int SIZE = 100;
    private int radius = 1;

    public Picture() {
        setSize(SIZE,SIZE);
    }

    public void vetoableChange(PropertyChangeEvent pce) throws PropertyVetoException {
        if ((pce.getPropertyName()).equals("value")) {
            int v = (Integer)pce.getNewValue();
            if ((v <=0)||(v > SIZE/2))
                throw new PropertyVetoException ("Value out of bounds!", pce);        
        }   
    }


    public void propertyChange(PropertyChangeEvent pce) {
        if ((pce.getPropertyName()).equals("value")) {
            setRadius((Integer)pce.getNewValue());
            repaint(); 
        }
    }

    public void setRadius(int radius) {
        this.radius = radius;
    }

    public int getRadius() {
        return this.radius;
    }

    public void paint (Graphics g) {
        Dimension d = getSize();
        g.setColor(Color.GREEN);
        g.fillOval(d.width/2 - radius, d.height/2 - radius, radius*2, radius*2);
    }

}

这是我的 Square class,它类似于:

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;


public class Square extends Canvas implements VetoableChangeListener, PropertyChangeListener {
    private final int SIZE = 100;
    private int side = 1;
    public Square() {
        setSize(SIZE,SIZE);
    }

    public void vetoableChange(PropertyChangeEvent pce) throws PropertyVetoException {
        if ((pce.getPropertyName()).equals("value")) {
            int v = (Integer)pce.getNewValue();
            if ((v <=0)||(v > SIZE/2))
                throw new PropertyVetoException ("Value out of bounds!", pce);        
        }   
    }

    public void propertyChange(PropertyChangeEvent pce) {
        if ((pce.getPropertyName()).equals("value")) {
            setSide((Integer)pce.getNewValue());
            repaint();
        }
    }

    public void setSide(int side) {
        this.side = side;
    }

    public int getSide() {
        return this.side;
    }

    public void paint (Graphics g) {
        Dimension d = getSize();
        g.setColor(Color.BLUE);
        g.drawRect(d.width/2 - side, d.height/2 - side, side*2, side*2);
    }

}

我已将它们都添加到调色板中。请向我解释如何将这两个元素放在一起,我是 Swing 和 JavaBeans 的新手。

提前致谢!

首先,您不应该扩展 Canvas,那是一个 AWT 组件。在 Swing 中,您可以扩展 JComponent(或 JPanel),然后将自定义绘画添加到 paintComponent(...) 方法。阅读 Swing 教程中有关自定义绘画的部分以获取更多信息。

另外,您应该使每个组件透明(通过在组件的构造函数中使用 setOaque(false),这样一个组件的背景就不会覆盖另一个组件。

I've added both of them to the palette.

由于使用了布局管理器的规则,它们都显示在调色板的顶部:

所以你有几个选择:

  1. 利用Swings parent/child关系。那就是将正方形添加到调色板,将圆形添加到正方形。这意味着您需要在正方形上设置一个布局管理器,以便您可以向其中添加圆圈。一个BorderLayout可能好用。

  2. 使用 OverlayLayout 创建面板。此布局管理器允许您在同一面板中将两个组件叠加在一起。您可以将正方形添加到面板,将圆形添加到面板(按此顺序,因为 Swing 会先绘制添加到面板的最后一个组件)。

  3. 一个完全不同(并且可能更简单)的选项是使用单个组件并在 paintComponent() 方法中绘制正方形和圆形。

您至少应该将 Circle 和 Square 上的 isOpaque 覆盖为 return false,因此未绘制的像素将被视为 "show-through"。

接下来您还需要在容器中使用自由布局,以便能够控制对象的准确位置。

注意:不要使用Canvas,最好不要子类化任何组件来表示绘图,只需实现一些需要绘制图形的方法(比如draw)使用并覆盖容器的 paintComponent 以在每个绘图对象上调用该方法:

class Circle implements Drawable {
    int x; int y; int radius;
    public void draw(Graphics g) {
        g.fillOval(x - radius, y - radius, radius*2, radius*2);
    }
}

class MyContainer extends JPanel {
    List<Drawable> ld = ...
    public void paintComponent(Graphics g) {
        for (Drawable d : ld) {
            d.draw(g);
        }
    }