Mostafa Rashed
Mostafa Rashed

Reputation: 48

JButton only show up on mouseover

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

Answers (2)

MadProgrammer
MadProgrammer

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.

enter image description here

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

Logan
Logan

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.

How to Make Frames

//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

Related Questions