按下JButton绘制矩形 [英] Draw Rectangle on pressing JButton

查看:42
本文介绍了按下JButton绘制矩形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

 公共类游戏{公共静态void main(String [] args){新的Game().gui();}公共无效gui(){DrawPanel面板= 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来调用菜单,但是问题是(出于测试原因)我想在按下开始"时绘制一个矩形.我尝试了不同的方法,但没有任何反应.

 公共类MainMenu扩展了JPanel实现ActionListener{GamePanel面板= new GamePanel();公共MainMenu(){setLayout(new GridBagLayout());GridBagConstraints c =新的GridBagConstraints();JButton b1 =新的JButton("Start");c.fill = GridBagConstraints.HORIZONTAL;c.ipadx = 200;b1.addActionListener(new ActionListener(){@Override公共无效actionPerformed(ActionEvent e){setVisible(false);}});加(b1,c);}}公共类DrawPanel扩展了JPanel{公共无效涂料(图形g){g.drawRect(10,10,200,200);}} 

解决方案

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

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

      frame.add(panel); 

    被评论,所以,这引出了下一个问题:

  2. 您正在覆盖 paint()方法,而不是

  3. 别忘了将程序放在通过如下编写您的 main 方法来创建事件调度线程(EDT):

      public static void main(String [] args){SwingUtilities.invokeLater(new Runnable(){@Override公共无效run(){//这里的构造函数}});} 

  4. 您正在 MainMenu 上实现 ActionListener ,但未实现它的方法,请删除它或实现 actionPerformed 方法并移动 b1 动作监听器中的代码.但是,我强烈建议您使用


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

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

      class DrawPanel扩展了JPanel {@Override受保护的void paintComponent(Graphics g){super.paintComponent(g);g.drawRect(10,10,200,200);}@Override公共维度getPreferredSize(){返回新的Dimension(400,300);}} 

    I am currently working on a little game but I just encountered a problem:

    I have three classes, the first one is the 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);
        }
    }
    

    Now I have two other classes, one is the mainMenu, currently consisting of just one JButton. I decided to make the menu its own class because later, I want to call the menu by pressing escape, but the problem is that (for testing reasons) I want to draw an rectangle when "start" is pressed. I tried different approaches but nothing happens.

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

    解决方案

    There are several errors I found in your code:

    1. You're not adding your DrawPanel to anything because this line

      frame.add(panel); 
      

      is commented, so, that leads us to the next problem:

    2. You're overriding paint() method instead of paintComponent() and also don't forget to call

      super.paintComponent();
      

      at the very beginning of the method. Without it, you're preventing your code to keep painting the rest of the components. See Custom painting in Swing

    3. That still doesn't makes anything appear because you haven't declared a location for your DrawPanel and thus it's taking JFrame's default Layout Manager which is BorderLayout and it's default location when not specified is CENTER, and as you're adding new MainMenu() to it on the same position it replaces the DrawPanel panel, since only one component can exist on the same position.

      Instead try and place the DrawPanel to the CENTER and the MainMenu to the SOUTH. It now should look like this:

    4. Don't forget to place your program on the Event Dispatch Thread (EDT) by writing your main method as follows:

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

    5. You're implementing ActionListener on MainMenu but not implementing it's methods, remove it or implement the actionPerformed method and move the code inside the b1 action listener to it. However I highly recommend you to take at Should your class implement ActionListener or use an object of an anonymous ActionListener class too

    6. You're playing with MainMenu's JPanel visibility, instead you should try using a CardLayout or consider using JDialogs.

      For example I would make a JDialog and place the JButton there, so it will open the JFrame with the Rectangle drawn in it.

    Now, the code that made the above output and follows all recommendations (but #6) is:

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


    As suggested in the comments by @MadProgrammer, you can also override the getPreferredSize() method of your DrawPanel and then call frame.pack():

    Your DrawPanel class should now look like this:

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

    这篇关于按下JButton绘制矩形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆