2017-01-25 135 views
0

我目前工作的一个小游戏,但我只是遇到了一个问题:绘制矩形上按下一个JButton

我有三类,第一种是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来调用菜单,但问题是(出于测试的原因)我想在按下“start”时绘制一个矩形。我尝试了不同的方法但没有任何反应

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

} 
+0

你有'//frame.add(面板);',所以没有任何绘制... –

+0

我知道。但它不管用。 – JonDoeMaths

+0

我认为你应该'@覆盖''paintComponent'方法。你可以看到[Swing中的自定义绘画](https://docs.oracle.com/javase/tutorial/uiswing/painting/)。你的按钮监听器是一个单独的问题,而不是现在绘制任何东西 –

回答

1

有几个错误,我在你的代码中发现:

  1. 你不增加你的DrawPanel到任何东西,因为这条线

    frame.add(panel); 
    

    的注释,所以,这导致我们到下一个问题:

  2. 你压倒一切paint()方法,而不是paintComponent(),也不要忘了打电话

    super.paintComponent(); 
    

    在方法的开始。没有它,你会阻止你的代码继续绘制其余的组件。见Custom painting in Swing

  3. 这仍然不能让任何东西出现,因为你还没有为你的DrawPanel声明的位置,因此它采取JFrame的默认Layout Manager这是BorderLayout,它不指定时默认位置是CENTER,并作为您将在其相同的位置上添加new MainMenu(),它会取代DrawPanel面板,因为只有一个组件可以位于同一位置。

    请尝试将DrawPanel设置为CENTER,将MainMenu设置为SOUTH。现在应该是这样的:

    enter image description here

  4. 不要忘记将你的程序在Event Dispatch Thread (EDT)通过编写main方法如下:

    public static void main(String[] args) { 
        SwingUtilities.invokeLater(new Runnable() { 
         @Override 
         public void run() { 
          //Your constructor here 
         } 
        }); 
    } 
    
  5. 你在实施ActionListenerMainMenu,但不执行它的方法,删除它或实现actionPerformed方法并将b1动作侦听器中的代码移动到它。不过我强烈建议你采取在Should your class implement ActionListener or use an object of an anonymous ActionListener class

  6. 你跟MainMenuJPanel知名度打,而不是你应该尝试使用CardLayout或考虑使用JDialogs

    例如,我会制作一个JDialog并将其放置在那里,因此它将打开JFrame并在其中绘制Rectangle

现在,作出了上述输出和代码遵循所有建议(但#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的意见建议,也可以覆盖您DrawPanel然后的getPreferredSize()方法调用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); 
    } 
} 
+1

我也建议覆盖'DrawPanel'的'getPreferredSize',它将提供额外的布局提示,这可以帮助,否则很好的答案;) – MadProgrammer

+0

@MadProgrammer谢谢你,我编辑了答案来添加你的建议,你可以检查它并告诉我这是你所指的? – Frakcool

+1

酷:) ....... – MadProgrammer