我正在使用mp3plugin.jar库,我的音乐很棒。唯一的问题是,当我的程序启动时,JFrame不会显示。在我添加音乐之前,它完美无缺。这是我的音乐代码:
package com.org.pong;
import javax.sound.sampled.*;
import javax.sound.*;
import java.io.*;
import java.net.URL;
public class Music {
Music(String url) {
int total, totalToRead, numBytesRead, numBytesToRead;
byte[] buffer;
boolean stopped;
AudioFormat wav;
TargetDataLine line;
SourceDataLine lineIn;
DataLine.Info info;
File file;
FileInputStream fis;
// AudioFormat(float sampleRate, int sampleSizeInBits,
// int channels, boolean signed, boolean bigEndian)
wav = new AudioFormat(44100, 16, 2, true, false);
info = new DataLine.Info(SourceDataLine.class, wav);
buffer = new byte[1024 * 333];
numBytesToRead = 1024 * 333;
total = 0;
stopped = false;
if (!AudioSystem.isLineSupported(info)) {
System.out.print("no support for " + wav.toString());
}
try {
// Obtain and open the line.
lineIn = (SourceDataLine) AudioSystem.getLine(info);
lineIn.open(wav);
lineIn.start();
fis = new FileInputStream(file = new File(url));
totalToRead = fis.available();
while (total < totalToRead && !stopped) {
numBytesRead = fis.read(buffer, 0, numBytesToRead);
if (numBytesRead == -1)
break;
total += numBytesRead;
lineIn.write(buffer, 0, numBytesRead);
}
} catch (LineUnavailableException ex) {
ex.printStackTrace();
} catch (FileNotFoundException nofile) {
nofile.printStackTrace();
} catch (IOException io) {
io.printStackTrace();
}
}
}
答案 0 :(得分:3)
这表示您正在阻止事件调度线程。这将阻止在您停止阻止之前更新任何UI元素。
只看了你的代码,我建议你的罪魁祸首就在这里......
while (total < totalToRead && !stopped) {
numBytesRead = fis.read(buffer, 0, numBytesToRead);
if (numBytesRead == -1)
break;
total += numBytesRead;
lineIn.write(buffer, 0, numBytesRead);
}
尝试创建一个后台线程,在其中运行Music
类或在其自己的后台线程中运行循环。
请查看Concurrency in Swing了解详情
更新了工作示例
这是一个相当粗略的例子。通常我会有一个Thread
负责播放音乐,但可以被打断并播放另一首歌,但这只是一个概念证明。
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.TargetDataLine;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestMusic {
public static void main(String[] args) {
new TestMusic();
}
public TestMusic() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
Music.play("/play/some/music/white/boy");
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JLabel("Look Ma, no hands"));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class Music {
public static void play(final String url) {
new Thread(new Runnable() {
@Override
public void run() {
new Music(url);
}
}).start();
}
private int total, totalToRead, numBytesRead, numBytesToRead;
private byte[] buffer;
private boolean stopped;
private AudioFormat wav;
private TargetDataLine line;
private SourceDataLine lineIn;
private DataLine.Info info;
private File file;
private FileInputStream fis;
public Music(String url) {
// AudioFormat(float sampleRate, int sampleSizeInBits,
// int channels, boolean signed, boolean bigEndian)
wav = new AudioFormat(44100, 16, 2, true, false);
info = new DataLine.Info(SourceDataLine.class, wav);
buffer = new byte[1024 * 333];
numBytesToRead = 1024 * 333;
total = 0;
stopped = false;
if (!AudioSystem.isLineSupported(info)) {
System.out.print("no support for " + wav.toString());
}
try {
// Obtain and open the line.
lineIn = (SourceDataLine) AudioSystem.getLine(info);
lineIn.open(wav);
lineIn.start();
fis = new FileInputStream(file = new File(url));
totalToRead = fis.available();
while (total < totalToRead && !stopped) {
numBytesRead = fis.read(buffer, 0, numBytesToRead);
if (numBytesRead == -1) {
break;
}
total += numBytesRead;
lineIn.write(buffer, 0, numBytesRead);
}
} catch (LineUnavailableException ex) {
ex.printStackTrace();
} catch (FileNotFoundException nofile) {
nofile.printStackTrace();
} catch (IOException io) {
io.printStackTrace();
}
}
}
}
答案 1 :(得分:2)
这是使用长时间运行的代码阻止Swing事件调度线程的典型示例。这将导致GUI冻结,因为线程不可用于绘制组件或与用户交互。解决方案:使用音乐的后台线程,这样就不会阻止GUI的事件线程。