0

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.

Community
  • 1
  • 1
Iwerzhon
  • 63
  • 1
  • 8

1 Answers1

1

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.

caprica
  • 3,902
  • 4
  • 19
  • 39
  • First, thanks for the quick reply ! As a `MediaPlayerComponent` needs to be placed in a heavyweight component (here a `JFrame` I suppose), I can't see a way to use it by using a `CardLayout` too, so it seems I'll use the second option. From the information found [here](http://stackoverflow.com/questions/9612684/drawing-in-java-using-canvas) and [here](http://stackoverflow.com/questions/10556369/mouselistener-in-canvas-not-working) I thought it wasn't a good practice to access `awt.Canvas` informations in a `Swing` environment. I'll documentate myself in how to do this and tell you the results. – Iwerzhon Mar 17 '17 at 12:48
  • I'm not sure what you mean. You really should check the vlcj examples and vlcj-player reference project. I use CardLayout on many of my media player projects with vlcj without any problem. I use mouse listeners and Canvas without any problem. I use Canvas generally in a Swing application without any problem. There are limitations to using heavyweight components in Swing applications, but there's no rule that you *can't*. – caprica Mar 17 '17 at 13:16
  • When you speak of limitation, you mean we can't use semi-transparent elements (logo, ...) in a JLabel to place above the video right ? Not related to what was asked above, but is there any workaround ? I'm currently modifying my code in order to test what you said, thanks. – Iwerzhon Mar 20 '17 at 08:18
  • Look in the vlcj test sources for anything that mentions "overlay". There are workarounds, none of which are ideal, but which may be good enough for you. – caprica Mar 20 '17 at 15:13
  • Also, you should consider using the native logo functionality, vlcj has an API for that - again, it might be good *enough*. – caprica Mar 20 '17 at 15:14
  • I was checking the possibilities with the native logo functionality from [this sample](https://github.com/caprica/vlcj/blob/master/src/test/java/uk/co/caprica/vlcj/test/logo/LogoTest.java#L178). I also read [the 3 ways](http://caprica.github.io/vlcj/javadoc/3.0.0/uk/co/caprica/vlcj/player/MediaPlayer.html) to implement it but didn't look further because it can only allow 1 logo per video. I didn't search why the logo didn't appear and will focus on the other solution instead (with transparent overlay), which allow us to set multiple logos/images. – Iwerzhon Mar 20 '17 at 17:23