Java 为什么我的paintComponent方法在JButton上绘制?我怎样才能使JPanel既有JButton又有图形?

Java 为什么我的paintComponent方法在JButton上绘制?我怎样才能使JPanel既有JButton又有图形?,java,swing,Java,Swing,我正在使用两个带有cardLayout的JPanel,它们都被添加到contentPane中。每个面板上都有一个JButton,可以切换到另一个面板,但在我的gridPanel上,它上面有图形,它们似乎覆盖了JButton,尽管当您单击它的位置时它仍然工作,但它是不可见的。如何获得一个既有图形又有JButton的JPanel?非常感谢你的帮助 主要类别: public class ProjectileGame extends JPanel { private static JFra

我正在使用两个带有cardLayout的JPanel,它们都被添加到contentPane中。每个面板上都有一个JButton,可以切换到另一个面板,但在我的gridPanel上,它上面有图形,它们似乎覆盖了JButton,尽管当您单击它的位置时它仍然工作,但它是不可见的。如何获得一个既有图形又有JButton的JPanel?非常感谢你的帮助

主要类别:

public class ProjectileGame extends JPanel
{   
    private static JFrame frame = new JFrame("MyGame");
    private static JPanel panelContent = new JPanel();
    MenuPanel menuPanel = new MenuPanel();
    GridPanel gridPanel = new GridPanel();
    Ball ball = new Ball();

    static CardLayout card = new CardLayout(); 

    public ProjectileGame()
    {   
        frame.setTitle("ProjectileGame");
        frame.add(panelContent);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.pack();
        frame.setSize(900, 700);

        panelContent.setLayout(card);
        panelContent.add(menuPanel, "1");
        panelContent.add(gridPanel, "2");

        card.show(panelContent, "1");   //First JPanel to be shown is that of the main menu.

        frame.setVisible(true);
    }     

    public static void menuButtonPressed()
    {
        card.show(panelContent, "2");
    }

    public static void gridButtonPressed()
    {
        card.show(panelContent, "1");
    }

    public static void main(String args[])
    {
        new ProjectileGame();
    }
}
gridPanel类:

public class GridPanel extends JPanel implements ActionListener
{
    private static final Graphics2D g2 = null;
    Ball ball = new Ball();
    JButton backToTheMenu = new JButton("To the Menu");
    Timer timer = new Timer(14, this);

    public GridPanel()
    {
        setOpaque(true);
        setBackground(Color.WHITE);
        setPreferredSize(new Dimension(900, 710));
        add(ball);
        add(backToTheMenu);

        backToTheMenu.addActionListener(new ActionListener()
        {
            public void actionPerformed(ActionEvent arg0)
            {       
                ProjectileGame.gridButtonPressed();
            }
        });
    } 

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);

        Graphics2D g2d1 = (Graphics2D)g;

        ball.paintComponent(g2d1);

        g.setColor(Color.RED);
        g.fillRect(0,  649,  30,  33);

        g.setColor(Color.BLUE);

        for (int i = 0; i < 35; i++)
        {
            g.setColor(Color.GREEN);
            g.drawLine(0, (20+(30*i)),  900,  (20+(30*i)));
            g.drawLine((30+(30*i)), 0, (30+(30*i)), 1000);
        }

        g.setColor(Color.RED);
        g.drawLine(0, 650, 900, 650);
        g.drawLine(30, 0, 30, 1000);

        g.setColor(Color.BLACK);
        g2d1.drawString("X Displacement (metres)", 400, 667);
        AffineTransform at = new AffineTransform();
        at.setToRotation(Math.PI / -1.97);
        g2d1.setTransform(at);
        g2d1.drawString("Y Displacement (metres)", -380, 8);    

    }                 

    public void actionPerformed(ActionEvent e)
    {
        ball.ballPhysics();
        repaint();
        timer.restart();
    }
}
公共类GridPanel扩展JPanel实现ActionListener
{
专用静态最终图形2d g2=null;
球=新球();
JButton backToTheMenu=新JButton(“到菜单”);
计时器=新的计时器(14,此);
公众谘询委员会(
{
set不透明(true);
挫折地面(颜色:白色);
设置首选尺寸(新尺寸(900710));
添加(球);
添加(返回菜单);
backToTheMenu.addActionListener(新建ActionListener())
{
已执行的公共无效操作(操作事件arg0)
{       
ProjectleName.gridButtonPressed();
}
});
} 
公共组件(图形g)
{
超级组件(g);
Graphics2D g2d1=(Graphics2D)g;
钢球.油漆组件(g2d1);
g、 setColor(Color.RED);
g、 fillRect(0649,30,33);
g、 setColor(Color.BLUE);
对于(int i=0;i<35;i++)
{
g、 setColor(Color.GREEN);
g、 抽绳(0,(20+(30*i)),900,(20+(30*i));
g、 抽绳((30+(30*i)),0,(30+(30*i)),1000);
}
g、 setColor(Color.RED);
g、 抽绳(0650900650);
g、 抽绳(30,0,30,1000);
g、 设置颜色(颜色为黑色);
g2d1.抽绳(“X位移(米)”,400667;
AffineTransform at=新的AffineTransform();
at.设置旋转(Math.PI/-1.97);
g2d1.setTransform(at);
g2d1.抽绳(“Y位移(米)”,-380,8);
}                 
已执行的公共无效操作(操作事件e)
{
ball.ball物理学();
重新油漆();
timer.restart();
}
}

不要将变换和旋转等添加到传递给
paintComponent()
方法的
Graphics
对象中。绘制时,此
图形
对象将传递给所有其他组件

相反,您应该创建一个临时的
图形
对象来进行绘制:

@Override
protected void paintComponent(Graphics g)
{
    super.paintComponent(g);

    Graphics2D g2d = (Graphics2D)g.create();

    //  do custom painting

    g2d.dispose();
}
现在,您需要能够将多个组件添加到面板中。请注意,您始终可以将另一个面板添加到面板中,以便可以有无限嵌套级别的面板。因此,您可以轻松地为您的CardLayout创建两张“卡片”,每张卡片上都添加了不同数量的组件

基本情况如下:

JButton button1 = new JButton("Back to Card2") 
JPanel gridPanel = new GridPanel();
JPanel card1 = new JPanel(new BorderLayout());
card1.add(button1, BorderLayout.PAGE_START);
card1.add(gridPanel, BorderLayout.CENTER);

JButton button2 = new JButton("Back to Card1");
JPanel card2 = new JPanel();
card2.add(button2);

JPanel cardPanel = new JPanel();
cardPanel.setLayout( new CardLayout(...) );
cardPanel.add(card1, ...);
cardPanel.add(card2, ...);

frame.add(cardPanel);

不要向传递给
paintComponent()
方法的
Graphics
对象添加变换和旋转等。绘制时,此
图形
对象将传递给所有其他组件

相反,您应该创建一个临时的
图形
对象来进行绘制:

@Override
protected void paintComponent(Graphics g)
{
    super.paintComponent(g);

    Graphics2D g2d = (Graphics2D)g.create();

    //  do custom painting

    g2d.dispose();
}
现在,您需要能够将多个组件添加到面板中。请注意,您始终可以将另一个面板添加到面板中,以便可以有无限嵌套级别的面板。因此,您可以轻松地为您的CardLayout创建两张“卡片”,每张卡片上都添加了不同数量的组件

基本情况如下:

JButton button1 = new JButton("Back to Card2") 
JPanel gridPanel = new GridPanel();
JPanel card1 = new JPanel(new BorderLayout());
card1.add(button1, BorderLayout.PAGE_START);
card1.add(gridPanel, BorderLayout.CENTER);

JButton button2 = new JButton("Back to Card1");
JPanel card2 = new JPanel();
card2.add(button2);

JPanel cardPanel = new JPanel();
cardPanel.setLayout( new CardLayout(...) );
cardPanel.add(card1, ...);
cardPanel.add(card2, ...);

frame.add(cardPanel);

什么是“球”?如果它是Swing组件,则不应直接调用其paintComponent方法。另外,请张贴一个有效的。球是我创建的对象。我现在如何发布一个最小的、完整的和可验证的示例?
我如何获得一个既有图形又有JButton的JPanel?
-通常你不会。我猜你想让一个“球”物体在屏幕上移动。因此,您通常会使用一个面板来制作球的动画。如果ball是一个Swing组件,那么您可以在面板上使用空布局,然后使用
setLocation()
方法移动球。因此,您将有一个父面板,可能使用了BorderLayout。您可以将JButton添加到BorderLayout.PAGE_START,将animation面板添加到BorderLayout.CENTER。关于
MCVE
,您的问题是关于带有图形和组件的面板。所以你只需要一个JFrame和一个panel。。然后在面板上添加一个按钮并重写paintComponent()方法,只需在面板上绘制一个字符串。现在您有了一个带有图形和按钮的面板。所以整个
MCVE
大约需要20行代码。关于MCVE,我明白了,谢谢。作为对camickr的回复,您知道我如何做到每个面板都有自己的JButton吗?如果我不想有一个带有永久按钮的主屏幕,而按钮下面的面板却在不断变化,那该怎么办?什么是“球”?如果它是Swing组件,则不应直接调用其paintComponent方法。另外,请张贴一个有效的。球是我创建的对象。我现在如何发布一个最小的、完整的和可验证的示例?
我如何获得一个既有图形又有JButton的JPanel?
-通常你不会。我猜你想让一个“球”物体在屏幕上移动。因此,您通常会使用一个面板来制作球的动画。如果ball是一个Swing组件,那么您可以在面板上使用空布局,然后使用
setLocation()
方法移动球。因此,您将有一个父面板,可能使用了BorderLayout。您可以将JButton添加到BorderLayout.PAGE_START,将animation面板添加到BorderLayout.CENTER。关于
MCVE
,您的问题是关于带有图形和组件的面板。所以你只需要一个JFrame和一个panel。。然后将一个按钮添加到面板并覆盖