简体   繁体   中英

Setting JPanel background to transparent

I'm trying to build my own video player using VLCJ, but I have a problem.

My code is

import java.awt.*;
import javax.swing.*;

import com.sun.jna.*;

import uk.co.caprica.vlcj.component.*;
import uk.co.caprica.vlcj.runtime.*;

public class MainFrame extends JFrame {

    public MainFrame(String vlcPath, String username) {
        super("Player");

        setSize(1366,700);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), vlcPath);

        EmbeddedMediaPlayerComponent player = new EmbeddedMediaPlayerComponent();

        setContentPane(player);

        JPanel panel = new JPanel();

        player.add(panel, BorderLayout.EAST);

        Dimension d = new Dimension(300,200);

        panel.setOpaque(false);
        panel.setLayout(null);
        panel.setPreferredSize(d);
        panel.setSize(d);

        setVisible(true);

        player.getMediaPlayer().playMedia("path to video");
    }
}

Now, as you can see, I want the video player to be on the whole screen, and I want an overlay with transparent background on the right side.

This code gives me the following:

在此输入图像描述

The background of the JPanel is for some reason black, not transparent. I tried creating my own class which extends JPanel and overrides paintComponent(Graphics g), but the result was the same.

The question is, how can I make it transparent?

The video is being played in a heavyweight AWT Canvas .

You can't overlay a transparent Swing component on top of that, it simply won't work.

Options:

  1. Overlay a transparent top level Window and put your overlay in there - this works because your window manager can deal with transparency of a top-level window - the problem with this is it's a bit clunky because you have to keep both frames in sync if you move them or minimize them, also your window manager might implement some sort of blend effect which is not what you want;
  2. Use the "direct" rendering media player and paint your own overlay on top of each frame - the downside is that it is less efficient than native rendering since your own application has to render each frame (it does work though);
  3. Use only heavyweight components in your overlay, like Label - but even then the label itself will not have a transparent background;

For the approach described in #1, you can use the setOverlay() method on your EmbeddedMediaPlayer instance, also use enableOverlay() to turn the overlay on and off.

For the approach described in #2, well this is probably the cleanest approach since it does not rely on any clunky workarounds (like keeping two top-level windows in sync), at the cost of more CPU usage and non-native video playback.

None of this is ideal, but it's the best you can do.

You should also probably look in the vlcj test sources because there are examples showing how to do overlays like this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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