简体   繁体   中英

A class that extends JPanel, that i want to add with CENTER proprity in my JFrame that is a BorderLayout

I have a class named panneau :

public class Panneau extends JPanel { 

    public void paintComponent(Graphics g){
        try {
            Image img = ImageIO.read(new File("src/disantiammo/image/image.png"));
            g.drawImage(img, 0, 0, this);
        } catch (IOException e) {
            e.printStackTrace();
        }   
    }
}
//for now it is not doing anything but it will...

In the JFrame I have a few JPanels with others elements.

The JFrame's layout is a BorderLayout

The probleme is this pan has to be "java.awt.BorderLayout.CENTER", I can only place it this way :

  this.setContentPane(new Panneau());

How do I do to place it in "CENTER"?

I tried things like

this.getContentPane().add(new Panneau(), java.awt.BorderLayout.CENTER);

Nothing seems to work the only thing I can do is to place "panneau" instead of what's inside my JFrame. EDIT :

This may sound as a really simple thing, but I don't understand why I can't do that, that I'm stuck trying doing it.

I have jDialog, it is in BorderLayout, in "south", "north" and "center" I have jPanel with elements (with nothing in the "center"'s jPanel. "center" jPanel is called Map.

I'm thing things like : in the main

  Graphics t = Map.getGraphics();
    paintComponent(t);

not in the main.

public void paintComponent(Graphics g){
 super.paintComponents(g);
 g.drawLine(0, 0, 50, 150);
}

I cannot draw anything.

I find that the easiest way to fully center a component is to give the container a GridBagLayout, and then add the single component to that container, but without using any constraints.

Side issue: your code reads in an image in a painting method -- never do this. Instead read the image in once and store it in a variable. Then display it within the painting method. Also be sure to call the super's painting method in your override.

eg,

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class CenteredImage extends JPanel {
    private static final String IMG_PATH = "https://upload.wikimedia.org/wikipedia/commons/"
            + "thumb/f/f8/Portrait_d%27une_Femme_%C3%A0_sa_Toilette%2C_by_Titian%2C_"
            + "from_C2RMF_retouched.jpg/300px-Portrait_d%27une_Femme_%C3%A0_sa_"
            + "Toilette%2C_by_Titian%2C_from_C2RMF_retouched.jpg";
    private BufferedImage img;

    public CenteredImage(BufferedImage img) {
        this.img = img;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (img != null) {
            g.drawImage(img, 0, 0, this);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension prefSize = super.getPreferredSize();
        if (isPreferredSizeSet() || img == null) {
            return super.getPreferredSize();
        }
        return new Dimension(img.getWidth(), img.getHeight());
    }


    private static void createAndShowGui() {
        BufferedImage img = null;
        try {
            URL imgUrl = new URL(IMG_PATH);
            img = ImageIO.read(imgUrl);
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(-1);
        }

        CenteredImage mainPanel = new CenteredImage(img);

        JFrame frame = new JFrame("CenteredImage");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(800, 650));
        frame.getContentPane().setLayout(new GridBagLayout());
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

Edit: use of a wrapper JPanel as noted in comments:

You state in comments:

Thank you for you anwser but I meant something else : There is : a JFrame/JDialog in borderLayout, I want to put "panneau" inside of it in the center position of it, maybe I don't know how to say it ... there are elements in "south", "north" ect ...

then wrap the image producing JPanel in another JPanel that uses GridBagLayout and add the wrapper JPanel to the JFrame BorderLayout.CENTER

private static void createAndShowGui() {
    BufferedImage img = null;
    try {
        URL imgUrl = new URL(IMG_PATH);
        img = ImageIO.read(imgUrl);
    } catch (IOException e) {
        e.printStackTrace();
        System.exit(-1);
    }

    CenteredImage centeredImagePanel = new CenteredImage(img);

    JPanel wrapperPanel = new JPanel(new GridBagLayout());
    wrapperPanel.add(centeredImagePanel);

    JFrame frame = new JFrame("CenteredImage");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setPreferredSize(new Dimension(800, 650));
    // frame.getContentPane().setLayout(new GridBagLayout());
    frame.getContentPane().add(wrapperPanel);
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> createAndShowGui());
}

Your core issue is (most likely) the fact that your panel doesn't provide any sizing hints to the layout manager, in order to allow it to make decisions about how much size it would need.

In order to achieve this, you need to override the getPreferredSize method of the panel to return the size you component would like to be.

This brings up a number of other issues:

  1. Don't load images in paintComponent , this is time consuming and can make your UI appear as it's frozen. Also, paintComponent gets called a lot, so you should avoid anything in there which takes to time to perform
  2. You should not reference src any where in you code. In this case, you will need use Class#getResource to obtain a reference to the image to load it
  3. You should call super.paintComponent as a matter of course

For example

public class Panneau extends JPanel { 

    private BufferedImage img;

    public Panneau() throws IOException {
        img = ImageIO.read(getClass().getResource("/disantiammo/image/image.png")); 
    }

    public void getPrefferedSize() {
        return img == null ? new Dimension(0, 0) : new Dimension(img.getWidth(), img.getHeight());
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (img != null) {
            g.drawImage(img, 0, 0, this);
        }
    }
}

PS: I've not tried to center the image in the container, but if the layout manager is honoring the size of the component, it won't make a difference

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM