Reputation: 3
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.
Upvotes: 0
Views: 588
Reputation: 347194
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:
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 performsrc
any where in you code. In this case, you will need use Class#getResource
to obtain a reference to the image to load itsuper.paintComponent
as a matter of courseFor 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
Upvotes: 1
Reputation: 285403
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.
e.g.,
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());
}
Upvotes: 2