0

Sorry if duplicate, couldn't find a proper answer

I'm trying to center a JPanel which is in itself added into another JPanel

public class bgframe extends JPanel
{
    // The Image to store the background image in.
    Image img;
    public bgframe()
    {
        // Loads the background image and stores in img object.
        img = Toolkit.getDefaultToolkit().getImage("img/fondAccueil.png");
    }

    protected void paintComponent(Graphics g)
    {
        // Draws the img to the BackgroundPanel_accueil.
        g.drawImage(img, 0, 0, this);
    }
}

and

public class Frame_Accueil extends JFrame
{
public Frame_Accueil()
{
        this.setSize(1000,500);

        bgframe fond = new bgframe();
        JPanel boutons = new JPanel(new GridBagLayout());
    
        JButton btn1 = new JButton("btn1");
        JButton btn2 = new JButton("btn1");

        btn1.setPreferredSize(new Dimension(300, 50));
        btn2.setPreferredSize(new Dimension(300, 50));

        btn.add(btn1);
        btn.add(btn2);

        this.add(fond,BorderLayout.CENTER);
        fond.add(boutons,BorderLayout.CENTER);
    
        this.setVisible(true);
    
    }
}

Problem is that I have the background but the buttons are not in the center. How can I fix this ??

Thanks

  • 1
    To make the buttons larger I would recommend you can use `button1.setMargin( new Insets(10, 100, 10, 100)`. (Note, you can create a single instance of the Inset and share it with all buttons. This will allow the button to calculate its own preferred size and the size will adjust automatically based on the text and Font of the button. In general avoid using random hard coded values. – camickr Apr 05 '21 at 18:14

2 Answers2

2

Before all, you have multiple issues in your code:

  1. bgframe doesn't extend from JFrame so a better name would be BgPanel or BgPane maybe as it extends JPanel.

  2. Both bgframe and Frame_Accueil don't follow Java naming conventions, as one of them isn't uppercased and the other one is using snake case rather than camel case.

    • FirstWordUpperCasedClass
    • firstWordLowerCasedVariable
    • firstWordLowerCasedMethodName()
    • ALL_WORDS_UPPER_CASED_CONSTANT
  3. You forgot to call super.paintComponent(g) as the first line of paintComponent inside bgframe, this could mess up your program as Swing might not know what or how to paint the components of bgframe at any random point in your execution.

  4. Don't call setSize(...), if you do so, your JFrame's decorations (borders and title bar) are taking into consideration for this, so your actual content screen's size is smaller than you think, it's better to override getPreferredSize() and then call pack() on your JFrame.

  5. There's no need to extend JFrame as you're not changing its behavior, would be better to create an instance of the JFrame inside your program instead, see: Extends JFrame vs. creating it inside the program for a more in-depth explanation of this.

  6. Idk what btn is, so I thought you were referring to boutons

  7. Images and other assets will become embedded-resources once you package your app as a jar file, so it's wise to start treating them as such, see this answer for a running example of that.

  8. Instead of setting the preferred size of your JButtons you could create a separate class that extends JButton, and override the getPreferredSize of it, just like in the JPanel as suggested in point 4 above.

  9. By default a JPanel has a FlowLayout and thus it will ignore your calls of BorderLayout.CENTER, you can combine different layout managers to get the desired output, for example if you change fond layout to BoxLayout it will be centered vertically as I think that's what your problem is.

  10. And last but not least, place your program on the EDT (and when posting code to Stack Overflow don't forget the main method), more in this answer

So, in the end your program (without the bgframe class that I removed as the background isn't needed for this particular problem) should look like this:

import java.awt.Dimension;
import java.awt.GridBagLayout;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class FrameAccueil {
    private JFrame frame;
    
    public FrameAccueil() {
        frame = new JFrame(getClass().getSimpleName());
        
        JPanel fond = new JPanel() { // Move this code inside your bgfond class
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(1000, 500);
            }
        };
        fond.setLayout(new BoxLayout(fond, BoxLayout.PAGE_AXIS));
        
        JPanel boutons = new JPanel(new GridBagLayout());

        JButton btn1 = new JButton("btn1");
        JButton btn2 = new JButton("btn1");

        JButton btn1 = new JButton("btn1") { // If you follow point 8, these code shall be moved there and these JButtons should be objects of that class.
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(300, 50);
            }
        };
        JButton btn2 = new JButton("btn1") {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(300, 50);
            }
        };

        boutons.add(btn1);
        boutons.add(btn2);

        fond.add(boutons); //Try to first add the inner objects and then the outer ones, so go inside-out as to keep them ordered in a more logical way
        frame.add(fond);

        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }
    
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new FrameAccueil()); //Place your program on the EDT
    }
}

And it should look like this (made the screen smaller)

enter image description here

Frakcool
  • 10,915
  • 9
  • 50
  • 89
  • 1
    (1+) for all 10 points. I would also suggest the OP read the [Swing tutorial](https://docs.oracle.com/javase/tutorial/uiswing/TOC.html). All the examples found there will follow the above suggestions. – camickr Apr 05 '21 at 18:16
  • Thanks it helps a lot ! However, when applying the layout of Font, it removes the background image. Do you know how I can fix it ? Thanks – Lucas Grandjean Apr 05 '21 at 18:48
  • 1
    Just set the `boutons` pane opacity to false. `boutons.setOpaque(false)` @LucasGrandjean – Frakcool Apr 05 '21 at 19:14
0

You could try to set the buttons in the center of your grid. You could also use "GridBagConstraints.CENTER" and "GridBagConstraints.HORIZONTAL"