Reputation: 48
I'm working on a "Tron" game, and for my menu I used a paint method to paint a background to the menu. Everything is good except that the 3 JButtons are "hiding" behind the background until I put my mouse over it then it appears. If there is a way to keep the buttons visible, I would appreciate it!
My code:
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Menu extends JFrame {
private static final long serialVersionUID = 1L;
String name;
Image bk;
public Menu() {
super("TRON");
// Set the size of window
setSize(800, 800);
// Set the default operation for the window
setDefaultCloseOperation(EXIT_ON_CLOSE);
// Set a background
ImageIcon ibk = new ImageIcon("background.jpg");
bk = ibk.getImage();
// Set a new panel
JPanel p = new JPanel(new GridBagLayout());
// Make buttons!
JButton b = new JButton("Play!");
JButton b2 = new JButton("High Scores");
JButton b3 = new JButton("Exit");
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new GameFrame();
}
});
b2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
new hsview();
}
});
b3.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
// Set the GridBagConstraints to organize the layout
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets (15, 15, 15, 15);
// Use gbc to space out each button
gbc.gridx = (0);
gbc.gridy = (0);
// Add them to the panel then to JFrame
p.add(b, gbc);
gbc.gridx = (0);
gbc.gridy = (1);
p.add(b2, gbc);
gbc.gridx = (0);
gbc.gridy = (2);
p.add(b3, gbc);
// Add to the frame at the bottom
add(p, BorderLayout.SOUTH);
}
// Background stuff
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(bk, 0, 0, null);
}
}
Upvotes: 0
Views: 3761
Reputation: 347334
Swing uses a "layering" concept for it's painting...
paint
calls paintComponent
, paintBorder
and paintChildren
. By overriding paint
and failing to call super.paint
, you've prevented the component from painting it's various layers.
In Swing, it is preferred to use paintComponent
to provide custom painting, which allows you to paint underneath any other components that might be added to the component.
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);
}
}
}
You might find A Closer look at the Paint Mechanism and Painting in AWT and Swing informative.
Upvotes: 2
Reputation: 2374
I think you need to call the pack() method and this display for your frame. I think the pack() method sets your components up to display.
Here are the steps listed for the JFrame tutorial.
//1. Create the frame.
JFrame frame = new JFrame("FrameDemo");
//2. Optional: What happens when the frame closes?
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//3. Create components and put them in the frame.
//...create emptyLabel...
frame.getContentPane().add(emptyLabel, BorderLayout.CENTER);
//4. Size the frame.
frame.pack();
//5. Show it.
frame.setVisible(true);
Upvotes: 0