0

私は 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();
        }
    } 

}
4

2 に答える 2

3

これは、イベント ディスパッチ スレッドをブロックしていることを示しています。これにより、ブロックを停止するまで UI 要素が更新されなくなります。

あなたのコードだけを見たので、あなたの犯人はここにいると思います...

while (total < totalToRead && !stopped) {
    numBytesRead = fis.read(buffer, 0, numBytesToRead);
    if (numBytesRead == -1)
    break;
    total += numBytesRead;
    lineIn.write(buffer, 0, numBytesRead);
}

Musicクラスを実行するか、独自のバックグラウンド スレッド内でループを実行するバックグラウンド スレッドを作成してみてください。

詳細については、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();
            }
        }
    }
}
于 2013-06-12T02:01:53.707 に答える
2

これは、実行時間の長いコードで Swing イベント ディスパッチ スレッドをブロックする典型的な例です。これにより、スレッドがコンポーネントの描画やユーザーとの対話に使用できなくなるため、GUI がフリーズします。解決策: 音楽のバックグラウンド スレッドを使用して、GUI のイベント スレッドをブロックしないようにします。

于 2013-06-12T02:01:39.817 に答える