Here是我的代码:我拿出了一些我觉得没必要的东西。我也可能已经取出了一些括号,但我只想展示我的内容。
当我运行程序时,背景图像描绘(它是资源中的PNG),只显示一个按钮(我的PLAY按钮),这是第一个按钮 - 它是自动选择的。
我实际上有四个按钮,但我的代码中只包含了播放和说明。除非我将鼠标放在它们上面,否则其他三个不显示。我知道这可能与paint方法有些奇怪,但我不知道如何修复它。
如果我选择一个不同的按钮并最小化窗口然后再次打开它,则所选按钮是唯一出现的按钮。我必须将鼠标移开才能显示其他按钮。
我已经将super.paint()
添加到paint方法中,我得到了所有按钮,但背景是灰色的。
我认为问题是super.paint()
描绘了我的所有按钮,而g.drawImage(bg, 0, 0, null)
只描绘了我的背景,如果没有绘制另一个,我就无法做到。
对不起,如果这是一团糟。我是Java的新手,我很难说出我想说的话。
public class MainMenu extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
//variables
public static Image bg;
public static void main(String[] args) {
MainMenu mainFrame = new MainMenu();
mainFrame.setSize(FRAME_WIDTH, FRAME_HEIGHT);
mainFrame.setResizable(false);
mainFrame.setLocationRelativeTo(null);
mainFrame.setTitle ("Zumby");
mainFrame.setLayout(null);
// Loads the background image and stores in bg object.
try {
bg = ImageIO.read(new File("zumby.png"));
} catch (IOException e) {
}
mainFrame.setVisible(true);
}
/**
* Overrides the paint method.
* MONDAY
*/
public void paint(Graphics g)
{
// Draws the img to the BackgroundPanel.
System.out.println("paint");
g.drawImage(bg, 0, 0, null);
}
/**
*/
public MainMenu() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 800, 500);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setOpaque(false);
setContentPane(contentPane);
contentPane.setLayout(null);
//create buttons
JButton btnPlay = new JButton("PLAY");
btnPlay.setBackground(Color.BLACK);
btnPlay.setForeground(Color.WHITE);
btnPlay.setFont(font);
btnPlay.setBorder(border);
btnPlay.setFocusPainted(false);
//if "Play" is clicked
btnPlay.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent click) {
setVisible(false);
new GamePlay(); //opens up GamePlay window
}
});
btnPlay.setBounds(600, 64, 141, 61);
contentPane.add(btnPlay);
JButton btnInstructions = new JButton("INSTRUCTIONS");
btnInstructions.setBounds(600, 160, 141, 61);
btnInstructions.setBackground(Color.BLACK);
btnInstructions.setFocusPainted(false);
// btnInstructions.setEnabled(true);
contentPane.add(btnInstructions);
repaint();
pack();
setVisible(true);
}
}
答案 0 :(得分:3)
Swing使用“分层”概念进行绘画......
paint
来电paintComponent
,paintBorder
和paintChildren
。通过覆盖paint
并且无法调用super.paint
,您已阻止组件绘制各个图层。
在Swing中,最好使用paintComponent
来提供自定义绘制,这允许您在可能添加到组件的任何其他组件下面绘制。
public class TestPaint01 {
public static void main(String[] args) {
new TestPaint01();
}
public TestPaint01() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Image backgroundImage;
public TestPane() {
try {
BufferedImage background = ImageIO.read(new File("/path/to/image.jpg"));
//backgroundImage = background.getScaledInstance(-1, background.getHeight() / 4, Image.SCALE_SMOOTH);
backgroundImage = background;
} catch (IOException ex) {
ex.printStackTrace();
}
setLayout(new GridBagLayout());
add(new JButton("Hello"));
}
@Override
public Dimension getPreferredSize() {
return backgroundImage == null ? super.getPreferredSize() : new Dimension(backgroundImage.getWidth(this), backgroundImage.getHeight(this));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = (getWidth() - backgroundImage.getWidth(this)) / 2;
int y = (getHeight() - backgroundImage.getHeight(this)) / 2;
g.drawImage(backgroundImage, x, y, this);
}
}
}
您可能会发现A Closer look at the Paint Mechanism和Painting in AWT and Swing信息丰富。
答案 1 :(得分:2)
我认为这是因为你重写了paint方法。最好覆盖重绘,然后调用super.repaint();像这样:
public void repaint(Graphics g)
{
super.repaint(g);
// Draws the img to the BackgroundPanel.
System.out.println("paint");
g.drawImage(bg, 0, 0, null);
}
然后组件也会重新绘制。
但是,如果您只想将图像显示为背景,请参阅here.
答案 2 :(得分:2)
您已覆盖paint()
,但请勿致电super.paint()
。因此,不执行JFrame的paint()
方法实现所完成的组件的正常绘制。
答案 3 :(得分:2)
由于您使用的是Swing和JFrame
绘制机制,用于覆盖通常与applet或AWT一起使用的paintComponent
而不是paint
。