我目前正在开发一款小游戏,但遇到一个问题:

我有三个类,第一个是JFrame:

public class Game
{

    public static void main(String[] args)
    {
        new Game().gui();
    }


    public void gui()
    {
        DrawPanel panel = new DrawPanel();
        JFrame frame = new JFrame("Test");
        //frame.add(panel);
        frame.add(new MainMenu());
        frame.setSize(800, 700);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
    }
}


现在,我还有另外两个类,一个是mainMenu,目前仅由一个JButton组成。
我决定将菜单设为自己的类,因为稍后,我想通过按Escape来调用菜单,但是问题是(出于测试原因)我想在按下“开始”时绘制一个矩形。我尝试了不同的方法,但没有任何反应。

public class MainMenu extends JPanel implements ActionListener
{

     GamePanel panel = new GamePanel();

     public MainMenu()
     {

         setLayout(new GridBagLayout());
         GridBagConstraints c = new GridBagConstraints();

         JButton b1 = new JButton("Start");
         c.fill = GridBagConstraints.HORIZONTAL;
         c.ipadx = 200;

         b1.addActionListener(new ActionListener()
         {
            @Override
            public void actionPerformed(ActionEvent e) {
                setVisible(false);
            }
         });
         add(b1, c);

     }

}


public class DrawPanel extends JPanel
{

     public void paint(Graphics g)
          {
            g.drawRect (10, 10, 200, 200);
          }

}

最佳答案

我在您的代码中发现了几个错误:


您没有将DrawPanel添加到任何内容,因为此行

frame.add(panel);


被评论,因此,这导致我们下一个问题:
您正在覆盖paint()方法而不是paintComponent(),并且也不要忘记调用

super.paintComponent();


在该方法的开始。没有它,您将阻止代码继续绘制其余组件。见Custom painting in Swing
仍然没有任何显示,因为您尚未为DrawPanel声明位置,因此它采用了JFrame的默认Layout Manager,即BorderLayout,未指定时的默认位置是CENTER ,并且在同一位置上添加new MainMenu()时,它将替换DrawPanel面板,因为同一位置只能存在一个组件。

而是尝试将DrawPanel放置到CENTER并将MainMenu放置到SOUTH。现在看起来应该像这样:

java - 按下JButton绘制矩形-LMLPHP
不要忘记通过编写main方法将程序放在Event Dispatch Thread (EDT)上,如下所示:

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

您正在ActionListener上实现MainMenu,但未实现它的方法,请删除它或实现actionPerformed方法,然后将代码移到b1动作侦听器中。但是,我强烈建议您也加入Should your class implement ActionListener or use an object of an anonymous ActionListener class
您正在玩MainMenuJPanel可见性,而应该尝试使用CardLayout或考虑使用JDialogs

例如,我将制作一个JDialog并将JButton放置在此处,这样它将打开其中绘制有JFrameRectangle


现在,完成以上输出并遵循所有建议(但#6)的代码是:

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Game {

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

    public void gui() {
        DrawPanel panel = new DrawPanel();
        JFrame frame = new JFrame("Test");
        frame.add(panel, BorderLayout.CENTER);
        frame.add(new MainMenu(), BorderLayout.SOUTH);
        frame.setSize(400, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
    }
}

class MainMenu extends JPanel  {

//  GamePanel panel = new GamePanel();

    public MainMenu() {

        setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();

        JButton b1 = new JButton("Start");
        c.fill = GridBagConstraints.HORIZONTAL;
        c.ipadx = 200;

        b1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setVisible(false);
            }
        });
        add(b1, c);
    }
}

class DrawPanel extends JPanel {

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawRect(10, 10, 200, 200);
    }
}




如@MadProgrammer的注释中所建议,您还可以覆盖getPreferredSize()DrawPanel方法,然后调用frame.pack()

您的DrawPanel类现在应如下所示:

class DrawPanel extends JPanel {

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawRect(10, 10, 200, 200);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(400, 300);
    }
}

08-18 06:22