简体   繁体   English

一个扩展JPanel的类,我想在具有BorderLayout的JFrame中添加CENTER属性

[英]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 : 我有一堂课叫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. 在JFrame中,我有一些带有其他元素的JPanels。

The JFrame's layout is a BorderLayout JFrame的布局是BorderLayout

The probleme is this pan has to be "java.awt.BorderLayout.CENTER", I can only place it this way : 问题是此锅必须是“ java.awt.BorderLayout.CENTER”,我只能以这种方式放置它:

  this.setContentPane(new Panneau());

How do I do to place it in "CENTER"? 如何将其放置在“ 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. 似乎无济于事,我唯一能做的就是放置“ panneau”而不是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. 我有jDialog,它在BorderLayout中,在“南”,“北”和“中心”中,我有带有元素的jPanel(“中心”的jPanel中没有任何内容。“中心” jPanel称为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. 我发现使组件完全居中的最简单方法是为容器提供GridBagLayout,然后将单个组件添加到该容器,但不使用任何约束。

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. 另外,请务必在您的替代中调用super的绘画方法。

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: 编辑:如注释中所述使用包装JPanel:

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 ... 谢谢您的帮助,但是我的意思是:在borderLayout中有一个JFrame / JDialog,我想在其中放“ panneau”到它的中心位置,也许我不知道该怎么说。在“南”,“北”等元素中...

then wrap the image producing JPanel in another JPanel that uses GridBagLayout and add the wrapper JPanel to the JFrame BorderLayout.CENTER 然后将生成图像的JPanel包装到另一个使用GridBagLayout的JPanel中,并将包装JPanel添加到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. 为了实现这一点,您需要重写面板的getPreferredSize方法以返回组件想要的大小。

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. 不要在paintComponent加载图像,这很费时间,并且可能会使您的UI冻结。 Also, paintComponent gets called a lot, so you should avoid anything in there which takes to time to perform 另外, paintComponent被调用很多,因此您应该避免在其中花费任何时间来执行操作
  2. You should not reference src any where in you code. 您不应在代码中的任何地方引用src In this case, you will need use Class#getResource to obtain a reference to the image to load it 在这种情况下,您将需要使用Class#getResource获得对图像的引用以将其加载
  3. You should call super.paintComponent as a matter of course 当然,您应该调用super.paintComponent

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 PS:我没有尝试将图像放在容器的中央,但是如果布局管理器尊重组件的大小,则不会有什么不同

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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