2015-04-02 101 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