Java - 在JButton Hover / Click / Released上播放声音

时间:2014-02-26 20:25:56

标签: java swing audio

我一直在使用Technic的源代码编写一个用于Minecraft的Launcher,我已经设法制作了一个非常漂亮的叉子。

为了使启动器更加独特,除了改变外观之外,我决定添加一个声音API,允许我在悬停/单击/释放按钮时播放* .wav,* .ogg文件在发射器中。我正在使用自己的组件,但它们扩展了Swing组件,因此我可以访问代码中的mouseClicked,mousePressed,mouseReleased,mouseEntered,mouseExited事件。

我已经看过几个向Java应用程序添加声音的不同示例,我试图调整它以适应我的应用程序。但没有运气。

这是AudioAPI类的源代码:

package uk.co.roguerage.launcher.main.ui.components.api;

import java.io.File;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;

public class AudioAPI {
    private AudioFormat audioFormat;
    private AudioInputStream audioInputStream;
    private SourceDataLine sourceDataLine;

    public void playAudio(File soundFile) {
        try {
            audioInputStream = AudioSystem.getAudioInputStream(soundFile);
            audioFormat = audioInputStream.getFormat();

            System.out.println(audioFormat);

            DataLine.Info dataLineInfo = new DataLine.Info(SourceDataLine.class, audioFormat);
            sourceDataLine = (SourceDataLine)AudioSystem.getLine(dataLineInfo);

            new PlayThread().start();
        } catch( Exception e ) {
            e.printStackTrace();
        }
    }

    class PlayThread extends Thread {
    byte tempBuffer[] = new byte[10000];

    public void run() {
        try {
            sourceDataLine.open(audioFormat);
            sourceDataLine.start();

            int cnt;

            while( (cnt = audioInputStream.read(tempBuffer,0,tempBuffer.length)) != -1 ) {
                if( cnt > 0 ) {
                    sourceDataLine.write(tempBuffer, 0, cnt);
                }
            }

            sourceDataLine.drain();
            sourceDataLine.close();
        } catch( Exception e ) {
            e.printStackTrace();
        }
    }
}

}

我使用以下代码调用API:

AudioAPI audioAPI = new AudioAPI();
audioAPI.playAudio(soundHover);

每当我将鼠标悬停在按钮上时,我似乎都会发现错误。这是错误:

[B#1] java.lang.NullPointerException
[B#1]   at com.sun.media.sound.SoftMidiAudioFileReader.getAudioInputStream(Unknown Source)
[B#1]   at javax.sound.sampled.AudioSystem.getAudioInputStream(Unknown Source)
[B#1]   at uk.co.roguerage.launcher.main.ui.components.api.AudioAPI.playAudio(AudioAPI.java:18)
[B#1]   at uk.co.roguerage.launcher.main.ui.components.LiteButton.mouseEntered(LiteButton.java:88)
[B#1]   at java.awt.AWTEventMulticaster.mouseEntered(Unknown Source)
[B#1]   at java.awt.Component.processMouseEvent(Unknown Source)
[B#1]   at javax.swing.JComponent.processMouseEvent(Unknown Source)
[B#1]   at java.awt.Component.processEvent(Unknown Source)
[B#1]   at java.awt.Container.processEvent(Unknown Source)
[B#1]   at java.awt.Component.dispatchEventImpl(Unknown Source)
[B#1]   at java.awt.Container.dispatchEventImpl(Unknown Source)
[B#1]   at java.awt.Component.dispatchEvent(Unknown Source)
[B#1]   at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
[B#1]   at java.awt.LightweightDispatcher.trackMouseEnterExit(Unknown Source)
[B#1]   at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
[B#1]   at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
[B#1]   at java.awt.Container.dispatchEventImpl(Unknown Source)
[B#1]   at java.awt.Window.dispatchEventImpl(Unknown Source)
[B#1]   at java.awt.Component.dispatchEvent(Unknown Source)
[B#1]   at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
[B#1]   at java.awt.EventQueue.access$000(Unknown Source)
[B#1]   at java.awt.EventQueue$3.run(Unknown Source)
[B#1]   at java.awt.EventQueue$3.run(Unknown Source)
[B#1]   at java.security.AccessController.doPrivileged(Native Method)
[B#1]   at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
[B#1]   at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
[B#1]   at java.awt.EventQueue$4.run(Unknown Source)
[B#1]   at java.awt.EventQueue$4.run(Unknown Source)
[B#1]   at java.security.AccessController.doPrivileged(Native Method)
[B#1]   at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
[B#1]   at java.awt.EventQueue.dispatchEvent(Unknown Source)
[B#1]   at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
[B#1]   at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
[B#1]   at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
[B#1]   at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
[B#1]   at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
[B#1]   at java.awt.EventDispatchThread.run(Unknown Source)

2 个答案:

答案 0 :(得分:1)

什么是soundHover指向?它说声音是空的,所以你确定你正确地调用了文件吗?

答案 1 :(得分:1)

我会在第audioInputStream = AudioSystem.getAudioInputStream(soundFile);行找到原因而开始验证文件是否正常(仅因为您创建了File对象并不意味着它与实际文件相关联),如果它指向文件系统中的REAL文件。更重要的是,每次将鼠标悬停在按钮上时,是否要从文件系统中读取文件?你不想将数据存储到内存中吗?