【问题标题】:JFrame doesn't show when music is playing?播放音乐时 JFrame 不显示?
【发布时间】:2013-06-12 01:59:02
【问题描述】:

我正在使用 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();
        }
    } 

}

【问题讨论】:

    标签: java swing audio concurrency event-dispatch-thread


    【解决方案1】:

    这表明您正在阻塞事件调度线程。这将阻止任何 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();
                }
            }
        }
    }
    

    【讨论】:

    • @AbhiUpadhyay:“我试过”告诉我们蹲下你实际做了什么。讲述并展示细节。
    • @HovercraftFullOfEels 我在我的音乐类中放了一个线程并在构造函数中启动它。抱歉没有具体说明。
    • @AbhiUpadhyay:你必须展示你做了什么。同样,您是在说“它不起作用”,但没有代码我们无法猜测原因。
    【解决方案2】:

    这是一个使用长时间运行的代码阻塞 Swing 事件调度线程的经典示例。这将导致 GUI 冻结,因为线程不可用于绘制组件或与用户交互。解决方案:为音乐使用后台线程,这样就不会阻塞 GUI 的事件线程。

    【讨论】:

    • @MadProgrammer:但你的更完整。 1+
    • @AbhiUpadhyay:有关于这个主题的章节和教程。你会想看看。从 MadProgrammer 答案中的链接开始。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-05
    • 2021-02-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多