Package uk.co.caprica.vlcj.test.layout

Source Code of uk.co.caprica.vlcj.test.layout.AdaptiveLayoutTest$ZoomLayoutManager

/*
* This file is part of VLCJ.
*
* VLCJ is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VLCJ is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VLCJ.  If not, see <http://www.gnu.org/licenses/>.
*
* Copyright 2009, 2010, 2011, 2012, 2013, 2014 Caprica Software Limited.
*/

package uk.co.caprica.vlcj.test.layout;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;

import uk.co.caprica.vlcj.component.EmbeddedMediaPlayerComponent;
import uk.co.caprica.vlcj.player.MediaPlayer;
import uk.co.caprica.vlcj.player.MediaPlayerFactory;
import uk.co.caprica.vlcj.test.VlcjTest;

/**
* An example showing one way to solve the problem of needing to "move" a media player video
* surface.
* <p>
* It is not possible to change the component hierarchy of a video surface (Canvas) in any way (e.g.
* by moving to another parent, showing/hiding and so on) and expect the video to continue playing.
* <p>
* If the component hierarchy changes, you must stop and play the media player (this is not a vlcj
* limitation, it is an inherent limitation of libvlc and AWT combined).
* <p>
* The most common use case is to have multiple media players in one view, then zoom/expand one of
* those media players to occupy the whole window.
* <p>
* One solution to solve this issue is to use a custom layout manager to change the bounds (move
* and/or resize) an existing video surface without changing it's component hierarchy.
* <p>
* This example shows one such possible implementation.
* <p>
* Click a video panel to zoom it, press the Escape key to return to the grid view.
* <p>
* The strategy in this example is: when one video play is focused, resize the other video players
* to a size of 1x1 (setting the size to 0x0 will invalidate the video surface and cause playback
* to fail), move the video player to 0x0, and then use a CardLayout to switch from the video view
* to a blank container (without this you might still see colour changes in the 1x1 video player
* windows).
* <p>
* The other videos keep playing, but they do not have to.
* <p>
* The key point is that this example demonstrates how you can achieve the effect of moving,
* resizing, showing or hiding video surfaces without invalidating the video surface component and
* therefore without causing video playback to fail.
* <p>
* Be warned, this example is somewhat of a lash-up for purposes of this demo only.
* <p>
* Be warned also that this example uses multiple in-process media players in the same application
* and this is not without it's own well known risks.
*/
@SuppressWarnings("serial")
public class AdaptiveLayoutTest extends VlcjTest {

    private static final String[] mrls = {
        // Put your MRL's here, this example uses 12
    };

    private final MediaPlayerFactory mediaPlayerFactory = new MediaPlayerFactory();

    private final JFrame frame;
    private final JPanel cp;

    private final ZoomLayoutManager layoutManager;

    private final List<VideoPane> videoPanes = new ArrayList<VideoPane>();

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new AdaptiveLayoutTest().start();
            }
        });
    }

    private AdaptiveLayoutTest() {
        cp = new JPanel();
        cp.setBackground(Color.black);
        cp.setBorder(new EmptyBorder(16, 16, 16, 16));

        InputMap im = cp.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "blur");

        ActionMap am = cp.getActionMap();
        am.put("blur", new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                layoutManager.blur();
                cp.revalidate();
            }
        });

        int rows = 3; // Change this to suit
        int cols = 4;

        layoutManager = new ZoomLayoutManager(rows, cols);
        cp.setLayout(layoutManager);

        for(int i = 0; i < rows * cols; i++) {
            VideoPane videoPane = new VideoPane(i);
            videoPanes.add(videoPane);
            cp.add(videoPane, String.valueOf(i));
        }

        frame = new JFrame("Custom Layout Test");
        frame.setContentPane(cp);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private void start() {
        frame.setSize(1200, 800);
        frame.setVisible(true);

        for(int i = 0; i < videoPanes.size() && i < mrls.length; i++) {
            videoPanes.get(i).mediaPlayer().startMedia(mrls[i]);
        }
    }

    class VideoPane extends JPanel {

        private final int id;

        private final EmbeddedMediaPlayerComponent mediaPlayer;

        VideoPane(int id) {
            this.id = id;

            setBackground(Color.black);
            setBorder(BorderFactory.createLineBorder(Color.white));

            setLayout(new CardLayout());

            JPanel vp = new JPanel();
            vp.setLayout(new BorderLayout());
            vp.setBackground(Color.pink);

            JPanel top = new JPanel();
            top.setBorder(BorderFactory.createEmptyBorder(2626));
            top.setBackground(Color.black);
            top.setLayout(new BoxLayout(top, BoxLayout.X_AXIS));

            JLabel label = new JLabel(String.valueOf(id+1));
            label.setForeground(Color.white);
            label.setFont(new Font("Sansserif", Font.BOLD, 12));
            top.add(label);
            vp.add(top, BorderLayout.NORTH);

            addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    layoutManager.focus(VideoPane.this.id);
                    cp.revalidate();
                }
            });

            mediaPlayer = new EmbeddedMediaPlayerComponent() {
                @Override
                protected MediaPlayerFactory onGetMediaPlayerFactory() {
                    return mediaPlayerFactory;
                }
            };

            mediaPlayer.getVideoSurface().addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if(e.getButton() == MouseEvent.BUTTON3) {
                        mediaPlayer.getMediaPlayer().skip(10000);
                    }
                    else {
                        layoutManager.focus(VideoPane.this.id);
                        cp.revalidate();
                    }
                }
            });

            vp.add(mediaPlayer, BorderLayout.CENTER);

            add(vp, "video");

            JPanel p = new JPanel();
            p.setBackground(Color.pink);
            add(p, "hide");
        }

        MediaPlayer mediaPlayer() {
            return mediaPlayer.getMediaPlayer();
        }
    }

    class ZoomLayoutManager implements LayoutManager {

        private final int hgap = 16;
        private final int vgap = 16;

        private final int rows;
        private final int cols;

        private final List<Component> components;;

        private int focusIndex = -1;

        public ZoomLayoutManager(int rows, int cols) {
            this.rows = rows;
            this.cols = cols;
            this.components = new ArrayList<Component>(rows * cols);
        }

        @Override
        public void addLayoutComponent(String name, Component comp) {
            components.add(comp);
        }

        @Override
        public void removeLayoutComponent(Component comp) {
            components.remove(comp);
        }

        @Override
        public Dimension preferredLayoutSize(Container parent) {
            return parent.getPreferredSize();
        }

        @Override
        public Dimension minimumLayoutSize(Container parent) {
            return parent.getMinimumSize();
        }

        @Override
        public void layoutContainer(Container parent) {
            Insets insets = parent.getInsets();

            int width = parent.getWidth() - (insets.left + insets.right);
            int height = parent.getHeight() - (insets.top + insets.bottom);

            int cellWidth = (width - ((cols - 1) * hgap)) / cols;
            int cellHeight = (height - ((rows - 1) * vgap)) / rows;

            int i = 0;
            int x = insets.left;
            int y = insets.top;

            if(focusIndex == -1) {
                outer: for(int r = 0; r < rows; r++) {
                    for(int c = 0; c < cols; c++) {
                        if(i < components.size()) {
                            Component comp = components.get(i++);
                            ((CardLayout)((JComponent) comp).getLayout()).show((Container) comp, "video");
                            comp.setBounds(x, y, cellWidth, cellHeight);
                            x += cellWidth + hgap;
                        }
                        else {
                            break outer;
                        }
                    }
                    x = insets.left;
                    y += cellHeight + vgap;
                }
            }
            else {
                for(i = 0; i < components.size(); i++) {
                    Component comp = components.get(i);
                    if(i != focusIndex) {
                        comp.setBounds(0, 0, 1, 1);
                        ((CardLayout)((JComponent) comp).getLayout()).show((Container) comp, "hide");
                    }
                    else {
                        ((CardLayout)((JComponent) comp).getLayout()).show((Container) comp, "video");
                        comp.setBounds(x, y, width, height);
                    }
                }
            }
        }

        public void focus(int index) {
            focusIndex = index;
        }

        public void blur() {
            focusIndex = -1;
        }
    }
}
TOP

Related Classes of uk.co.caprica.vlcj.test.layout.AdaptiveLayoutTest$ZoomLayoutManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.