基于java.swing的可视化播放器

本文详细介绍了基于JavaSwing框架设计的音乐播放器的代码实现,包括播放、暂停、上一首/下一首、歌曲列表、进度条等交互功能。此外,还提出了增加文件选择歌曲的功能,并展示了各种交互效果,如按钮的鼠标悬停和按下状态,以及歌词和播放时间的动态展示。
摘要由CSDN通过智能技术生成

1.概述

我们是基于java.swing框架下设计的用户界面,实现播放器的基本交互功能。本代码由于设计之初考虑不是很周到导致代码冗余严重,其次我在代码内只设置了三首歌,其实可以增加一个从文件选择歌曲的按钮用来将歌曲导入列表。

代码需要导入的包如下:

import java.io.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.text.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.util.*;
import java.util.Timer;
import javax.sound.sampled.*;

目录

1.概述

2.各功能模块的设计思路和方法

2.1暂停按钮

2.2播放按钮

2.3上一首/下一首按钮

2.4歌曲列表按钮

2.5进度条按钮(可交互)

2.6歌词模块

2.7开场动画模块

2.8播放歌曲GIF图模块

2.9播放时间动态展示模块

3.效果展示

3.1开场动画效果展示

3.2未播放任何歌曲时的展示

3.3歌曲列表展示

3.4按钮效果展示

3.5播放效果展示


2.各功能模块的设计思路和方法

2.1暂停停按钮

1)实现功能:能将正在播放的歌曲暂停,并且将暂停图标会变成播放图标,同时歌词滚动停止。鼠标悬停和按下有特殊效果,悬停时伴有文字提示功能。

(2)具体代码实现:

buttonStop = new JButton();//添加暂停按钮
buttonStop.setToolTipText("暂停");
buttonStop.setBounds(211, 615, 52, 54); //设置暂停按钮大小
Icon icon_stop = new ImageIcon(".//applestop.jpg");//创建暂停图标对象
buttonStop.setIcon(icon_stop);          //设置暂停图标
buttonStop.setBorder(BorderFactory.createEmptyBorder());
buttonStop.setFocusPainted(false);
buttonStop.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseEntered(MouseEvent e) {
        // 鼠标进入按钮时的效果
        buttonStop.setBorder(BorderFactory.createLineBorder(Color.WHITE, 2));

    }

    @Override
    public void mouseExited(MouseEvent e) {
        // 鼠标离开按钮时的效果恢复到默认状态
        buttonStop.setBorder(BorderFactory.createEmptyBorder());
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        super.mouseReleased(e);
        buttonStop.setBorder(BorderFactory.createLineBorder(Color.WHITE, 2));
        remove(buttonStop);
        remove(blank);
        add(buttonPlay);
        audioplay.stop();
    }

    @Override
    public void mousePressed(MouseEvent e) {
        super.mousePressed(e);
        buttonStop.setBorder(BorderFactory.createLineBorder(Color.GRAY, 2));
    }
});

2.2播放按钮

(1)实现功能: 能将暂停的歌或者选定的歌重新播放重新播放,播放按钮的位置变成暂停按钮的样式,对于鼠标悬停以及按压会产生一定的效果,鼠标悬停有文字提示其功能。

(2)具体代码实现:

buttonPlay = new JButton();//添加播放按钮
buttonPlay.setToolTipText("播放");
buttonPlay.setBounds(211, 615, 52, 54); //设置播放按钮大小
Icon icon = new ImageIcon(".//appleplay.png");//创建播放图标对象
buttonPlay.setIcon(icon);          //设置播放图标
buttonPlay.setBorder(BorderFactory.createEmptyBorder());
buttonPlay.setFocusPainted(false);
buttonPlay.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseEntered(MouseEvent e) {
        // 鼠标进入按钮时的效果
        buttonPlay.setBorder(BorderFactory.createLineBorder(Color.WHITE, 2));

    }

    @Override
    public void mouseExited(MouseEvent e) {
        // 鼠标离开按钮时的效果恢复到默认状态
        buttonPlay.setBorder(BorderFactory.createEmptyBorder());
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        super.mouseReleased(e);
        buttonPlay.setBorder(BorderFactory.createLineBorder(Color.WHITE, 2));
        textName.setText(""+SongName[choose].substring(0,SongName[choose].length()-4));
        remove(buttonPlay);
        remove(GIF[0]);
        remove(GIF[1]);
        remove(GIF[2]);
        revalidate();
        repaint();
        add(GIF[choose-1]);
        add(buttonStop);
        add(blank);
        //System.out.println(audioplay.GetTotaltime());
        if (audioplay.getFramePosition() > 0) {
            audioplay.playAfterPause(audioplay.getFramePosition());
        } else {
            audioplay.play(0);
        }


    }

    @Override
    public void mousePressed(MouseEvent e) {
        super.mousePressed(e);
        buttonPlay.setBorder(BorderFactory.createLineBorder(Color.GRAY, 2));
    }

});

add(buttonPlay);//添加播放按钮至窗口中

2.3上一首/下一首按钮

(1) 实现功能:能将播放的歌曲切换成列表的下一首/上一首,并且将所有的效果全部更换成下一首/上一首的(包括歌名、动图,歌词等等),如果此时时暂停歌曲的状态,点击下一首会直接跳转成播放下一首的状态,各图标随之改变成对应状态。这两个按钮同样具有鼠标的悬停以及按压的特殊效果,以及悬停时的文字提示功能(这里作补充解释:我将歌曲定义在列表中,每个歌曲都有对于的编号,实现上一首/下一首的实际就是将编号加一或者减一,并且模歌曲总数量)

(2)具体代码实现(这里仅展示下一首的代码,上一首按钮代码类似):

buttonRight = new JButton();
buttonRight.setToolTipText("下一首");
buttonRight.setBounds(300, 615, 67, 51);
Icon icon_right = new ImageIcon(".//right.png");
buttonRight.setIcon(icon_right);
buttonRight.setBorder(BorderFactory.createEmptyBorder());
buttonRight.setFocusPainted(false);
buttonRight.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseEntered(MouseEvent e) {
        // 鼠标进入按钮时的效果
        buttonRight.setBorder(BorderFactory.createLineBorder(Color.WHITE, 2));

    }

    @Override
    public void mouseExited(MouseEvent e) {
        // 鼠标离开按钮时的效果恢复到默认状态
        buttonRight.setBorder(BorderFactory.createEmptyBorder());
    }

    @Override
    public void mousePressed(MouseEvent e) {
        super.mousePressed(e);
        buttonRight.setBorder(BorderFactory.createLineBorder(Color.GRAY, 2));

    }

    @Override
    public void mouseReleased(MouseEvent e) {
        super.mouseReleased(e);
        buttonRight.setBorder(BorderFactory.createLineBorder(Color.WHITE, 2));
        choose++;
        if(choose==4) choose=1;
        audioplay.SetPlayAudioPath("./"+SongName[choose]);
        remove(buttonPlay);
        add(blank);
        remove(GIF[0]);
        remove(GIF[1]);
        remove(GIF[2]);
        revalidate();
        repaint();
        textName.setText(""+SongName[choose].substring(0,SongName[choose].length()-4));
        add(GIF[choose-1]);
        add(buttonStop);
        audioplay.play(0);
    }
});

add(buttonRight);

2.4歌曲列表按钮

(1) 实现功能:能另外再创建一个窗口,并且悬停在原窗口上方,在此窗口展示期间不允许对原窗口进行任何操作。窗口内展示歌曲列表,我们可以单击歌曲列表,从而选中某一首歌,此时是选中,不播放,可以在主界面中手动点击播放按钮从而实现播放,也可以双击列表,即播放该歌曲。

(2)具体代码实现:

if (e.getSource() == buttonList) {//如果是打开文件按钮点击事件
    JDialog floatingWindow = new JDialog(this, "歌曲选择", true);
    floatingWindow.setSize(300, 200);
    floatingWindow.setLocationRelativeTo(this);

    JPanel contentPane = new JPanel() {
        @Override
        protected void paintComponent(Graphics g) {
            // 绘制背景图片
            super.paintComponent(g);
            ImageIcon backgroundImage = new ImageIcon("choice_ground.jpg");
            g.drawImage(backgroundImage.getImage(), 0, 0, getWidth(), getHeight(), null);
        }
    };

    floatingWindow.setContentPane(contentPane);

    // 创建一个列表模型
    DefaultListModel<String> listModel = new DefaultListModel<>();
    listModel.addElement("飘洋过海  00:53");
    listModel.addElement("山外小楼夜听雨  01:40");
    listModel.addElement("我和我的祖国  00:59");

    // 创建列表,并设置选择监听器
    JList<String> songList = new JList<>(listModel);
    songList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    songList.addListSelectionListener(new ListSelectionListener() {
        public void valueChanged(ListSelectionEvent e) {
            if (!e.getValueIsAdjusting()) {
                // 处理列表项选择事件
                choose=songList.getSelectedIndex()+1;
                String selectedSong = SongName[choose];
                audioplay.SetPlayAudioPath("./"+selectedSong);
                textName.setText(""+SongName[choose].substring(0,SongName[choose].length()-4));
                add(buttonPlay);
                remove(blank);
                remove(buttonStop);
                remove(GIF[0]);
                remove(GIF[1]);
                remove(GIF[2]);
                progressBar.setValue(0);
                revalidate();
                repaint();

            }
        }
    });
    songList.addMouseListener(new MouseListener() {
        @Override
        public void mouseClicked(MouseEvent e) {
            if(e.getClickCount()==2){
                textName.setText(""+SongName[choose].substring(0,SongName[choose].length()-4));
                add(buttonStop);
                remove(buttonPlay);
                remove(GIF[0]);
                remove(GIF[1]);
                remove(GIF[2]);
                revalidate();
                repaint();
                add(GIF[choose-1]);
                add(blank);
                audioplay.play(0);

            }
        }

        @Override
        public void mousePressed(MouseEvent e) {}

        @Override
        public void mouseReleased(MouseEvent e) {}

        @Override
        public void mouseEntered(MouseEvent e) {}

        @Override
        public void mouseExited(MouseEvent e) {}
    });//增加双击功能
    songList.setOpaque(false);

    // 将列表放置在滚动面板中,并将滚动面板添加到悬浮窗口中
    JScrollPane scrollPane = new JScrollPane(songList);
    //scrollPane.setOpaque(false);
    floatingWindow.getContentPane().add(scrollPane, BorderLayout.CENTER);

    floatingWindow.setVisible(true);


}

2.5进度条按钮(可交互)

(1) 实现功能:能另外再创建一个窗口,并且悬停在原窗口上方,在此窗口展示期间不允许对原窗口进行任何操作。窗口内展示歌曲列表,我们可以单击歌曲列表,从而选中某一首歌,此时是选中,不播放,可以在主界面中手动点击播放按钮从而实现播放,也可以双击列表,即播放该歌曲。

(2)具体代码实现:

(第一部分:通过歌曲时间控制进度条,注:该部分代码放在定时器函数体内部)

double p = (double) audioplay.getFramePosition() / audioplay.GetTotaltime();
if(audioplay.getFramePosition()>0){
    nPlayTime = (int) (p*100);
    progressBar.setValue(nPlayTime);

(第二部分:通过点击进度条从而达到控制歌曲进度的目的)

progressBar=new JProgressBar();
progressBar.setMaximum(100);
progressBar.setMinimum(0);
progressBar.setBounds(50,565,388,6);
progressBar.addMouseListener(new MouseAdapter() {
    @Override
    public void mouseReleased(MouseEvent e) {
        super.mouseReleased(e);
        int mouseX=e.getX();
        int progressBarWidth=progressBar.getWidth();
        int progress=(int)((double)mouseX/progressBarWidth*progressBar.getMaximum());
        progressBar.setValue(progress);
        long time=(long)((double)mouseX/progressBarWidth*audioplay.GetTotaltime());
        audioplay.SetTime(time);
    }
});
progressBar.setBackground(Color.GRAY);
progressBar.setForeground(Color.WHITE);
progressBar.setBorder(BorderFactory.createEmptyBorder());
add(progressBar);

2.6歌词模块

(1) 实现功能:能实现在特定的区域展示每首歌曲带来的歌词,并且歌词会随着歌曲的变换而实现对应的变换,这里还要求实现歌词能随着歌曲的播放实现对应歌词高亮显示,这里我还实现了字体的一个放大的效果。

(2)具体代码实现:

(这里的歌词展示也是在定时器函数体内实现的,使用多个for循环输出歌词,这里歌词是在代码内部定义的,何时跳转也是在代码内部定义,这里可以改进为直接从歌曲文件中读入,通过时间戳文件来进行跳转)

if(audioplay.getFramePosition()>0){
    textLyrics.setText("");

    try {
        // 添加文本,并设置样式
        int light=0;
        while(breakTime[choose][light]<second){
            if(breakTime[choose][light+1]==-1) break;
            light++;

        }
        for(int i=0;i<light;i++){
            doc.insertString(doc.getLength(), sLyric[choose][i], style);
        }
        if(light<sLyric[choose].length)    doc.insertString(doc.getLength(), sLyric[choose][light], style2);
        light++;
        for(;light<sLyric[choose].length;light++){
            doc.insertString(doc.getLength(), sLyric[choose][light], style);
        }

    } catch (BadLocationException e) {
        e.printStackTrace();
    }
}//歌词设计

2.7开场动画模块

(1) 实现功能:运行程序之初播放一段视频,并且在一定的时间(我这里设置的是3s)后自动结束并且正常运行程序。

(2)具体代码实现:

(这里的begin组件就是一个JLabel组件,并且有动图)

add(Begin);
setVisible(true);
try {
    Thread.sleep(3000);
}catch (InterruptedException e){
    e.printStackTrace();
}

remove(Begin);

2.8播放歌曲GIF图模块

(1) 实现功能:能够在播放歌曲的时候有GIF动图展示,并且在切换歌曲是动图也会随之切换。

(2)具体代码实现:

(这里是为了利用数组下标,定义一个GIF数组)

Icon icon_gif3=new ImageIcon(".//GIF2.gif");
Icon icon_gif1=new ImageIcon(".//GIF6.gif");
Icon icon_gif2=new ImageIcon(".//GIF5.gif");
GIF[0]=new JLabel(icon_gif1);
GIF[0].setBounds(98,122,290,290);
GIF[1]=new JLabel(icon_gif2);
GIF[1].setBounds(98,122,290,290);
GIF[2]=new JLabel(icon_gif3);
GIF[2].setBounds(98,122,290,290);

(注:这里没有列出具体的切换逻辑,具体的逻辑体现在具体的按钮功能模块代码中)

2.9播放时间动态展示模块

(1) 实现功能:能够随着歌曲的播放,即时的展示播放时间,以及剩余时间

(2)具体代码实现:

int second=(int)audioplay.getFramePosition()/1000000;
int rest=(int)audioplay.GetTotaltime()/1000000-second;
if(audioplay.getIsRunning()&&audioplay.getFramePosition()>0){
    String time1="0"+second/60+":";
    String time2="-0"+rest/60+":";
    if(second%60<10) time1+="0";
    if(rest%60<10) time2+="0";
    time1=time1+second%60;
    time2=time2+rest%60;
    textTime1.setText(time1);
    textTime2.setText(time2);

}//时间组件设置

3.效果展示

3.1开场动画效果展示

 

(这里其实是设置一个动图,所以在实际的展示效果中使用动态效果的)

3.2未播放任何歌曲时的展示

 

3.3歌曲列表展示

 

3.4按钮效果展示

(这里展示的是当鼠标悬停在按钮上时按钮的效果,按下按钮时按钮边框会变灰,释放时恢复)

3.5播放效果展示

 

(图示中左边所展示图片是一个动图,当在播放歌曲时未在播放字样消失,出现歌曲名称,此时的进度条是可交互的,还有时间也会随着进度条或者歌曲的变化而变化,左侧的是已播放时间,右侧的是剩余时间)

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值