Máquina de escrever - anexando sons ao arquivo Jar

Eu fiz uma “máquina de escrever” que emite o som das teclas ao digitar. Quando estou no NetBeans está funcionando bem. Mas quero fazer o jar, e quando gero o jar, ele não acessa o som… fica um bloco de notas comum…

Alguem sabe como fazer para o som ser anexado ao pacote? Segue o código da classe.

[code]package escritor;

/**
*

  • @author luciano santos
    /
    import java.awt.
    ;
    import java.awt.event.;
    import java.io.
    ;
    import java.util.logging.;
    import javax.sound.sampled.
    ;
    import javax.swing.*;

public class Escritor extends JFrame {

JTextArea txtPagina;
JScrollPane scrlGeral;
AudioInputStream sndDigito;
Clip clip;
Font King;
JButton btnContinuar, btnSalvar, btnNovo;
JMenuBar barra;
JMenu menuArquivo;
JMenuItem arqSair;
JPanel painel;
JTabbedPane pnlDoc;
JScrollPane scrlPainel;
ImageIcon icon = (null);
JFileChooser jFileChooser;
File som = new File("sound/tecla2.wav");
private boolean hasChanged = false; //Indica se o texto foi alterado
private static final String title = "Máquina de Escrever"; //Titulo da janela

public Escritor() {
    this.setTitle(title);
    this.setSize(810, 580);
    this.setLayout(null);
    this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); //Isso é pra não fechar
    this.setLocationRelativeTo(null);
    this.addWindowListener(new WindowAdapter() { //Listener pra tratar o fechamento

        @Override
        public void windowClosing(WindowEvent e) {
            doExit();
        }
    });

    barra = new JMenuBar();
    menuArquivo = new JMenu("Arquivo");
    arqSair = new JMenuItem("Sair");
    menuArquivo.add(arqSair);
    barra.add(menuArquivo);
    this.setJMenuBar(barra);

    arqSair.addActionListener(Sair);
    painel = new JPanel();
    painel.setLayout(null);
    painel.setBounds(0, 0, 840, 500);
    add(painel);

    getJButton();
    getSalvar();
    painel.add(btnContinuar);
    painel.add(btnSalvar);
    txtPagina = new JTextArea();
    txtPagina.setBounds(20, 20, 640, 480);
    txtPagina.setLineWrap(true);
    txtPagina.setBorder(BorderFactory.createLineBorder(Color.black));
    txtPagina.setFont(King = new Font("American Typewriter Medium BT", Font.BOLD, 16));
    painel.add(txtPagina);

    getJTextArea();
    scrlPainel = new JScrollPane(txtPagina);
    scrlPainel.setBounds(20, 20, 640, 480);
    painel.add(scrlPainel);

    txtPagina.addKeyListener(Digitar);
    txtPagina.requestFocus();
}

private JTextArea getJTextArea() {

    txtPagina.addKeyListener(new KeyAdapter() {

        @Override
        public void keyTyped(KeyEvent e) { //Detecta modificação e seta tbm
            if (!hasChanged) {
                setTitle(title + " *");
                hasChanged = true;
            }
        }
    });
    return txtPagina;
}

private JButton getSalvar() {
    btnSalvar = new JButton();
    btnSalvar.setText("Salvar");
    btnSalvar.setBounds(670, 60, 120, 30);
    btnSalvar.addActionListener(new java.awt.event.ActionListener() { //Listener pra salvar arquivo no clique do botão

        @Override
        public void actionPerformed(java.awt.event.ActionEvent e) {
            saveFile();
        }
    });
    return btnSalvar;
}

private JButton getJButton() {
    btnContinuar = new JButton();
    btnContinuar.setText("Abrir");
    btnContinuar.setBounds(670, 20, 120, 30);

    btnContinuar.addActionListener(new java.awt.event.ActionListener() { //Listener pra carregar arquivo no clique do botão

        @Override
        public void actionPerformed(java.awt.event.ActionEvent e) {
            loadFile();
        }
    });
    return btnContinuar;
}

private void loadFile() {
    int state = getJFileChooser().showOpenDialog(this); //chama janela pra selecionar arquivo
    if (state == JFileChooser.APPROVE_OPTION) { //verifica o status
        File f = getJFileChooser().getSelectedFile(); //pega o file selecionado na janela
        try { //Tenta ler o arquivo para o controle de texto
            FileReader fr = new FileReader(f); //cria o FileReader com o file previamente selecionado
            String temp = ""; //String temporaria

            int i = fr.read();
            while (i != -1) {
                temp += ((char) i);
                i = fr.read();
            }
            fr.close(); //fecha arquivo
            getJTextArea().setText(temp); //atribui temp ao controle
            setTitle(title); //seta o titulo pra remover o * se houver
            hasChanged = false; //Não alterado
        } catch (FileNotFoundException e) { //Não encontrou arquivo
            System.out.println("Erro - " + e);
        } catch (IOException e) { //Algum erro na leitura
            System.out.println("Erro - " + e);
        }
    }
}

private JFileChooser getJFileChooser() {
    if (jFileChooser == null) {
        jFileChooser = new JFileChooser();
        jFileChooser.setMultiSelectionEnabled(false);
    }
    return jFileChooser;
}

private void saveFile() {
    int state = getJFileChooser().showSaveDialog(this); //Abre dialogo pra selecionar
    if (state == JFileChooser.APPROVE_OPTION) { //se selecionou
        File f = getJFileChooser().getSelectedFile(); //pega file
        try {
            //tenta salvar      
            FileWriter fw = new FileWriter(f);
            //pega o texto do TextArea e envia pra stream no arquivo
            //A função write escreve uma string para o arquivo. Existem outras opções
            //a função write pode gerar IOException
            fw.write(getJTextArea().getText());
            fw.close();//fecha arquivo
            setTitle(title); //seta o titulo pra remover o * se houver
            hasChanged = false; //marca como não alterado
        } catch (FileNotFoundException e) { //Não encontrou o arquivo
        } catch (IOException e) { //Algum outro erro de io, não conseguiu gravar pois não tem permissão por exemplo
        }
    }
}

private void doExit() {
    if (hasChanged) {
        int state = JOptionPane.showConfirmDialog(this,
                "O Arquivo foi moficado. Quer salva antes de sair?");
        if (state == JOptionPane.YES_OPTION) {
            saveFile();
        } else if (state == JOptionPane.CANCEL_OPTION) {
            return;
        }
    }
    System.exit(0);
}
KeyListener Digitar = new KeyListener() {

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
        try {
            sndDigito = AudioSystem.getAudioInputStream(som);
        } catch (UnsupportedAudioFileException ex) {
            Logger.getLogger(Escritor.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Escritor.class.getName()).log(Level.SEVERE, null, ex);
        }

        // load the sound into memory (a Clip)
        DataLine.Info info = new DataLine.Info(Clip.class, sndDigito.getFormat());
        clip = null;
        try {
            clip = (Clip) AudioSystem.getLine(info);
        } catch (LineUnavailableException ex) {
            Logger.getLogger(Escritor.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            clip.open(sndDigito);
        } catch (LineUnavailableException ex) {
            Logger.getLogger(Escritor.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(Escritor.class.getName()).log(Level.SEVERE, null, ex);
        }
        // play the sound clip
        javax.swing.SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
            // due to bug in Java Sound, explicitly exit the VM when the sound has stopped.
            clip.addLineListener(new LineListener() {
            @Override
                    public void update(LineEvent event) {
                        if (event.getType() == LineEvent.Type.STOP) {
                            event.getLine().close();
                        }
                    }
                });
                clip.start();
            }
        });
    }
};
ActionListener Sair = new ActionListener() {

    @Override
    public void actionPerformed(ActionEvent click) {
        doExit();
    }
};

public static void main(String[] args) {
    Escritor maquina = new Escritor();
    maquina.setVisible(true);
    try {
        UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
    } catch (Exception exemp) {
        System.out.println("Erro - " + exemp);
    }
}

}[/code]

A linha Clip trabalha no máximo com 32 arquivos de sons por linha, acho melhor vc utilizar o SourceDataLine se tiver mais que 32 arquivos

A linha Clip trabalha no máximo com 32 arquivos de sons por linha, acho melhor vc utilizar o SourceDataLine se tiver mais que 32 arquivos