0

I have encountered a problem whilst working the JFrame's, and JButtons. I am trying to center my JButton, however when I do so, it covers almost the entire screen. Any idea's on what's causing this?

Here is a picture on how it looks :

enter image description here

And here is my code :

package character;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.io.IOException;

/**
 * Created by Niknea on 6/28/14.
 */
public class characterSelector{


    JFrame  cselectorButtons, clogo;

    JLabel logo, characterName, label;

    JButton male, female;


    public characterSelector(){

        this.createCharacterSelector();

    }


    public void createCharacterSelector() {

        try {
            label = new JLabel(new ImageIcon(ImageIO.read(getClass()
                    .getResource("/resources/Grass_Background.jpg"))));
            cselectorButtons = new JFrame("SupremeSoccer");
            logo = new JLabel(new ImageIcon(ImageIO.read(this.getClass().getResource("/resources/Character_Selector_Image.png"))));
            characterName = new JLabel("<Character Name>");
            characterName.setFont(new Font(characterName.getFont().getName(),
                    Font.HANGING_BASELINE, 50));

            /*
            Buttons
             */

            male = new JButton("Male");


            ////******************////
            //// END OF BUTTONS  ////
            ////****************////
            cselectorButtons.add(logo);
            cselectorButtons.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            cselectorButtons.setContentPane(label);
            cselectorButtons.setLayout(new BorderLayout());
            cselectorButtons.add(logo, BorderLayout.NORTH);
         cselectorButtons.add(male, BorderLayout.CENTER);
            cselectorButtons.pack();
            cselectorButtons.setLocationRelativeTo(null);
            cselectorButtons.setVisible(true);
        } catch (IOException exp) {
            exp.printStackTrace();
        }
    }
}

Thanks again.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Niknea
  • 39
  • 9

2 Answers2

3

Any idea's on what's causing this?

This is the default behaviour of BorderLayout. The component at the CENTER position will occupy the maximum amount of space the is available from the parent component, when the other (NORTH, SOUTH, EAST, WEST) positions have been taken into account

Depending on what you are trying to achieve you might consider creating another JPanel (set it's opaque state to false so it's transparent) and use something like GridLayout or GridBagLayout instead.

Take a look at A Visual Guide to Layout Managers for some more ideas

Updated

So based on your linked code, I changed

part2 = new JPanel();

to

part2 = new JPanel(new java.awt.GridBagLayout());

And got...

Get it on

Updated with additional example

Start by breaking down your requirements into individual containers and focus on the layout requirements for each individual, then build them all back into a single container.

This will make changing them later much easier and also make controlling them much easier...

Grass

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ExampleLayout {

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

    public ExampleLayout() {
        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 TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private HeaderPane header;
        private ScorePane score;
        private CharacterSelectionPane characterSelection;

        public TestPane() {

            setLayout(new BorderLayout());

            JLabel background = new JLabel();

            try {
                BufferedImage img = ImageIO.read(getClass().getResource("/Grass.jpg"));
                background.setIcon(new ImageIcon(img));
            } catch (IOException ex) {
                ex.printStackTrace();
            }

            add(background);

            background.setLayout(new GridBagLayout());

            header = new HeaderPane();
            score = new ScorePane();
            characterSelection = new CharacterSelectionPane();

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            gbc.weightx = 1;
            gbc.fill = GridBagConstraints.BOTH;

            background.add(header, gbc);
            background.add(score, gbc);
            gbc.weighty = 1;
            background.add(characterSelection, gbc);
        }
    }

    public class HeaderPane extends JPanel {

        public HeaderPane() {
            setLayout(new BorderLayout());
            JLabel label = new JLabel("Character Selection");
            label.setForeground(Color.WHITE);
            label.setFont(label.getFont().deriveFont(Font.BOLD, 48f));
            label.setHorizontalAlignment(JLabel.CENTER);
            add(label);
            setOpaque(false);
        }

    }

    public class ScorePane extends JPanel {

        public ScorePane() {
            JLabel label = new JLabel("[-][-[]-][-]");
            label.setForeground(Color.YELLOW);
            add(label);
            setOpaque(false);
        }

    }

    public class CharacterSelectionPane extends JPanel {

        private JButton btMale;
        private JButton btFemale;
        private JTextField tfName;
        private JButton btContinue;

        public CharacterSelectionPane() {
            setOpaque(false);
            setLayout(new GridBagLayout());

            btMale = new JButton("Male");
            btFemale = new JButton("Female");
            btContinue = new JButton("Continue");
            tfName = new JTextField(10);

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.insets = new Insets(4, 4, 4, 4);
            gbc.fill = GridBagConstraints.HORIZONTAL;

            add(btMale, gbc);
            gbc.gridx++;
            add(btFemale, gbc);
            gbc.gridx = 0;
            gbc.gridy++;
            add(new JLabel("Name:"), gbc);
            gbc.gridx++;
            add(tfName, gbc);
            gbc.gridx = 0;
            gbc.gridy++;
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            add(btContinue, gbc);
        }

    }

}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I've had a bit of issue's in the past involving centering an object using JPanel. Would I be required to do that? Or just center the JPanel? Also, should I be creating a new frame like a main one, or is the first one ok to be the "main" one? Thanks again. – Niknea Jun 30 '14 at 00:38
  • Use the `JPanel` instead of the button, this will be added to the `CENTER` position of the `JLabel`, but, so long as it's transparent, you won't even know it's there. Something like `GridBagLayout` will then allow you to add components which will be positioned around the center of the container (the panel). If you need to switch between views, you might consider using a [`CardLayout`](http://docs.oracle.com/javase/tutorial/uiswing/layout/card.html) as well – MadProgrammer Jun 30 '14 at 00:43
  • Do you by any chance know a good guide I can check out about all of this? Thanks. – Niknea Jun 30 '14 at 01:02
  • [A Visual Guide to Layout Managers](http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html) – MadProgrammer Jun 30 '14 at 01:08
  • @Niknea you already got the guide in [this answer](http://stackoverflow.com/a/24472525/2587435). Are you actually going to look at it this time? – Paul Samsotha Jun 30 '14 at 01:50
  • I have indeed looked into a good chunk of the docs, and will finish it after I finish typing this question. I've managed to make it work, however the button isn't fully "centered" . Here is how it looks, http://imgur.com/Lj6JsPx, and here is my code http://pastie.org/9339159. I'll finish up the docs to see if it explains a fix, if not maybe you can solve it? Once again I apologies for my lack of knowledge involving creating GUI's. Thanks again. – Niknea Jun 30 '14 at 04:46
  • It looks like you're still using the default layout manager for `JPanel` instead of using something like `GridBagLayout` – MadProgrammer Jun 30 '14 at 04:48
  • Alright, I'm really really really close to figuring this out. I've centered it. However now it only shows one button. I remembered when pesskillet said when two buttons are located in the same place it will be overrided. So I changed locations. Yet only the male button is in the center, the female button is no where to exists. Here is my code : http://pastie.org/9339228. Thanks again. – Niknea Jun 30 '14 at 05:12
  • First of all `GridBagConstraints.WEST` isn't used for filling, but for anchoring. Second of all, try using `g.gridx++;` instead then add your next button – MadProgrammer Jun 30 '14 at 05:14
  • Thank you very much it finally works! I have one last question, how would I go along putting another component under the buttons? Is there some sort of method like \n? Thanks again, and once again my apologies for my lack of knowledge. – Niknea Jun 30 '14 at 05:44
  • Either place it in the `SOUTH` position of the `BorderLayout` or simply added to the next grid position under the buttons – MadProgrammer Jun 30 '14 at 05:45
  • How would I go along adding it to the next grid position? As assuming I can't do the same as I did before with the g.gridx++;, and if I set the position to SOUTH wouldn't that put the component at the very bottom? – Niknea Jun 30 '14 at 05:49
  • `gridy` would be the property you're looking for, you'd need to reset the `gridx` position and possible supply a `gridwidth` value as well. And yes, the `SOUTH` position would be place at the very bottom, like the header is at the top – MadProgrammer Jun 30 '14 at 05:52
  • Hey mad, my apolgies for bugging you again, but I encoutred a problem with the positioning. When I edit the y, the text wont go down. I would like the yellow text at the top to go down. Here is a picture: http://prntscr.com/3xwez4, and here is the code: http://pastie.org/9339414. Once again extremely sorry for bugging you again, and thanks again. – Niknea Jun 30 '14 at 07:33
  • You can't add multiple components to the same position within `BorderLayout` – MadProgrammer Jun 30 '14 at 07:36
  • However I've created another JPanel for that JLabel. Am I only allowed to create one BorderLayout per gui? – Niknea Jun 30 '14 at 07:40
  • No, you can have as many `BorderLayout`s as like, but only one per container...but you added `part3` to the `NORTH` position of the same container as the log; `cselectorButtons.add(part3, BorderLayout.NORTH);` – MadProgrammer Jun 30 '14 at 07:44
  • Ahh I see what your saying, the reason I set it north was because when it was in the panel named part2 that was located in the center, it would only go up to a certain extent. So where would you recommended me to position the image before I push it to the middle? – Niknea Jun 30 '14 at 08:07
  • You could try using `GridBagLayout` as I did, or start with an outer panel with `BorderLayout`, to which you add the logo, then an inner pane with a `BorderLayout` onto which you add everything else and put this at the `CENTER` of the outer panel – MadProgrammer Jun 30 '14 at 09:17
  • I've changed it up a bit, created a main panel, and parts to it. However it still doesn't work. The characterName doesn't appear at all. Here is my code : http://pastie.org/9341203. Thanks again. – Niknea Jun 30 '14 at 18:28
2

Use a BoxLayout or (easier) GridBagLayout for the bottom area, as seen in this answer.

Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433