如何使视频列表像YouTube一样摇摆

时间:2018-12-16 18:19:11

标签: java swing user-interface

我正在尝试为桌面制作类似YouTube的应用程序。我有一个包含视频的数据库,并且实现了搜索功能。事实是,我不知道如何使界面显示视频列表,因此我无法单击它并播放它。我想知道是否存在一个GUI元素,可以用来向其中添加多个条目并显示它们,因为youtube将您的订阅中的视频显示为列表。

我是用户界面的新手,所以请提前为菜鸟提问感到抱歉。

1 个答案:

答案 0 :(得分:2)

JPanels和FlowLayout,就这样...

创建并JPanel代表一个视频,我们称它们为视频容器,它的标题,视图和作者有JLabel。您需要为每个视频制作一个JPanel,其中一些必须很小,例如YouTube中的JPanel。现在要安排它们,诀窍是,JPanel必须与视频容器相同,或者要稍大于视频容器的宽度,然后使用FlowLayout。使用固定的宽度和FlowLayout,您的视频容器将在垂直方向上相互堆叠,就像在显示器右侧的YouTube中一样。

演示

请注意,我使用BoxLayout和Y_AXIS来堆叠视频,而不是FlowLayout方法。它有效,请检查:D

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.plaf.basic.BasicBorders;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.text.NumberFormat;
import java.util.Locale;

public class YoutubeLikeUI {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        JPanel contentPane = new JPanel(new BorderLayout(0,0));
        frame.setContentPane(contentPane);

        // This is the part than you're interested in
        // Adding video to the panel
        JPanel videos = new JPanel();
        // Important, make videos stack under each other / vertically
        BoxLayout layout = new BoxLayout(videos, BoxLayout.Y_AXIS);
        videos.setLayout(layout);
        // Here we are adding the individual videos to the so called "list"
        // You can change the JPanel "video" to an JScrollPanel and make the video list scrollable
        videos.add(new Video("Why choose mechanical keyboard?", 4975742, "Showing Tech 64",
                "https://images.freeimages.com/images/large-previews/5ce/my-keyboard-1241023.jpg"));
        videos.add(new Video("Ports explained", 9284573, "Showing Tech 64",
                "https://images.freeimages.com/images/large-previews/7ed/the-back-side-of-my-external-dvd-rom-1519905.jpg"));
        videos.add(new Video("Java 4 life. Here's why!", 7947173, "Showing Tech 64",
                "https://www.filecluster.com/howto/wp-content/uploads/2014/08/java-logo.jpg"));
        videos.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createEmptyBorder(8, 0, 8, 0), null));
        contentPane.add(videos, BorderLayout.EAST);
        // That was it, the magic, down below you see a class Video, look that up also

        // Nothing exciting, a demo video, just for the looks :)
        JPanel demoVideo = new JPanel();
        BoxLayout layout2 = new BoxLayout(demoVideo, BoxLayout.Y_AXIS);
        demoVideo.setLayout(layout2);

        // Search bar
        JTextField search = new JTextField() {
            @Override
            public void paint(Graphics g) {
                super.paint(g);
                if (getText().length() == 0) {
                    int h = getHeight();
                    ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
                    Insets ins = getInsets();
                    FontMetrics fm = g.getFontMetrics();
                    int c0 = getBackground().getRGB();
                    int c1 = getForeground().getRGB();
                    int m = 0xfefefefe;
                    int c2 = ((c0 & m) >>> 1) + ((c1 & m) >>> 1);
                    g.setColor(new Color(c2, true));
                    g.drawString("Search anything", ins.left, h / 2 + fm.getAscent() / 2 - 2);
                }
            }
        };
        search.setFont(new Font("Arial", Font.PLAIN, 24));
        search.setBackground(new Color(192, 192, 192, 255));
        search.setForeground(Color.WHITE);
        search.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createEmptyBorder(8, 8, 8, 8),
                BorderFactory.createLineBorder(Color.white)));
        contentPane.add(search, BorderLayout.NORTH);

        // Video
        demoVideo.add(new JLabel(new ImageIcon(getImage("https://dclottery.com/img/play-button-overlay.png").
                getScaledInstance(640, 360, Image.SCALE_SMOOTH))));
        JPanel info = new JPanel(new BorderLayout(8, 8));

        // Title
        JLabel title = new JLabel("The art of lighting. Get professional");
        title.setFont(new Font("Arial", Font.BOLD, 20));
        demoVideo.add(title);

        // Views
        JLabel views = new JLabel("8,195,384 views");
        views.setFont(new Font("Arial", Font.PLAIN, 18));
        demoVideo.add(views);

        // Author
        JLabel author = new JLabel(" Showing Tech 64 ");
        author.setFont(new Font("Arial", Font.BOLD, 12));
        author.setBorder(BorderFactory.createLineBorder(Color.lightGray));
        author.setBackground(new Color(0, 0, 0, 64));
        demoVideo.add(author);

        demoVideo.add(info);
        // Add gap around the content pane
        demoVideo.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createEmptyBorder(8, 8, 8, 8), null));
        contentPane.add(demoVideo, BorderLayout.LINE_START);

        // JFrame info
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    public static class Video extends JPanel {
        String name, author, imageURL;
        int views;
        BufferedImage image;

        public Video(String title, int views, String author, String imageURL) {
            super(new BorderLayout(8, 8));
            // Set the size of the video panel
            setMaximumSize(new Dimension(460, 96));
            setMinimumSize(new Dimension(460, 96));
            setPreferredSize(new Dimension(460, 96));

            // Initialize variables, add your own if needed
            this.name = title;
            this.views = views;
            this.author = author;
            this.imageURL = imageURL;

            // Get image, remove it and pass the image directly as an argument if needed
            image = getImage(imageURL);

            // Add components, here's the magic
            JLabel thumbnail = new JLabel(new ImageIcon(image.getScaledInstance(170, 96, Image.SCALE_DEFAULT)));
            thumbnail.setPreferredSize(new Dimension(170, 96));
            add(thumbnail, BorderLayout.WEST);

            JPanel info = new JPanel();
            BoxLayout layout = new BoxLayout(info, BoxLayout.Y_AXIS);
            info.setLayout(layout);

            JLabel titleLabel = new JLabel(makeWebSafe(title));
            titleLabel.setForeground(Color.black);
            titleLabel.setFont(new Font("Arial", Font.BOLD, 16));
            titleLabel.setToolTipText(title);
            info.add(titleLabel);
            JLabel authorLabel = new JLabel(makeWebSafe(author));
            authorLabel.setForeground(Color.gray);
            authorLabel.setFont(new Font("Arial", Font.PLAIN, 14));
            info.add(authorLabel);
            JLabel viewsTitle = new JLabel(makeWebSafe(NumberFormat.getNumberInstance(Locale.US).format(views)+" views"));
            viewsTitle.setForeground(new Color(64, 128, 64));
            viewsTitle.setFont(new Font("Arial", Font.PLAIN, 12));
            info.add(viewsTitle);

            add(info, BorderLayout.CENTER);

            // This is here to add a little gap between the videos in the list
            setBorder(BorderFactory.createCompoundBorder(
                    BorderFactory.createEmptyBorder(0, 2, 2, 2), null));
        }
    }

    // Inserting strings to an html without telling it, that it is not an piece of code, is very dangerous, use this method!
    // I used it to show the information about videos, because the name of the video might
    // contain html
    public static String makeWebSafe(String string) {
        return string.replace("<", "&lt;").replace(">", "&gt;");
    }

    // Download the image from the url, the image will not be stored as a file
    public static BufferedImage getImage(String imageURL) {
        try { return ImageIO.read(new URL(imageURL));
        } catch (Exception e) {
            return null;
        }
    }
}