一个扩展JPanel的类,我希望在我的JFrame中添加CENTER proprity,这是一个BorderLayout

时间:2017-11-03 03:16:05

标签: java swing jframe jpanel

我有一个名为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...

在JFrame中,我有一些JPanel和其他元素。

JFrame的布局是BorderLayout

问题是这个平底锅必须是" java.awt.BorderLayout.CENTER",我只能这样放置:

  this.setContentPane(new Panneau());

如何将其放入" CENTER"?

我尝试过像

这样的事情
this.getContentPane().add(new Panneau(), java.awt.BorderLayout.CENTER);

似乎没有什么工作我唯一可以做的就是放置" panneau"而不是我的JFrame中的内容。 编辑:

这可能听起来很简单,但我不明白为什么我不能这样做,我一直在尝试这样做。

我有jDialog,它在BorderLayout,在"南","北"和"中心"我有jPanel元素("中心"' jPanel中没有任何内容。 "中心" jPanel称为Map。

我的事情如下: 在主要的

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

不是主要的。

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

我无法画任何东西。

2 个答案:

答案 0 :(得分:2)

我发现完全集中组件的最简单方法是给容器一个GridBagLayout,然后将单个组件添加到该容器,但不使用任何约束。

附带问题:您的代码以绘画方式读取图像 - 从不执行此操作。而是在一次中读取图像并将其存储在变量中。然后在绘画方法中显示它。另外一定要在你的覆盖中调用super的绘画方法。

如,

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());
    }
}

编辑:使用包装JPanel,如评论中所述:

您在评论中说明:

  

谢谢你anwser,但我的意思是:在borderLayout中有一个JFrame / JDialog,我想在它的中心位置放置“panneau”,也许我不知道怎么说它......“南方”,“北方”等元素......

然后将生成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());
}

答案 1 :(得分:1)

您的核心问题(很可能)是您的面板未向布局管理器提供任何尺寸提示,以便让其决定需要的尺寸。

为了实现这一目标,您需要覆盖面板的getPreferredSize方法以返回组件希望的大小。

这引出了许多其他问题:

  1. 不要在paintComponent中加载图片,这非常耗时,并且可以让您的用户界面显示为已冻结。此外,paintComponent被大量调用,因此您应该避免在那里花费时间执行任何事情
  2. 您不应该在代码中的任何位置引用src。在这种情况下,您需要使用Class#getResource来获取对图像的引用以加载它
  3. 您应该当然致电super.paintComponent
  4. 例如

    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:我没有尝试将图像置于容器中心,但如果布局管理器尊重组件的大小,它就不会有所作为

相关问题