Here is my code: I took out some stuff that I felt wasn't necessary. I might've took out some brackets too, but I'm just trying to show the content I have.
What happens is, when I run the program, the background image paints (it's a PNG in resources), and only ONE button appears (my PLAY button), which is the first button - it's auto-selected.
I actually have four buttons but I've only included PLAY and INSTRUCTIONS in my code. The other three don't show up unless I mouse over them. I know it's probably something weird with the paint method, but I don't know how to fix it.
If I select a different button and minimize the window then open it again, that selected button is the only one that appears. I have to mouse over to get the other buttons to appear.
I've added super.paint()
to the paint method too and I get all my buttons but the background is grey. I think the problem is super.paint()
paints all my buttons, and g.drawImage(bg, 0, 0, null)
only paints my background and I can't do one without painting over the other.
Sorry if this was a mess. I'm new at Java and I have trouble articulating what I'm trying to say.
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);
}
}
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.
I think it's because you're overriding the paint method. It's better to override repaint, then call super.repaint(); Like this:
public void repaint(Graphics g)
{
super.repaint(g);
// Draws the img to the BackgroundPanel.
System.out.println("paint");
g.drawImage(bg, 0, 0, null);
}
Then the components get redrawn as well.
But if all you want to do is show an image as the background see here.
You're overriding paint()
but don't call super.paint()
. So the normal painting of the components done by the JFrame's paint()
method implementation is not executed.
由于您使用的是Swing和JFrame
因此用于覆盖paintComponent
的绘制机制不会paint
通常与applet或AWT一起使用的paint
。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.