2015-04-02 103 views
0

我正在嘗試爲棋盤遊戲風險製作一個主菜單。有一個自定義背景圖像,理想情況下,我希望按鈕出現在圖像上。但是,當我運行我的代碼時,只會出現名爲「新遊戲」的按鈕,如果將鼠標懸停在其上,則會出現其他按鈕。我已經嘗試了幾乎所有東西(這裏有類似的問題),但似乎無法解決問題。也許它與我的代碼有關?我感謝任何幫助/建議!JButtons被圖像覆蓋

package View; 


import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.GridLayout; 
import java.awt.Image; 
import java.awt.event.ActionListener; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 

import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JButton; 
import javax.swing.SpringLayout; 

/** 
* These classes set up the GUI of the Risk program. 
* The main menu, dialog for setting player count, dialog for name/color  settings for each 
* player, the Risk game board, and a menu used during a Risk game session are included. 

**/ 
public class Menu extends JFrame { 

private JPanel mainPanel; 


private JButton newGameButton; 
private JButton loadGameButton; 
private JButton quitButton; 
private JButton ruleButton; 

private String newGameButtonName = "newGameBtn"; 
private String loadGameButtonName = "loadGameBtn"; 
private String quitButtonName = "quitBtn"; 
private String ruleButtonName = "rulebtn"; 

//private SpringLayout mainLayout; 
private static BufferedImage img; 

/** 
* Constructs the main menu. 
**/ 
public Menu() 
{ 
    add(mainMenu()); 
    //setTitle("Risk: UConn Edition"); 
    setPreferredSize(new Dimension(640, 700)); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    setLocationRelativeTo(null); 
    setResizable(false); 



    toFront(); 
    pack(); 

    setVisible(true); 


} 

/** 
* creates the buttons for the jPanel 
* 
* @return 
*/ 
private JPanel mainMenu() 
{ 
    // Creates the panel 
    mainPanel = new JPanel(); 
    // Sets Layout 
    //mainLayout = new SpringLayout(); 
    mainPanel.setLayout(null); 

    // Creates buttons 
    newGameButton = new JButton("New Game"); 
    newGameButton.setBounds(20,300,150,50); 
    newGameButton.setOpaque(false); 
    newGameButton.setContentAreaFilled(false); 
    newGameButton.setForeground(Color.RED); 
    newGameButton.setBackground(Color.BLUE); 

    loadGameButton = new JButton("Load Game"); 
    loadGameButton.setBounds(20,400,150,50); 
    //loadGameButton.setOpaque(false); 
    //loadGameButton.setContentAreaFilled(false); 
    loadGameButton.setForeground(Color.RED); 

    quitButton = new JButton("Quit"); 
    quitButton.setBounds(490,400,150,50); 
    quitButton.setOpaque(false); 
    quitButton.setContentAreaFilled(false); 
    quitButton.setForeground(Color.RED); 

    ruleButton = new JButton("Rules"); 
    ruleButton.setBounds(490,300,150,50); 
    ruleButton.setOpaque(false); 
    ruleButton.setContentAreaFilled(false); 
    ruleButton.setForeground(Color.RED); 

    // Sets button commands 
    newGameButton.setActionCommand(newGameButtonName); 
    loadGameButton.setActionCommand(loadGameButtonName); 
    quitButton.setActionCommand(quitButtonName); 

    // Adds buttons to mainPanel 
    mainPanel.add(newGameButton); 
    mainPanel.add(loadGameButton); 
    mainPanel.add(quitButton); 
    mainPanel.add(ruleButton); 
// add(mainPanel); 

    return mainPanel; 
} 
private Image createImage(){ 
    try { 
     img = ImageIO.read(
       Menu.class.getResource("../resource/riskUconn.jpg")); 


    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    return img; 
    } 
/** 
* paint method 
*/ 
@Override 
public void paint (Graphics g) { 

    Image img = createImage(); 
    g.drawImage(img, 20,20,this); 
    super.paint(g); 


    } 


// Action listeners for Menu 
protected void riskViewActionListeners(ActionListener evt) 
{ 
    newGameButton.addActionListener(evt); 
    loadGameButton.addActionListener(evt); 
    quitButton.addActionListener(evt); 
} 



public static void main(String [] args){ 
    Menu m = new Menu(); 


} 

}

回答

2

繪畫成分並不總是通知家長或子組件。而不是覆蓋paint,請嘗試覆蓋paintComponent並在此處繪製背景,這就是paintComponent的真正目的,即繪製背景。

您應該避免重寫頂級容器的paint
大多數頂級容器都有一系列圖層,其中包括JRootPane,contentPane甚至glassPane,所有這些圖層都將繪製在一個框架的頂部。

取而代之,創建一個自定義組件,它從JPanel之類的東西延伸出來,並將其用作基礎組件。您可以覆蓋它的paintComponent並在其中繪製背景。然後將此組件添加到您的框架中,甚至可以將其添加到內容窗格中。

請記住,如果一個組件是不透明的,它會覆蓋所有的子組件

你也應該避免加載資源從任何油漆方法中(尤其是連續重裝他們),因爲這樣可以有一個服務於性能的影響你的程序。繪畫應儘可能快地繪畫。

對於exampleexample

+0

的OP使用'JFrame',雖然。 – johnchen902 2015-04-02 03:10:28

+0

如果我嘗試使用paintComponent,它給了我錯誤「Menu類型的paintComponent(Graphics)方法必須覆蓋或實現一個超類型方法」,所以如果我做了super.paintComponent(g)給了我錯誤「方法paintComponent(圖形)未定義爲JFrame類型「,因爲我使用JFrame作爲@ johnchen902聲明。 – user2938241 2015-04-02 03:13:18

+0

@ johnchen902更糟的是,檢查更新 – MadProgrammer 2015-04-02 03:13:20