简体   繁体   English

如何将2个Java swing元素彼此叠加?

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

so I have this project that I'm doing, which draws a circle and a square, and resizes them through buttons. 所以我有一个我正在做的项目,它画一个圆和一个正方形,并通过按钮调整它们的大小。 Everything works great, however what I must do is put the circle inside the square, so that the circle is inscribed, and I can't seem to figure out how to put both swing elements on top of each other. 一切都很好,但是我必须做的是将圆放置在正方形内,这样就将圆内切了,而且我似乎无法弄清楚如何将两个摆动元件彼此叠置。 Here's a picture of how it currently is: 这是当前情况的图片:

在此处输入图片说明

And here's a photoshop version of how it should look like: 这是它的外观的photoshop版本:

在此处输入图片说明

Here's my Circle class: 这是我的Circle课程:

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

}

And here's my Square class, which is similar: 这是我的Square班级,类似于:

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

}

I've added both of them to the palette. 我已经将它们都添加到了调色板中。 Would you please explain to me how to put those both elements on top of each other, I'm new to Swing and JavaBeans. 您能否向我解释一下如何将这两个元素相互叠加,我对Swing和JavaBeans还是陌生的。

Thanks in advance! 提前致谢!

First of all you should not be extending Canvas, that is an AWT component. 首先,您不应该扩展Canvas,它是AWT组件。 In Swing you can extend JComponent (or JPanel) and then you add custom painting to the paintComponent(...) method. 在Swing中,您可以扩展JComponent(或JPanel),然后将自定义绘画添加到paintComponent(...)方法。 Read the section from the Swing tutorial on Custom Painting for more information. 阅读Swing教程中有关Custom Paint的部分,以获取更多信息。

Also you should make each component transparent (by using setOaque(false) in the constructor of the component so that the background of one component does not cover the other. 另外,还应该使每个组件透明(通过在组件的构造函数中使用setOaque(false),以便一个组件的背景不会覆盖另一个组件)。

I've added both of them to the palette. 我已经将它们都添加到了调色板中。

And they both display on top of the palette because of the rules of the layout manager being used: 由于使用了布局管理器的规则,它们都显示在调色板的顶部:

So you have a couple of options: 因此,您有两种选择:

  1. Take advantage of Swings parent/child relationship. 利用Swings的父子关系。 That is add the square to the palette and the circle to the square. 也就是说,将正方形添加到调色板中,并将圆圈添加到正方形。 This means you will need to set a layout manager on the square so you can add the circle to it. 这意味着您将需要在正方形上设置布局管理器,以便可以向其添加圆形。 A BorderLayout might be easy to use. BorderLayout可能易于使用。

  2. Create a panel using the OverlayLayout . 使用OverlayLayout创建一个面板。 This layout manager allows you to add two components on top of one another in the same panel. 使用此布局管理器,您可以在同一面板中彼此叠加添加两个组件。 You would add the square to the panel and the circle to the panel (in that order since Swing paints the last component added to a panel first). 您将在面板上添加正方形,在面板上添加圆圈(由于Swing首先绘制了最后添加到面板中的组件,所以按此顺序)。

  3. A completely different (and probably easier) option is to have a single component and paint both the square and circle in the paintComponent() method. 完全不同(并且可能更容易)的选项是具有单个组件,并在paintComponent()方法中绘制正方形和圆形。

You should at least override isOpaque to return false on both Circle and Square thus non-painted pixel will be considered as "show-through". 您至少应该重写isOpaque以在Circle和Square上均返回false,因此未绘制的像素将被视为“透视”。

Next you also need to use a free layout in the container to be able to control exact location of your objects. 接下来,您还需要在容器中使用自由布局,以便能够控制对象的确切位置。

Note: don't use Canvas , it would be much better not to subclass any component to represent drawings, just implements some method (say draw ) that would take a graphics to draw with, and override paintComponent of your container to call that method on every drawing object: 注意:不要使用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);
        }
    }

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

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