2017-01-25 136 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