0

I'm trying to write a simple music player on Java. Everything had worked fine until I tried to add a new function with the JSlider. I wasn't running the program from Main, but from the Replayer class (see in the code below). I wanted the track's position to move according to the slider, but the timer that I added worked too fast and it didn't let me do that. I tried running from the main file and got the error that I've mentioned in the title. Here's Main:

import javax.sound.sampled.\*;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
public class Main {
public static void main(String\[\] args) throws UnsupportedAudioFileException, LineUnavailableException, IOException {
new Replayer();
}
}

Here's the Replayer class:

import javax.sound.midi.Track;
import javax.sound.sampled.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.event.*;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

public class Replayer extends JFrame{
    long mspos = 0;
    int selected_track = 0;
    protected JPanel Calculator;
    protected JTextField textDisplay;
    protected JButton PlayButton;
    protected JButton StopButton;
    protected JButton PauseButton;
    protected JButton Next;
    protected JButton Prev;
    protected JSlider TrackProgress;
    public Replayer() throws UnsupportedAudioFileException, IOException, LineUnavailableException {
        File folder = new File("music");
        File[] files = folder.listFiles((dir, name) -> name.toLowerCase().endsWith(".wav"));
        assert files != null;
        AudioInputStream[] audioStream = new AudioInputStream[files.length];
        Clip[] clips = new Clip[files.length];
        for(int i = 0; i < files.length; i++){
            audioStream[i] = AudioSystem.getAudioInputStream(files[i]);
            clips[i] = AudioSystem.getClip();
            clips[i].open(audioStream[i]);
        }
        TrackProgress.setValue(0);
        TrackProgress.setMaximum(1000000);
        textDisplay.setText(files[selected_track].getName());

        final Timer[] timer = {new Timer()};

        TimerTask task = new TimerTask(){
            @Override
            public void run() {
                int curpos = (int) ((1.0 * clips[selected_track].getMicrosecondPosition() / clips[selected_track].getMicrosecondLength()) * 1000000);
                if(curpos != TrackProgress.getValue()){
                    TrackProgress.setValue(curpos);
                }
            }
        };
        timer[0].scheduleAtFixedRate(task, 0, 1);

        PlayButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(clips[selected_track].getMicrosecondPosition() == clips[selected_track].getMicrosecondLength()){
                    mspos = 0;
                }
                clips[selected_track].setMicrosecondPosition(mspos);
                clips[selected_track].start();
                textDisplay.setText(files[selected_track].getName());
            }
        });

        StopButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                mspos = 0;
                clips[selected_track].stop();
                clips[selected_track].setMicrosecondPosition(0);
                TrackProgress.setValue(0);
            }
        });

        PauseButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                clips[selected_track].stop();
                mspos = clips[selected_track].getMicrosecondPosition();
            }
        });

        Next.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(selected_track == files.length - 1){
                    textDisplay.setText("Error: this is the last track");
                }else{
                    TrackProgress.setValue(0);
                    clips[selected_track].stop();
                    selected_track++;
                    textDisplay.setText(files[selected_track].getName());
                    mspos = 0;
                }
            }
        });

        Prev.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(selected_track < 1){
                    textDisplay.setText("Error: this is the first track");
                }else{
                    TrackProgress.setValue(0);
                    clips[selected_track].stop();
                    selected_track--;
                    textDisplay.setText(files[selected_track].getName());
                    mspos = 0;
                }
            }
        });


        TrackProgress.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                super.mousePressed(e);
                clips[selected_track].stop();
                //timer[0].cancel();
                //timer[0] = new Timer();
            }
            public void mouseReleased(MouseEvent e) {
                super.mouseReleased(e);
                mspos = (long) ((1.0 * TrackProgress.getValue()) / 1000000 * clips[selected_track].getMicrosecondLength());
                clips[selected_track].setMicrosecondPosition(mspos);
                clips[selected_track].start();
                //timer[0] = new Timer();
                //timer[0].scheduleAtFixedRate(task, 0, 1);
            }
        });

        JFrame frame = new JFrame("Replayer");
        frame.setContentPane(new Replayer().Calculator);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setResizable(false);
        frame.pack();
        frame.setVisible(true);
    }
    
}

I don't really know what to do, I have very little experience with Java

6
  • if you have very little experience with java, you should first focus on learning Java. You claim that when you start the app from the Replayer class, you don't get this problem, but the Replayer class has no main method, meaning with the code you've shown, you can't start it from there. Commented Oct 5, 2023 at 6:38
  • forgot to mention, I had "Replayer extends Main" at first Commented Oct 5, 2023 at 6:53
  • with for the rest the same code as now? why exactly does it extend JFrame now? Commented Oct 5, 2023 at 6:55
  • pretty much yeah, except for the Frame section at the end which was originally in Main Commented Oct 5, 2023 at 6:56
  • 3
    The exception is thrown in exactly two places (github.com/openjdk/jdk17u/blob/master/src/java.desktop/share/…, github.com/openjdk/jdk17u/blob/master/src/java.desktop/share/…) and in both places it happens because the JVM has insufficient memory to allocate byte arrays. Maybe you are just trying to load too many audio streams at the same time. Do you really need to open all files at once? Commented Oct 5, 2023 at 7:36

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.