简体   繁体   English

动态地将JPanel添加到groupLayout

[英]Dynamically add a JPanel to a groupLayout

I try to build a webcam app for a university project in java. 我尝试使用Java为大学项目构建网络摄像头应用程序。 Until now i never needed GUI so i have no experience with this and for that i used the gui builder inside of netbeans. 到目前为止,我从不需要GUI,因此我对此没有经验,因此我在netbeans中使用了gui生成器。

For now the GUI looks like that: 现在,GUI看起来像这样:

http://i.stack.imgur.com/3MCiv.png

It's only a jPanel and a jButton added inside the gui builder. 它只是在gui构建器中添加的jPanel和jButton。

The image i want to display is taken by using openCV. 我要显示的图像是使用openCV拍摄的。 This works just fine and i get a bufferedImage. 这工作得很好,我得到了bufferedImage。 To display this image i created a subclass of jPanel and changed the paintComponent method. 为了显示此图像,我创建了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;
}

The GUI class has the member openCameraButton and outputPanel , which are the elements you can see on the screenshot. GUI类具有成员openCameraButtonoutputPanel ,它们是您可以在屏幕截图中看到的元素。 I tryed the following to add my imagePanel to the outputPanel inside of the method which handles the ActionPerformed event of the button. imagePanel了以下操作,将我的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();

This doesn't work =(. I googled around and tested for 2 days (also reading the oracle documentation on layouts : documentation ) not finding a solution. 这不起作用=(。我在Google周围搜索并测试了2天(还阅读了有关布局的oracle文档: documentation ),但未找到解决方案。

So the main questions are: 因此,主要问题是:

  1. How do i add the ImagePanel? 如何添加ImagePanel?
  2. Should i manually implement the GUI with an other layout? 我应该以其他布局手动实现GUI吗?

Thanks in advance for your help. 在此先感谢您的帮助。

2.Should i manually implement the GUI with an other layout? 2.是否应该以其他布局手动实现GUI?

Yes, code generated by an IDE is hard to maintain and change. 是的,IDE生成的代码很难维护和更改。

The JFrame is uses a BorderLayout by default so you could do something like: 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);

So the idea is you add the panel to the frame at design time. 因此,您的想法是在设计时将面板添加到框架。 Then whenever you capture an image you invoke the setImage() method. 然后,无论何时捕获图像,都将调用setImage()方法。 The code in your setImage() method would be: setImage()方法中的代码为:

this.image = img;
repaint();

Your paintComponent() code would change to: 您的paintComponent()代码将更改为:

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

Also get rid of the repaint(). 还要摆脱repaint()。 This will cause an infinite loop. 这将导致无限循环。

i changed my code as you recommended ... 我按照您的建议更改了代码...

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

... and created the GUI by hand. ...并手动创建了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();
}

Inside the openCameraButtonActionPerformed method i took the image and used the setImage method of the ImagePanel to set it. openCameraButtonActionPerformed方法内部,我拍摄了图像并使用ImagePanelsetImage方法进行设置。

this.imageOutput.setImage(img);

But unfortunately nothing happens. 但是不幸的是没有任何反应。 If i do the following, i get a new window with the image inside. 如果我执行以下操作,则会得到一个新窗口,其中包含图像。

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

What i am doing wrong? 我做错了什么?

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

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