按钮似乎被视频覆盖

Button seems to be covered by video

我正在尝试编写一个使用网络摄像头捕捉照片的程序。我想在直播视频的 JFrame 中添加一个 JButton。然而,按钮没有出现。我的信念是视频涵盖了它。我在下面附上了我的代码。

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class MyFrame extends JFrame {
private JPanel contentPane;


/**
 * Launch the application.
 */
public static void main(String[] args) {
    MyFrame frame = new MyFrame();
    frame.contentPane.add(new JButton("Camera"));
    frame.setVisible(true);
}
 // Create the frame.
public MyFrame() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 650, 490);      
    contentPane = new JPanel();
    setContentPane(contentPane);
    contentPane.setLayout(null);
    new MyThread().start();
}
VideoCap videoCap = new VideoCap();
public void paintComponent(Graphics g){
    g = contentPane.getGraphics();
    g.drawImage(videoCap.getOneFrame(), 0, 0, this);
}
class MyThread extends Thread{
    @Override
    public void run() {
        for (;;){
            repaint();
            try { Thread.sleep(30);
            } catch (InterruptedException e) {    }
        }  
    } 
}
}

任何建议都会很棒。
我查看了很多关于 Jbuttons not showing 的问题,但我不确定哪一个与我的相似。有的话请指点一下。

提前致谢。

您正在向内容窗格添加按钮,然后在其上绘制视频。当然,视频会覆盖您的按钮。

一些建议:

  1. 不要设置自定义内容窗格。

  2. 创建两个单独的面板并将它们添加到内容窗格。

  3. 将按钮添加到一个面板。

  4. 将您的视频绘制到另一个视频上。

  5. 重构您的代码以正确覆盖 paintComponent 并从另一个线程重新绘制它。

我不确定您使用哪个库来制作上述视频。尽管在此示例中,我使用 opencv 库从网络摄像头创建图像。您必须对其进行修改,以使其适用于您的用例。

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStream;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

import org.opencv.core.*;     
import org.opencv.videoio.VideoCapture;

public class ApplicationBase {

    private BufferedImage m_Captured_BufferedImage;

    static {
        System.out.println(System.getProperty("java.library.path"));
        System.loadLibrary ( Core.NATIVE_LIBRARY_NAME );
    }

    private void displayGUI ( BufferedImage image, String title, int x, int y ) {
        JFrame frame = new JFrame ( title );
        frame.setDefaultCloseOperation ( JFrame.DISPOSE_ON_CLOSE );

        JPanel contentPane = new JPanel ( new BorderLayout ( 5, 5 ) );

        PictureDrawer pictureDrawer = new PictureDrawer ( image );
        contentPane.add ( pictureDrawer, BorderLayout.CENTER );

        JButton button = new JButton ( "Click Me not!" );
        contentPane.add ( button, BorderLayout.PAGE_END );

        frame.setContentPane ( contentPane );
        frame.pack ();
        frame.setLocationByPlatform ( true );
        frame.setVisible ( true );
    }

    private void startApp () {
        VideoCapture camera = new VideoCapture ( 0 );

        Mat videoFrame = new Mat ();
        camera.read ( videoFrame );

        if ( camera.read ( videoFrame ) ) {
            m_Captured_BufferedImage = matToBufferedImage ( videoFrame );
            Runnable runnable = new Runnable () {
                @Override
                public void run () {
                    displayGUI ( m_Captured_BufferedImage, "Image", 0, 0 );
                }
            };                  
            EventQueue.invokeLater ( runnable );
        }
        camera.release ();
    }

    public BufferedImage matToBufferedImage ( Mat videoFrame ) {
        //Mat() to BufferedImage
        int type = 0;
        if ( videoFrame.channels () == 1 ) {
            type = BufferedImage.TYPE_BYTE_GRAY;
        } else if ( videoFrame.channels () == 3 ) {
            type = BufferedImage.TYPE_3BYTE_BGR;
        }
        BufferedImage image = new BufferedImage ( videoFrame.width (), videoFrame.height (), type );
        WritableRaster raster = image.getRaster ();
        DataBufferByte dataBuffer = ( DataBufferByte ) raster.getDataBuffer ();
        byte [] data = dataBuffer.getData ();
        videoFrame.get ( 0, 0, data );

        return image;
    }

    public static void main ( String [] args ) {
        new ApplicationBase ().startApp ();
    }
}

class PictureDrawer extends JComponent {

    private BufferedImage m_BufferedImage;

    public PictureDrawer ( BufferedImage bufferedImage ) {
        this.m_BufferedImage = bufferedImage;
    }

    @Override
    protected void paintComponent ( Graphics g ) {
        super.paintComponent ( g );
        g.drawImage ( m_BufferedImage, 0, 0, this );
    }

    @Override
    public Dimension getPreferredSize () {
        return new Dimension ( m_BufferedImage.getWidth (), m_BufferedImage.getHeight () );
    }
}

我从 this

下载了 OpenCV 库

使用此命令编译项目:

javac -classpath .;C:\install\opencv\opencv\build\java\opencv-320.jar; -d bin source\*.java

对 运行 项目的命令:

>java -classpath .;C:\install\opencv\opencv\build\java\opencv-320.jar; -Djava.library.path=C:\install\opencv\opencv\build\java\x64 ApplicationBase