JButton 被图像覆盖
JButtons are painted over by an image
我正在尝试为棋盘游戏风险制作一个主菜单。有一个自定义背景图像,理想情况下我希望按钮显示在图像上。但是,当我 运行 我的代码时,只会出现名为 "New Game" 的按钮,如果将鼠标悬停在其他按钮上,它们就会出现。我已经尝试了几乎所有的方法(这里也有类似的问题)但似乎无法解决问题。也许它与我的代码有关?我很感激任何 help/suggestions!
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();
}
}
绘制组件并不总是通知父组件或子组件。不要覆盖 paint
,而是尝试覆盖 paintComponent
并在那里绘制背景,这就是 paintComponent
的真正含义,绘制背景。
您应该避免覆盖 paint
顶级容器。
大多数顶层容器都有一系列层,包括 JRootPane
、contentPane
甚至 glassPane
,所有这些层都将绘制在框架的顶部。
相反,创建一个自定义组件,它从 JPanel
之类的东西扩展而来,并将其用作您的基础组件。您可以覆盖它的 paintComponent
并在其中绘制背景。然后将此组件添加到您的框架中,甚至可能使其成为内容窗格。
记住,如果一个组件是不透明的,它将覆盖任何子组件
您还应该避免从任何绘制方法中加载资源(尤其是连续重新加载它们),因为这会对您的程序性能产生影响。画画要越快越好
对于example and
我正在尝试为棋盘游戏风险制作一个主菜单。有一个自定义背景图像,理想情况下我希望按钮显示在图像上。但是,当我 运行 我的代码时,只会出现名为 "New Game" 的按钮,如果将鼠标悬停在其他按钮上,它们就会出现。我已经尝试了几乎所有的方法(这里也有类似的问题)但似乎无法解决问题。也许它与我的代码有关?我很感激任何 help/suggestions!
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();
}
}
绘制组件并不总是通知父组件或子组件。不要覆盖 paint
,而是尝试覆盖 paintComponent
并在那里绘制背景,这就是 paintComponent
的真正含义,绘制背景。
您应该避免覆盖 paint
顶级容器。
大多数顶层容器都有一系列层,包括 JRootPane
、contentPane
甚至 glassPane
,所有这些层都将绘制在框架的顶部。
相反,创建一个自定义组件,它从 JPanel
之类的东西扩展而来,并将其用作您的基础组件。您可以覆盖它的 paintComponent
并在其中绘制背景。然后将此组件添加到您的框架中,甚至可能使其成为内容窗格。
记住,如果一个组件是不透明的,它将覆盖任何子组件
您还应该避免从任何绘制方法中加载资源(尤其是连续重新加载它们),因为这会对您的程序性能产生影响。画画要越快越好
对于example and