- 浏览: 182820 次
- 性别:
- 来自: 北京
最新评论
-
u011374223:
获取颜色的方法有两个,07xssfWORKBOOK的需要用这个 ...
apache poi读取excel中的颜色,真是坑爹啊 -
zhangtcb:
读取的颜色和Excel中的不一样啊
apache poi读取excel中的颜色,真是坑爹啊 -
LD_21:
...
log4j日志文件的相对路径 -
xfxlch:
upThx
来,让我们一起画个印章吧 -
xinxinlong:
单元格的style里面有个颜色,如果双击单元格,里面的文字选中 ...
apache poi读取excel中的颜色,真是坑爹啊
今天上班实在是无法静下心来工作,突然想到给我以前写的mp3播放器添加一个歌词显示组件.
大概思路是这样.
在一个组件上绘制出所有的歌词信息.
然后按照歌曲进度和歌词所在的进度移动示口,把要显示的那行歌词显示在组件中央.
如果必要,可以重绘组件屏幕中央的那行文字.加上一些效果.(现在没有做)
而且也没有做offset的修正.
现在实在是太简陋了,等有空再完善.要做的事实在太多了.
那个ProgressListener在我以前的文章<swing做的mp3播放器>中.
首先是lrc模型,歌词的内容保存在TreeMap中,key为歌词开始的时间.单位为毫秒.value为歌词.
package jmp123.shell.lrc; import java.util.TreeMap; class LRC { private String artist; private String title; private String album; private String maker; private int offset; private TreeMap<Integer, String> texts; public String getArtist() { return this.artist; } public void setArtist(String artist) { this.artist = artist; } public String getTitle() { return this.title; } public void setTitle(String title) { this.title = title; } public String getAlbum() { return this.album; } public void setAlbum(String album) { this.album = album; } public String getMaker() { return this.maker; } public void setMaker(String maker) { this.maker = maker; } public int getOffset() { return this.offset; } public void setOffset(int offset) { this.offset = offset; } public TreeMap<Integer, String> getTexts() { if (this.texts == null) { this.texts = new TreeMap<Integer, String>(); } return this.texts; } }
接着是读取和显示组件:
package jmp123.shell.lrc; import java.awt.Dimension; /** * 读取歌词 <br> * * @日期. 2010-10-9 下午01:27:49 */ public class LRCReader extends JScrollPane { private class DisplayComponent extends JComponent { /** * */ private static final long serialVersionUID = -1926347751983144607L; @Override protected void paintComponent(Graphics g) { int width = LRCReader.this.getViewport().getWidth(); int height = this.getStringHeight(); int y = (LRCReader.this.getViewport().getHeight() - height) / 2; String title = "标题: " + LRCReader.this.lrc.getTitle(); g.drawString(title, (width - this.getStringWidth(title)) / 2, y); y += height; String artist = "艺术家: " + LRCReader.this.lrc.getArtist(); g.drawString(artist, (width - this.getStringWidth(artist)) / 2, y); y += height; String album = "专辑: " + LRCReader.this.lrc.getAlbum(); if (album != null) { g .drawString(album, (width - this.getStringWidth(album)) / 2, y); } y += height; String maker = LRCReader.this.lrc.getMaker(); if (maker != null) { maker = "By: " + maker; g .drawString(maker, (width - this.getStringWidth(maker)) / 2, y); } y += height; // 空一行 y += height; LRCReader.this.raise = height * 5 * 1000 / LRCReader.this.lrc.getTexts().firstKey(); // 内容 for (String s : LRCReader.this.lrc.getTexts().values()) { g.drawString(s, (width - this.getStringWidth(s)) / 2, y); y += height; } if (this.getHeight() < y) { this.setPreferredSize(new Dimension(this.getWidth(), y)); } } private int getStringWidth(String text) { Graphics g = this.getGraphics(); FontMetrics fm = g.getFontMetrics(); int w = 0; for (char c : text.toCharArray()) { w += fm.charWidth(c); } return w; } private int getStringHeight() { Graphics g = this.getGraphics(); FontMetrics fm = g.getFontMetrics(); return fm.getAscent() + fm.getDescent() + fm.getLeading(); } public void update(int current) { Integer key = LRCReader.this.lrc.getTexts().floorKey(current); System.out.println("Current:" + current + ";Key:" + key); if (key != null) { if (key != LRCReader.this.lrc.getTexts().firstKey()) { Integer next = LRCReader.this.lrc.getTexts().higherKey(key); if (next != null) { int i = next - key; if (i > 0) { LRCReader.this.raise = this.getStringHeight() * 1000 / i; System.out.println(raise); } } } } } } /** * */ private static final long serialVersionUID = 7690089125689655670L; /** * artist艺术家、演唱者 */ private static final String TAG_AR = "ar"; /** * title题目,标题,曲目 */ private static final String TAG_TI = "ti"; /** * album唱片集、专辑 */ private static final String TAG_AL = "al"; /** * (介词)制作者、编辑人员(一般指lrc歌词的制作人) */ private static final String TAG_BY = "by"; /** * 其单位是毫秒,正值表示延迟,负值表示提前。用于整体调整歌词显示慢(快)于音乐播放。 */ private static final String TAG_OS = "offset"; /** * lrc文件路径 */ private String path; /** * lrc内容 */ private LRC lrc; private ProgressListener listener; private volatile int raise; /** * 匹配标签 */ private static Pattern PATTER_TAG = Pattern .compile("\\[(.*?)\\]"); /** * 匹配时间 */ private static Pattern PATTER_TIME = Pattern .compile("(\\d+):(\\d+)(\\.(\\d+))?"); public LRCReader(String path) { this.path = path; this .setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); this .setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER); this.init(); } private void init() { if (this.path != null) { try { BufferedReader reader = new BufferedReader( new InputStreamReader(new FileInputStream(this.path), "GBK")); String line = null; this.lrc = new LRC(); while ((line = reader.readLine()) != null) { if (line.trim().length() > 0) { Matcher tagMatcher = LRCReader.PATTER_TAG.matcher(line); while (tagMatcher.find()) { String tag = tagMatcher.group(1).trim(); Matcher timeMatcher = LRCReader.PATTER_TIME .matcher(tag); if (timeMatcher.matches()) {// lrc内容 String m = timeMatcher.group(1); String s = timeMatcher.group(2); String ms = timeMatcher.group(4); int tms = 0; tms += Integer.valueOf(m) * 60 * 1000; tms += Integer.valueOf(s) * 1000; if (ms != null) { tms += Integer.valueOf(ms); } String text = line.substring( line.lastIndexOf("]") + 1).trim(); this.lrc.getTexts().put(tms, text); } else {// tags if (tag != null) { String[] array = tag.split(":"); String key = array[0].trim(); String value = array[1].trim(); if (LRCReader.TAG_AL.equalsIgnoreCase(key)) { this.lrc.setAlbum(value); } else if (LRCReader.TAG_AR .equalsIgnoreCase(key)) { this.lrc.setArtist(value); } else if (LRCReader.TAG_BY .equalsIgnoreCase(key)) { this.lrc.setMaker(value); } else if (LRCReader.TAG_OS .equalsIgnoreCase(key)) { this.lrc.setOffset(Integer .valueOf(value)); } else if (LRCReader.TAG_TI .equalsIgnoreCase(key)) { this.lrc.setTitle(value); } } } } } } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } if (this.lrc != null) { this.setViewportView(new DisplayComponent()); final Timer timer = new Timer(1000, new ActionListener() { public void actionPerformed(ActionEvent e) { JViewport vp = LRCReader.this.getViewport(); Point p = vp.getViewPosition(); p.setLocation(p.x, p.y + LRCReader.this.raise); if (p.y < vp.getView().getHeight() - vp.getHeight() / 2) { vp.setViewPosition(p); } } }); timer.start(); } } public ProgressListener getLRCListener() { if (this.listener == null) { this.listener = new ProgressListener() { public void update(ProgressEvent event) { int current = (int) (event.getLength() * 1000 * event.getFrame() / event.getFrames()); ((DisplayComponent) LRCReader.this.getViewport().getView()) .update(current); } }; } return this.listener; } public static void main(String[] args) { LRCReader r = new LRCReader("E:\\music\\lyrics\\王力宏 - 十八般武艺_1.lrc"); LRC lrc = r.lrc; System.out.println(lrc.getArtist()); for (Map.Entry<Integer, String> entry : lrc.getTexts().entrySet()) { System.out.println(entry.getKey() + " : " + entry.getValue()); } } }
测试类:
package jmp123.shell.lrc; import java.awt.BorderLayout; public class LRCTest extends JFrame { /** * */ private static final long serialVersionUID = -9185495379210075085L; private JPanel contentPane; private LRCReader reader; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { LRCTest frame = new LRCTest(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } /** * Create the frame. */ public LRCTest() { this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setBounds(100, 100, 450, 431); this.contentPane = new JPanel(); this.contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); this.contentPane.setLayout(new BorderLayout(0, 0)); this.setContentPane(this.contentPane); this.contentPane.add(this.getReader(), BorderLayout.CENTER); } private LRCReader getReader() { if (this.reader == null) { this.reader = new LRCReader("E:\\music\\lyrics\\王力宏 - 十八般武艺_1.lrc"); final ProgressListener pl = this.reader.getLRCListener(); new Timer(1000, new ActionListener() { private int i = 0; public void actionPerformed(ActionEvent e) { pl.update(new ProgressEvent(null, 240, 240, i++)); } }).start(); } return this.reader; } }
发表评论
-
公约数,公倍数和素数的简单计算
2012-04-01 16:08 1331为自己留作备份,省得用到的时候再去寻找 简单的计算最大公约数 ... -
java简单打印
2012-03-08 09:56 1234没什么,就是一个简单的打印,留作存档 publi ... -
httpclient4的封装
2012-01-06 15:11 4636没什么特别的,自己封装着用的. package cpcns. ... -
h2的baseDir
2011-11-11 16:38 1464使用h2 1.3.161.在web项目中.计划在Listene ... -
eclipse下自动打包项目并部署到web项目的lib下
2011-10-18 15:59 5119修改web项目的.settings下的org.eclipse. ... -
获取汉字的五笔,全拼和双拼的工具类
2011-10-10 15:51 2393如题,项目需要,首先可用的自然是pinyin4j. 在不考虑 ... -
五笔86和汉字对照表
2011-10-09 16:53 2533项目要用到汉字转拼音和五笔,拼音容易,使用pinyin4j. ... -
java System属性
2011-09-19 10:14 1387自定义 : java -Dname=value S ... -
log4j日志文件的相对路径
2011-09-01 10:51 6813一直没能很好的解决log4j的日志文件的保存路径.今天恰好又遇 ... -
Apache codec中的base64
2011-07-20 09:46 2287一直使用sun的base64,但是感觉不是很好,毕竟不是标准包 ... -
来,让我们一起画个印章吧
2011-07-04 14:52 4530这几天发现有哥们在介 ... -
svg中的arc转化为java中的arc
2011-05-27 15:31 2682最近项目需要解析svg中的path.直线和贝塞尔曲线都好办,唯 ... -
swing的拖拽(dnd)的简单实现
2011-03-28 10:18 2008这几天项目需要用到dnd,API比较麻烦.在网上找了很多,都只 ... -
自用的MD5计算工具
2011-03-11 15:45 1783/** * 检查输入流的MD5值是否符合.如果MD5为 ... -
用jsoup分析下载巨鲸的mp3
2011-02-25 15:37 1727这两天突然想听听杰克逊的歌.首选当然是巨鲸. 支持正版. ... -
获取子类的泛型参数
2011-01-27 16:03 1358用的时候不好找,今天看nutz的dao的源码看到了,摘出来备份 ... -
简单的通过注解运行的dao
2011-01-26 11:47 1792项目是个老项目,是个比较简单,但是编码比较凌乱的项目.数据库字 ... -
java模拟js的escape和unescape函数
2011-01-05 10:43 3468这个是在网上找的代码,然后修改了下.作用标题已经很明显了. ... -
自己写的多线程对象池
2010-12-10 16:53 1322/** * 排版器的一个公用接口 <br> ... -
apache poi读取excel中的颜色,真是坑爹啊
2010-12-01 16:23 16973工作原因,需要使用poi来读取excel中的所有内容. 其他 ...
相关推荐
在Java编程领域,Swing库是一个非常重要的组件,它提供了丰富的图形用户界面(GUI)工具,用于构建桌面应用程序。本项目“musicPlayer123_swing_音乐播放器_”显然是一个利用Swing来实现的音乐播放器。下面将详细...
- 歌词显示:可以解析LRC格式的歌词文件,将歌词与时间戳关联,根据播放进度展示相应的歌词。 5. WAV文件读取与播放: - 使用`AudioInputStream`读取WAV文件,通过`Clip`对象进行播放控制。 - ` Clip.open(Audio...
Java音乐播放器歌词同步是一个基于Java编程语言开发的简易音乐播放器,主要特色在于实现歌词与音乐播放的同步。在本文中,我们将深入探讨这个项目的核心技术和相关知识点,以帮助你理解和掌握Java在多媒体处理方面的...
【Java音乐播放器】是一个基于Java编程语言开发的全功能音乐播放软件,它不仅具备了基本的音频播放功能,还特别加入了LRC歌词同步显示,为用户提供了丰富的音乐体验。这款音乐播放器的设计考虑到了跨平台性,因此既...
Swing是Java标准库的一部分,提供了丰富的用户界面组件,用于构建桌面应用,包括音乐播放器这样的多媒体应用程序。这款播放器因其开源特性而备受青睐,允许开发者深入研究其代码,学习并扩展其功能。 在音乐播放器...
3. **歌词显示**:为了实时同步显示歌词,开发者可能使用LRC(Lyrics)文件格式,这是一种时间标记的文本格式,用于存储歌曲的逐句歌词。解析LRC文件并将其与音乐播放进度同步是实现这一功能的关键。 4. **图形用户...
虽然在给出的代码片段中没有详细展示歌词显示的具体实现方式,但可以推测这可能通过读取单独的歌词文件(通常是.txt或.lrc格式),并在`JTextArea`组件中动态更新歌词内容来实现。 ```java TextArea textArea = new...
使用Swing或JavaFX等图形用户界面库可以创建进度条组件。 4. **示波器波形图显示**:示波器波形图能直观地展示音乐的音频信号。这通常通过读取音频数据并进行傅立叶变换来实现,然后将结果显示在图形界面上。可能...
程序会解析LRC文件中的时间标签,并将对应的歌词在界面上适时滚动显示,增强用户的听歌体验。为了使功能正常工作,用户需要将歌词文件放置在播放器指定的目录下,与对应的音乐文件一起。 在开发过程中,学生需要...
4. **用户界面**:为了方便用户操作,歌词制造器可能使用JavaFX或Swing等GUI工具包来构建用户界面,包括播放、暂停、停止等控制按钮,以及歌词显示区域。 5. **事件监听和处理**:为了响应用户的操作,如点击播放...
这些库提供了各种组件,如按钮、文本框和标签,用于构建播放、暂停、停止等控件,以及歌词显示区域。 7. **事件监听**: 播放器中的按钮和其他交互元素需要监听用户的操作,例如点击播放按钮会触发播放事件。这是...
同时,为了实现音乐播放器的界面,开发者可能使用了Java Swing或JavaFX库,它们提供了丰富的UI组件,如按钮、播放进度条、音量控制等,用于构建一个用户友好的界面。 歌词同步功能是该播放器的一大亮点。这通常涉及...
- **播放器界面**:通常使用Swing或JavaFX等GUI库构建用户界面,包括播放按钮、进度条、音量控制、歌词显示区域等组件。 - **音频流处理**:JMF的`Player`类用于播放音频流,开发者需要创建`Player`实例,加载MP3...
在JavaFX或Swing中,可以改变组件的外观和感觉(LookAndFeel)。 5. **调节亮度**:对于支持这一特性的平台,例如Android,可以通过改变系统或应用程序的亮度设置来实现。这通常涉及到获取和设置系统的亮度值,或者...
音乐播放器的开发涉及到了多个技术组件: 1. **Java Sound API**:Java Sound API是Java标准版平台提供的底层声音处理接口,能够实现录音、播放和编辑声音等多种功能。它还允许通过服务提供者接口(SPI)来扩展支持...
考虑到支持歌词显示,播放器界面很可能有一个专门区域用于实时滚动显示歌词,这部分可能采用了类似于LRC格式的歌词文件解析技术。 对于多平台支持,开发者可能利用了Java的JNI(Java Native Interface)技术与各...
8. **歌词同步**:如果项目包含歌词同步功能,开发者需要解析LRC格式的歌词文件,并在播放过程中实时更新歌词显示。 9. **设计模式**:在开发大型项目时,设计模式如单例模式、工厂模式等可以帮助保持代码结构清晰...
开发者需要解析LRC文件,将歌词与音乐的时间轴同步,然后根据音乐播放的进度实时更新歌词显示。这可以通过定时器或者监听音乐播放器的事件来实现。 4. **进度条拖动** 进度条拖动功能允许用户自由调整音乐播放的...
项目通过联网获取与当前播放歌曲对应的LRC歌词文件(一种文本格式,包含时间戳和歌词内容)。开发者可能使用HTTP或HTTPS协议发送请求到歌词服务器,接收到响应后解析出歌词内容,并将其同步显示在界面上,以便用户在...
3. 实时歌词同步:通过LRC文件或者API获取歌词信息,配合歌曲播放实现逐句滚动显示,提升用户体验。 四、系统扩展性 1. 蓝牙/网络点歌:为了满足不同场景需求,系统应支持蓝牙设备或网络进行点歌,这需要Java的...