2

Ok, i know that this question has been asked before, but i just can't seem to get my application to work with the help from other peoples posts.

I am just trying to make a screen with a picture i made and then 3 buttons (just like a game menu). I have done the image and i am now trying to make the 3 buttons like this.

screen

my code at the moment is this:

public class Test {
   static int WIDTH = 700;
   static int HEIGHT = 600;

   public static void main(String[] args) {
      JLabel label = new JLabel();
      JFrame f = new JFrame();
      JPanel panel = new JPanel();
      JButton button = new JButton("hello again");
      button.addActionListener ((ActionListener) new Action1());

      label.setIcon(new ImageIcon("C:\\Users\\barney\\workspace\\game\\res\\background.jpg"));
      f.add(panel);
      f.add(label);
      f.setVisible(true);
      f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);
      f.setSize(WIDTH, HEIGHT);
      f.setResizable(false);
      f.setLocationRelativeTo(null);
      f.setTitle("2d platformer v1.1");
      f.setVisible(true);
   }
}

So how would i add the buttons like in the picture

also could you tell me if i have set my code out wrong as i am new to java.

thanks.

user2099816
  • 231
  • 1
  • 3
  • 7
  • @user2099816 tough your question is not much clear what I can get from it is that buttons are not visible. Bdw I must say you added code and everything properly normally new users don't do it. – amod Mar 11 '13 at 19:55
  • Soz if it wasnt clear what i wanted, but basically, how would i make 3 buttons one under each other (like in the picture) hope thats better. – user2099816 Mar 11 '13 at 20:10
  • See, [Background Panel](http://tips4java.wordpress.com/2008/10/12/background-panel/). – camickr Mar 11 '13 at 20:32

3 Answers3

5

I'm going to be smacked around for this...

label.setLayout(new GridBagLayout());
GridBagConstraints gbc = GridBagConstraints();
gbc.insets = new Insets(4, 0, 4, 0);
gbc.gridwidth = GridBagConstraints.REMAINDER;

label.add(button, gbc);
// add the other buttons

Updated

Personally, I'd create a custom JPanel, that would paint the background and then add buttons to it, using the GridBagLayout from above

Updated

The problem with this question is "it depends"

It depends on how you want to implement the actual buttons. Because you've left "blank" spaces, I assume you intend to render some buttons onto the image. I would personally, render a full image and then add some normal buttons onto, but it's your project not mine.

If you wanted to use something like JButton (or any other Component), you would need a custom layout manager to help you align the components with gaps you have left. Hence the reason I would simply do a nice background and use something like GridBagLayout instead...

I apologize, I may have gone slightly over board, but I was having fun.

enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RadialGradientPaint;
import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ButtonImage {

    public static void main(String[] args) {
        new ButtonImage();
    }

    public ButtonImage() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new MenuPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class MenuPane extends JPanel {

        public static final Rectangle NEW_GAME_BOUNDS = new Rectangle(221, 157, 262, 85);
        public static final Rectangle LOAD_GAME_BOUNDS = new Rectangle(221, 276, 262, 85);
        public static final Rectangle EXIT_GAME_BOUNDS = new Rectangle(221, 396, 262, 85);
        private BufferedImage img;
        private Rectangle selectedBounds;

        public MenuPane() {
            try {
                img = ImageIO.read(getClass().getResource("/vtr1a.jpg"));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
            MouseAdapter mouseHandler = new MouseAdapter() {
                @Override
                public void mouseMoved(MouseEvent e) {
                    if (getNewGameBounds().contains(e.getPoint())) {
                        System.out.println("in new");
                        selectedBounds = getNewGameBounds();
                    } else if (getLoadGameBounds().contains(e.getPoint())) {
                        System.out.println("in load");
                        selectedBounds = getLoadGameBounds();
                    } else if (getExitGameBounds().contains(e.getPoint())) {
                        System.out.println("in exit");
                        selectedBounds = getExitGameBounds();
                    } else {
                        selectedBounds = null;
                    }
                    repaint();
                }

                @Override
                public void mouseClicked(MouseEvent e) {
                    if (getNewGameBounds().contains(e.getPoint())) {
                        System.out.println("New Game");
                    } else if (getLoadGameBounds().contains(e.getPoint())) {
                        System.out.println("Load Game");
                    } else if (getExitGameBounds().contains(e.getPoint())) {
                        System.out.println("Exit Game");
                    }
                }
            };
            addMouseListener(mouseHandler);
            addMouseMotionListener(mouseHandler);
        }

        @Override
        public Dimension getPreferredSize() {
            return img == null ? super.getPreferredSize() : new Dimension(img.getWidth(), img.getHeight());
        }

        protected Point getImageOffset() {

            Point p = new Point();
            if (img != null) {
                p.x = (getWidth() - img.getWidth()) / 2;
                p.y = (getHeight() - img.getHeight()) / 2;
            }

            return p;

        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            if (img != null) {
                Graphics2D g2d = (Graphics2D) g.create();

                Point p = getImageOffset();

                g2d.drawImage(img, p.x, p.y, this);

                drawText(g2d, "New Game", getNewGameBounds());
                drawText(g2d, "Load Game", getLoadGameBounds());
                drawText(g2d, "Exit Game", getExitGameBounds());

                g2d.dispose();
            }
        }

        protected void drawText(Graphics2D g2d, String text, Rectangle bounds) {

            FontMetrics fm = g2d.getFontMetrics();

            g2d.setColor(Color.GRAY);
            if (selectedBounds != null) {
                if (bounds.contains(selectedBounds)) {
                    RadialGradientPaint rpg = new RadialGradientPaint(
                            new Point(bounds.x + (bounds.width / 2), bounds.y + (bounds.height / 2)),
                            Math.min(bounds.width, bounds.height), 
                            new float[]{0f, 1f},
                            new Color[]{new Color(252, 180, 42), new Color(97, 205, 181)}
                            );
                    g2d.setPaint(rpg);
                    RoundRectangle2D fill = new RoundRectangle2D.Float(bounds.x, bounds.y, bounds.width, bounds.height, 22, 22);
                    g2d.fill(fill);
                    g2d.setColor(Color.WHITE);
                }
            }

            g2d.drawString(
                    text,
                    bounds.x + ((bounds.width - fm.stringWidth(text)) / 2),
                    bounds.y + ((bounds.height - fm.getHeight()) / 2) + fm.getAscent());

        }

        protected Rectangle getNewGameBounds() {
            return getButtonBounds(NEW_GAME_BOUNDS);
        }

        protected Rectangle getLoadGameBounds() {
            return getButtonBounds(LOAD_GAME_BOUNDS);
        }

        protected Rectangle getExitGameBounds() {
            return getButtonBounds(EXIT_GAME_BOUNDS);
        }

        protected Rectangle getButtonBounds(Rectangle masterBounds) {
            Rectangle bounds = new Rectangle(masterBounds);
            Point p = getImageOffset();
            bounds.translate(p.x, p.y);
            return bounds;
        }
    }
}

You could, just as easily, use separate images for each button and instead of rendering the text/graphics, render a image at the required position.

Check out Custom Painting and 2D Graphics for some more info.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • somone can crucify you for using JLabel as Container, required to notify OP about implemented LayoutManagers only for JFrame and JPanel in API directly, – mKorbel Mar 11 '13 at 20:12
  • Yeah, it's a "little" hackey – MadProgrammer Mar 11 '13 at 20:13
  • see comment by [our inquisitor here](http://stackoverflow.com/questions/8575641/how-returns-xxxsize-from-jcomponents-added-to-the-jlabel) – mKorbel Mar 11 '13 at 20:16
4

I guess you didn't add Button to JFrame

f.add(button)
Eran
  • 387,369
  • 54
  • 702
  • 768
amod
  • 4,190
  • 10
  • 49
  • 75
  • Given the fact that the default layout manager is BorderLayout and that the OP has already added the background label to the frame, this is simply going to replace the label with the button (and fill the entire frame). Pretty sure that's not what the OP wants – MadProgrammer Mar 11 '13 at 19:56
  • I think OP wants a custom button, not a "default" swing button. – davidbuzatto Mar 11 '13 at 19:57
  • Yes, but simply "adding" a component to the frame is going to override what ever is at the centre position, removing there background – MadProgrammer Mar 11 '13 at 20:00
  • @MadProgrammer the question is not much clear. You can assume it from GUI. But the fact remains the same. He has to add the button somewhere and that's what he missed. BDW a nice observation on label stuff. – amod Mar 11 '13 at 20:00
  • And I don't actually see where the ask for anything other the "buttons" – MadProgrammer Mar 11 '13 at 20:00
  • 1
    But my point is, you've not suggested a means by which they can use there background ADD add buttons (of any kind) to it – MadProgrammer Mar 11 '13 at 20:02
  • @MadProgrammer Yes I do agree. I assume that he can adjust he can do that. I just wanted to make him note that he has to add button somewhere. :) – amod Mar 11 '13 at 20:04
  • So you agree you've not answered the question ;) – MadProgrammer Mar 11 '13 at 20:12
  • @MadProgrammer No its the answer. I just not done the spoon feeding. – amod Mar 11 '13 at 20:32
  • Heee, I'll be the first to admit that the meaning of communication is the interruption of the receiver. I've interrupted the question as "how do I add buttons to my image", not "how do I add buttons to the frame" - it's a nit pick to be sure. The OP has already demonstrated that they know how to add components to a container, but not a knowledge of layout managers, IMHO (and that is all it is) is you answer will raise more questions then it answers - I'm a pain I know ;) – MadProgrammer Mar 11 '13 at 22:37
1

As you want different buttons than Swing button, to make the things simpler, you can draw your buttons in a JPanel (using the paintComponent method and Java 2D). Each JPanel will be a button. Them, you will use some mouse events to detect clicks, etc. Another approach is do the same thing that you are doing with your background (several JLabels with images) and register mouse events in each label. You can also create your own Look And Feel for your buttons, but this is not so simple. Of course, you will need to change your layout manager to fit your buttons.

davidbuzatto
  • 9,207
  • 1
  • 43
  • 50
  • Using labels and mouse listeners is harder then doing custom painting? Oooookkkaayyy....while a reasonable comment, I fail to see how this helps answer the OP's question (it is early) – MadProgrammer Mar 11 '13 at 19:57
  • @MadProgrammer I said that dealing with custom LAF if not so simple. Custom painting is ok. – davidbuzatto Mar 11 '13 at 20:06