Swing 将jpanel放在另一个类的jpanel之上

Swing 将jpanel放在另一个类的jpanel之上,swing,jframe,jpanel,paint,Swing,Jframe,Jpanel,Paint,我试图使一个类中的Jpanel出现在另一个类中的Jpanel之上。我可以绕道而行,但我知道从长远来看我会后悔的。我的frame类包含带有按钮的主Jpanel,我想暂时将另一个带有按钮的Jpanel放在它上面。我试图简化我的代码。注意ShopButton方法和第一段代码下面的Shop类。这正是我想要关注的。我试图将Shop JPanel放在现有的“框架”(我称之为我的类)JPanel上 \uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

我试图使一个类中的Jpanel出现在另一个类中的Jpanel之上。我可以绕道而行,但我知道从长远来看我会后悔的。我的frame类包含带有按钮的主Jpanel,我想暂时将另一个带有按钮的Jpanel放在它上面。我试图简化我的代码。注意ShopButton方法和第一段代码下面的Shop类。这正是我想要关注的。我试图将Shop JPanel放在现有的“框架”(我称之为我的类)JPanel上

\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

public class Shop extends JPanel {
    public JButton CloseButton;
    public Shop(){
        CloseButton();
        setVisible(true);
        setLayout(null);
    }
    public void paint(Graphics g){
        System.out.println("shop is working");
        g.setColor(Color.WHITE);
        g.fillRect(100, 50, 350, 275);
        g.drawRect(100, 50, 350, 275);
    } 
    public void CloseButton(){
        //for 
        CloseButton= new JButton("Exit Shop");
        CloseButton.addActionListener( new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent Event) {
                System.out.println("am i alive?");
            }
        });
        CloseButton.setBounds(100, 100, 90, 30);
        add(CloseButton);
    }
}

覆盖
paintComponent()
而不是
paint()
,然后您可以正常放置组件并让swing负责绘制它们:

import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Sample {
    private static class ImagePanel extends JPanel {
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            // Some background drawing
            g.setColor(Color.BLUE);
            g.fillOval(0, 0, getWidth(), getHeight());
        }
    }

    Sample() {
        JFrame frame = new JFrame("Button atop drawing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);
        JPanel panel = new ImagePanel();
        panel.setLayout(new FlowLayout(FlowLayout.CENTER, 50, 50));

        JButton button = new JButton("Sample button");
        panel.add(button);

        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Sample();
            }
        });
    }
}
。。。结果:


哇,我真不敢相信这会奏效。。。非常感谢你!我需要去检查油漆和油漆组件之间的区别,实际上现在它只添加了按钮,没有绘制我想要的填充矩形。我会设法找出原因。Thanks@CameronRoberson
paint()
是顶级绘制方法,负责调用
paintComponent()
paintChildren()
paintBorder()
。所以通常您只想覆盖
paintComponent()
。如果您的子组件下面没有绘制某些内容,我的猜测是,要么它们不遵守不透明约定,要么在背景上绘制。对于按钮,您可以通过设置
button.setContentAreaFilled(false),快速检查它是否正在绘制;按钮。设置不透明(假)
并查看背景是否显示出来。
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Sample {
    private static class ImagePanel extends JPanel {
        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            // Some background drawing
            g.setColor(Color.BLUE);
            g.fillOval(0, 0, getWidth(), getHeight());
        }
    }

    Sample() {
        JFrame frame = new JFrame("Button atop drawing");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationByPlatform(true);
        JPanel panel = new ImagePanel();
        panel.setLayout(new FlowLayout(FlowLayout.CENTER, 50, 50));

        JButton button = new JButton("Sample button");
        panel.add(button);

        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Sample();
            }
        });
    }
}