Odtwarzanie mp3 - jak zakończyć wątek?

0

Mam problem z zamknięciem lub zawieszeniem przed czasem wątku min. odtwarzającego mp3. Normalnie, bez obiektu player wyświetla w ramce tekst i wątek daje się zamknąć standardowo. Natomiast po dodaniu playera już nie. Jakby samo odtwarzanie było wątkiem całkowicie niezależnym... Oczywiście można temu zaradzić dodając linię player.close(). Ale interesuje mnie jak można zamknąć playera samym zamknięciem wątku. I dlaczego teraz tym kodem nie można tego zrobić. Poniżej 3 klasy :

 package rnest.Watki.pak4;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileNotFoundException;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

import javazoom.jl.decoder.JavaLayerException;

public class RamkaStandard extends JFrame{
    
    private Watek w;
    
    public RamkaStandard() throws FileNotFoundException, JavaLayerException{
        
        this.utworzRamke();
        
        
        Box box = Box.createVerticalBox();
        JTextArea pole = new JTextArea(15, 15);
        JScrollPane sp = new JScrollPane(pole);
        
        w = new Watek(pole);
        w.start();
        
        
        JButton klaw = new JButton("Przerwij");
        klaw.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent arg0) {
                // TODO Auto-generated method stub
                w.interrupt();
            }});
        
        box.add(sp);
        box.add(klaw);
        this.add(box);
        pack();
        
    }
    
    private void utworzRamke(){
        
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                // TODO Auto-generated method stub
                
                setSize(800, 600);
                setLocation(100, 50);
                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                setVisible(true);
                
                
            }});
        
    }

}

 package rnest.Watki.pak4;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import javax.swing.JOptionPane;
import javax.swing.JTextArea;

import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.Player;

public class Watek extends Thread{
    
    private JTextArea pole;
    private Player player;
    
    public Watek(JTextArea area) throws FileNotFoundException, JavaLayerException{
        pole = area;
        
        player = new Player(new FileInputStream(new File("D:\\crysis\\insertion.mp3")));
    }
    
    public void run(){
        int i = 0;
        while(!Thread.currentThread().isInterrupted()){
            
            i++;
            String wynik = "   Petla nr " + (i + 1) + "\n";
            pole.append(wynik);
            try {
                player.play();
            } catch (JavaLayerException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                
                return;
                
            }
            
            if(Thread.currentThread().isInterrupted())
                pole.append("Przerwano.");
            
        }
        
    }

}

package rnest.Watki.pak4;

import java.io.FileNotFoundException;

import javazoom.jl.decoder.JavaLayerException;

public class WatekBody {

    public static void main(String[] args) throws FileNotFoundException, JavaLayerException {
        // TODO Auto-generated method stub
        
        new RamkaStandard();
        
    }

}

 

Biblioteka JLayer w załączniku.

0

Zamiast

w.interrupt()

mógłbyś użyć w.stop()

, co rzeczywiście zatrzyma twój wątek.

W poniższym linku jest jednak wyjaśnione, dlaczego nie powinno się tak robić oraz prawidłowe rozwiązanie tego problemu:
http://docs.oracle.com/javase/1.5.0/docs/guide/misc/threadPrimitiveDeprecation.html
0

Artykuł ciekawy. Owszem w.stop() stopuje wątek. Ale metoda stop() jest zdeprecjonowana jako potencjalnie szkodliwa.
Natomiast poniższy kod(z treści artykułu) wywołuje błąd IllegalMonitorStateException ...

 package rnest.Watki.pak4;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

import javazoom.jl.decoder.JavaLayerException;
import javazoom.jl.player.Player;

public class RamkaStandard extends JFrame{
    
    private volatile Thread w;
    private Player player;
    private FileInputStream soket;
    private volatile boolean zawies;
    
    public RamkaStandard() throws FileNotFoundException, JavaLayerException{
        
        this.utworzRamke();
        soket = new FileInputStream(new File("D:\\crysis\\insertion.mp3"));
        player = new Player(soket);
        zawies = false;
        Box box = Box.createVerticalBox();
        JTextArea pole = new JTextArea(15, 15);
        JScrollPane sp = new JScrollPane(pole);
        
        w = new Thread(new Runnable(){
            @Override
            public void run() {
                // TODO Auto-generated method stub
                
                try{
                    
                    while (true) {
                        try {
                            
                            Thread.sleep(10);
                            player.play();

                            if (zawies) {
                                synchronized(this) {
                                    while (zawies)
                                        wait();
                                }
                            }
                        } catch (InterruptedException e){
                        }
                        
                    }
                    
                }catch(Exception e){
                    
                }
                
            }});
        
        w.start();
        
        JButton klaw = new JButton("Przerwij");
        klaw.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent a) {
                // TODO Auto-generated method stub
            
                zawies = true;
                if(zawies){
                    notify();
                }
                
            }});
        
        box.add(sp);
        box.add(klaw);
        this.add(box);
        pack();
        
    }
    
    private void utworzRamke(){
        
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                // TODO Auto-generated method stub
                
                setSize(800, 600);
                setLocation(100, 50);
                setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                setVisible(true);
                
                
            }});
        
    }

}

Można jeszcze zamknąć FileInputStream - soket.close(). I obsłużyć błąd, który wtedy powstaje...
Bardziej zależałoby mi na zawieszaniu wątku. Można wtedy użyć takiego wątku w programie do odtwarzania mp3 jako funkcji pauzowania. Natomiast z samym zatrzymaniem odtwarzania w JLayer nie ma problemu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1