Search code examples
javaswingcanvasmouselistenervlcj

Using MouseListener with vlcj


I'm currently developping a Java interface which needs to loop a HomeVideo until someone clicks on it to access the program. I'm using vlcj to read the video and it works well.

However, I need to detect if someone is clicking the video. Sadly as mentionned in the wiki the media player needs to be placed in a heavyweight component that implies I MUST place it under a Canvas (which is an AWT object, not a Swing one). Thus the solution here seems not be applicable to my problem.

Since then, I can't detect any click in the video (even though it works outside of the Canvas).

I know it is also possible to place the media player directly in the JFrame :

JFrame frame = new JFrame("My First Media Player");
frame.setBounds(100, 100, 600, 400);
mediaPlayerComponent = new EmbeddedMediaPlayerComponent();
frame.setContentPane(mediaPlayerComponent);
frame.setVisible(true);
mediaPlayerComponent.getMediaPlayer().playMedia("./Video.mp4");

but that doesn't seem possible here : I'm using a CardLayout to navigate through my JPanel, including the HomePage containing the media player.

Here is a SSCCE with vlcj-3.10.1, jna-4.1.0, jna-platform-4.1.0, slf4j-api-1.7.24 (and slf4j-simple-1.7.24) which executes vlcj in a Canvas contained in a JPanel with a MouseListener attached. When we click on the video, nothing happens but if we click outside (i.e the Canvas), we get the coordinates.

public class mediaplayer {

    JFrame frame;
    JPanel p;
    Canvas c;

    public static void main(final String[] args) {
        new NativeDiscovery().discover();
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new mediaplayer(args);
            }
        });
    }    

    private mediaplayer(String[] args) {
        frame = new JFrame("vlcj player");
        frame.setSize(1200, 800);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

        p = new JPanel();
        p.setLayout(null); // Absolute positionning
        p.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent me) {
                double x = me.getX();
                double y = me.getY();
                System.out.println("X and Y: " + x + " " + y);
            }
        });

        // heavyweight component where to place MediaPlayer
        c = new Canvas();
        c.setBackground(Color.black);
        c.setBounds(0, 0, 1000, 560);

        p.add(c);

        frame.add(p, BorderLayout.CENTER);

        MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory();
        EmbeddedMediaPlayer mediaPlayer = mediaPlayerFactory.newEmbeddedMediaPlayer();
        mediaPlayer.setVideoSurface(mediaPlayerFactory.newVideoSurface(c));
        mediaPlayer.setRepeat(true);
        mediaPlayer.prepareMedia("./Video.mp4");
        mediaPlayer.play();
    }
}

Is there any way to use a MouseListener on a Canvas, or a way to use vlcj in a way that it allows to detect mouse clicks ? Thanks by advance,

What I'm asking here is a solution to counter the lack of connexion between AWT.Canvas and Swing by using something else (than a Canvas) or with a workaround.


Solution

  • With vlcj on Linux and Windows adding a MouseListener to the video surface Canvas should just work in the usual way.

    If you use the vlcj MediaPlayerComponent encapsulation, this works (for me at least):

    mediaPlayerComponent.getVideoSurface().addMouseListener(listener);
    

    If you don't use a MediaPlayerComponent, then just add your listener directly to your Canvas.