Java 动态地将JPanel添加到groupLayout

Java 动态地将JPanel添加到groupLayout,java,swing,user-interface,Java,Swing,User Interface,我尝试用java为一个大学项目构建一个网络摄像头应用程序。到目前为止,我从来都不需要GUI,所以我没有这方面的经验,为此我在netbeans中使用了GUI构建器 目前,GUI看起来如下所示: 它只是在gui构建器中添加的一个jPanel和一个jButton 我要显示的图像是使用openCV拍摄的。这很好,我得到了一个缓冲区图像。为了显示这个图像,我创建了jPanel的一个子类,并更改了paintComponent方法 package WebcamImageCapture; import ja

我尝试用java为一个大学项目构建一个网络摄像头应用程序。到目前为止,我从来都不需要GUI,所以我没有这方面的经验,为此我在netbeans中使用了GUI构建器

目前,GUI看起来如下所示:

它只是在gui构建器中添加的一个jPanel和一个jButton

我要显示的图像是使用openCV拍摄的。这很好,我得到了一个缓冲区图像。为了显示这个图像,我创建了jPanel的一个子类,并更改了paintComponent方法

package WebcamImageCapture;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;

public class ImagePanel extends JPanel
{
    /**
     * Creates a new empty ImagePanel.
     */
    public ImagePanel()
    {
        this.image = null;
    }

    /**
     * Creates a new ImagePanel from BufferedImage img.
     * @param img The BufferedImage to display on the ImagePanel
     */
    public ImagePanel(BufferedImage img)
    {
        this.image = img;
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        g.drawImage(this.image, 0, 0, this.image.getWidth(), this.image.getHeight(), null);

        g.setColor(new Color(240, 160, 40));
        g.fillRect(10, 10, 25, 25);

        this.repaint();
    }

    /**
     * Sets the BufferedImage img to display on ImagePanel.
     * @param img The BufferedImage to display on the ImagePanel
     */
    public void setImage(BufferedImage img)
    {
        this.image = img;
    }

    private BufferedImage image;
}
GUI类具有成员
openCameraButton
outputPanel
,这是您可以在屏幕截图上看到的元素。我尝试将我的
imagePanel
添加到处理按钮的
ActionPerformed
事件的方法内部的
outputPanel

// create the custom jPanel
ImagePanel webcamFrame = new ImagePanel(img);
webcamFrame.setPreferredSize(new Dimension(640, 480));

this.outputPanel.getLayout().addLayoutComponent("webcamFrame", webcamFrame);
this.outputPanel.revalidate();
this.outputPanel.repaint();

this.revalidate();
this.repaint();
这不起作用=(.我在谷歌上搜索了2天并进行了测试(还阅读了oracle关于布局的文档:)没有找到解决方案

因此,主要问题是:

  • 如何添加ImagePanel
  • 我应该用其他布局手动实现GUI吗
  • 提前感谢你的帮助

    2.我是否应该使用其他布局手动实现GUI

    是的,IDE生成的代码很难维护和更改

    默认情况下,JFrame使用BorderLayout,因此您可以执行以下操作:

    ImagePanel = new ImagePanel();
    frame.add(imagePanel, BorderLayout.CENTER);
    
    JPanel south = new JPanel();
    JButton load = new JButton("Load Image");
    south.add(load);
    frame.add(south, BorderLayout.PAGE_END);
    
    因此,我们的想法是在设计时将面板添加到框架中。然后,每当捕获图像时,都会调用setImage()方法。setImage()方法中的代码是:

    this.image = img;
    repaint();
    
    您的
    paintComponent()
    代码将更改为:

    if (image != null);
        g.drawImage(this.image, 0, 0, this.image.getWidth(), this.image.getHeight(), null);
    
    也要去掉repaint()。这将导致无限循环

    2.我是否应该使用其他布局手动实现GUI

    是的,IDE生成的代码很难维护和更改

    默认情况下,JFrame使用BorderLayout,因此您可以执行以下操作:

    ImagePanel = new ImagePanel();
    frame.add(imagePanel, BorderLayout.CENTER);
    
    JPanel south = new JPanel();
    JButton load = new JButton("Load Image");
    south.add(load);
    frame.add(south, BorderLayout.PAGE_END);
    
    因此,我们的想法是在设计时将面板添加到框架中。然后,每当捕获图像时,都会调用setImage()方法。setImage()方法中的代码是:

    this.image = img;
    repaint();
    
    您的
    paintComponent()
    代码将更改为:

    if (image != null);
        g.drawImage(this.image, 0, 0, this.image.getWidth(), this.image.getHeight(), null);
    

    也要去掉repaint()。这将导致无限循环。

    我按照您的建议更改了代码

    package WebcamImageCapture;
    
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.image.BufferedImage;
    import javax.swing.JPanel;
    
    public class ImagePanel extends JPanel
    {
        /**
         * Creates a new empty ImagePanel.
         */
        public ImagePanel()
        {
            this.image = null;
        }
    
        /**
         * Creates a new ImagePanel from BufferedImage img.
         * @param img The BufferedImage to display on the ImagePanel
         */
        public ImagePanel(BufferedImage img)
        {
            this.image = img;
        }
    
        @Override
        public void paintComponent(Graphics g)
        {
            if(this.image != null)
            {
                super.paintComponent(g);
                g.drawImage(this.image, 0, 0, this.image.getWidth(), this.image.getHeight(), null);
    
                g.setColor(new Color(240, 160, 40));
                g.fillRect(10, 10, 25, 25);
    
                System.out.println("image drawn ...");
            }
            else
            {
                System.out.println("image not drawn ...");
            }
        }
    
        /**
         * Sets the BufferedImage img to display on ImagePanel.
         * @param img The BufferedImage to display on the ImagePanel
         */
        public void setImage(BufferedImage img)
        {
            this.image = img;
            this.repaint();
        }
    
        private BufferedImage image;
    }
    
    …并手动创建GUI

    private void init()
    {
        this.imageOutput = new ImagePanel();
        this.add(imageOutput, BorderLayout.CENTER);
    
        this.openCameraButton = new JButton("open camera");
        this.openCameraButton.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openCameraButtonActionPerformed(evt);
            }
        });
    
        JPanel navigation = new JPanel();
        navigation.add(this.openCameraButton, BorderLayout.PAGE_END);
    
        this.add(navigation);
        this.setTitle("Webcam");
        this.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    
        this.pack();
    }
    
    openCameraButtonActionPerformed
    方法中,我获取图像并使用
    ImagePanel
    setImage
    方法进行设置

    this.imageOutput.setImage(img);

    但不幸的是什么也没发生。如果我做了以下操作,我会得到一个新窗口,里面有图像

    JFrame myFrame = new JFrame("myFrame");
    ImagePanel out = new ImagePanel(img);
    myFrame.add(out);
    myFrame.pack();
    myFrame.setVisible(true);
    

    我做错了什么?

    我按照您的建议更改了代码

    package WebcamImageCapture;
    
    import java.awt.Color;
    import java.awt.Graphics;
    import java.awt.image.BufferedImage;
    import javax.swing.JPanel;
    
    public class ImagePanel extends JPanel
    {
        /**
         * Creates a new empty ImagePanel.
         */
        public ImagePanel()
        {
            this.image = null;
        }
    
        /**
         * Creates a new ImagePanel from BufferedImage img.
         * @param img The BufferedImage to display on the ImagePanel
         */
        public ImagePanel(BufferedImage img)
        {
            this.image = img;
        }
    
        @Override
        public void paintComponent(Graphics g)
        {
            if(this.image != null)
            {
                super.paintComponent(g);
                g.drawImage(this.image, 0, 0, this.image.getWidth(), this.image.getHeight(), null);
    
                g.setColor(new Color(240, 160, 40));
                g.fillRect(10, 10, 25, 25);
    
                System.out.println("image drawn ...");
            }
            else
            {
                System.out.println("image not drawn ...");
            }
        }
    
        /**
         * Sets the BufferedImage img to display on ImagePanel.
         * @param img The BufferedImage to display on the ImagePanel
         */
        public void setImage(BufferedImage img)
        {
            this.image = img;
            this.repaint();
        }
    
        private BufferedImage image;
    }
    
    …并手动创建GUI

    private void init()
    {
        this.imageOutput = new ImagePanel();
        this.add(imageOutput, BorderLayout.CENTER);
    
        this.openCameraButton = new JButton("open camera");
        this.openCameraButton.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                openCameraButtonActionPerformed(evt);
            }
        });
    
        JPanel navigation = new JPanel();
        navigation.add(this.openCameraButton, BorderLayout.PAGE_END);
    
        this.add(navigation);
        this.setTitle("Webcam");
        this.setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    
        this.pack();
    }
    
    openCameraButtonActionPerformed
    方法中,我获取图像并使用
    ImagePanel
    setImage
    方法进行设置

    this.imageOutput.setImage(img);

    但不幸的是什么也没发生。如果我做了以下操作,我会得到一个新窗口,里面有图像

    JFrame myFrame = new JFrame("myFrame");
    ImagePanel out = new ImagePanel(img);
    myFrame.add(out);
    myFrame.pack();
    myFrame.setVisible(true);
    
    我做错了什么