简体   繁体   中英

Java error: Cannot find symbol - but method is in the data type class

I receive the following error when trying to compile a Playlist class:

 Playlist.java:164: error: cannot find symbol
     head.data.play();
            ^
  symbol:   method play()
  location: variable data of type Music

Music data type class:

import java.net.MalformedURLException;
import java.net.URL;
import javazoom.jlgui.basicplayer.BasicPlayer;
import javazoom.jlgui.basicplayer.BasicPlayerException;

public class Music extends MediaData
{
// Data Fields
/** The name of the artist displayed */
private String artist;
/** The disk directory to a music file */
private String mediaFilePath;
/** Enables audio music to be played */
private BasicPlayer player = new BasicPlayer();

// Constructor for a music media type
public Music(String t, String a)
{
    super.setTitle(t);
    setArtist(a);
    getPlayCount();
    getMediaFilePath();
} 

// mutator and accessor methods removed for space

/** Locates the media file on disk */
public String getMediaFilePath()
{
    mediaFilePath = System.getProperty("user.dir") + "/Music Library/" +    
                                    getArtist() + "-" + getTitle() + ".mp3";
    return mediaFilePath;
}

/** Plays a music file */
public void play()
{
    try 
    {
        player.open(new URL("file:///" + getMediaFilePath()));
        player.play();
    } 
    catch (BasicPlayerException | MalformedURLException e)
    {
        e.printStackTrace();
    }
   }    
 }

The play method in this class works fine when tested in a driver program. However, when I try to access it from the play method in a Playlist class, where a Playlist is a double LinkedList with Music data type nodes, I get the error above:

import java.net.MalformedURLException;
import java.net.URL;
import javazoom.jlgui.basicplayer.BasicPlayer;
import javazoom.jlgui.basicplayer.BasicPlayerException;
import java.util.*;

public class Playlist<Music> extends MediaData
{
// Data fields
/** The playlist queue */
private LinkedList<Music> musicList;
/** The list head */
private Node<Music> head;


/** A Node is the building block for a single-linked list. */
private static class Node<Music> 
{

// Data Fields

/** The reference to the data. */
private Music data;
/** The reference to the next node. */
private Node<Music> next;
/** The reference to the previous node. */
private Node<Music> prev;

// Constructors
/**
* Creates a new node with null next and previous fields.
* @param dataItem The data stored
*/
private Node(Music dataItem)
{
     data = dataItem;
     next = null;
     prev = null;
}

/**
 * Creates a new node that references another node.
 * @param dataItem The data stored
 * @param nodeRef The node referenced by new node
 */
    private Node(Music dataItem, Node<Music> prevNode)
    {
        Node<Music> afterPrevNode = prevNode.next;
        Node<Music> node = new Node(dataItem);

        prevNode.next = node;
        prevNode.prev = node;

        node.prev = prevNode;
        node.next = afterPrevNode;
    }
} //end class Node

// Constructor
public Playlist(String t)
{
    super.setTitle(t);
    musicList = new LinkedList<Music>();
}

/**
 * Adds a new node to the end of a list.
 * @param head The head of the current list
 * @param data The data for the new node
 */
private void add(Node<Music> head, Music data) 
{
    // If the list has just one element, add to it.
    if (head.next == null) 
    {
        Node<Music> node = new Node<Music>(data);
        head.next = node;
        node.prev = head;
    } 
    else 
    {
        add(head.next, data);
    }
}

/**
 * Wrapper method for adding a new node to the end of a list.
 * @param data The data for the new node
 */
public void add(Music data) 
{
    if (head == null) 
    {
        head = new Node<Music>(data);
    } 
    else 
    {
        add(head, data);
    }
}

/**
 * Wrapper method for removing a node.
 * @post The first occurrence of outData is removed.
 * @param outData The data to be removed
 * @return true if the item is removed,
 *         and false otherwise
 */
public boolean remove(Music song)
{
    boolean result;
    if (head == null) 
    {
        result = false;
    } 
    else 
    {
        result = remove(head.next, head, song);
    }
    return result;
}

/**
 * Removes a node from a list.
 * @post The first occurrence of outData is removed.
 * @param head The head of the current list
 * @param pred The predecessor of the list head
 * @param outData The data to be removed
 * @return true if the item is removed
 *         and false otherwise
 */
private boolean remove(Node<Music> head, Node<Music> pred, Music song) 
{
    boolean result;
    if (head == null)
    {
        result = false;
    } 
    else if (head.data.equals(song)) 
    {
        pred.next = head.next;
        pred.prev = null;
        head = pred;
        result = true;
    } 
    else 
    {
        result = remove(head.next, head, song);
    }
    return result;
}

/** Plays a playlist
 *    @param head The song to be played */
private void play(Node<Music> head)
{
    if (head != null)
    {
         head.data.play();
         play(head.next);
    }
}

/** Wrapper method that plays a playlist */
public void play()
{
    if (head != null)
    {
         head.data.play();
         play(head.next);
    }
}

public void pause()
{

}

/**
 * Finds the size of a list.
 * @param head The head of the current list
 * @return The Size of the Current List
 */
private int size(Node<Music> head) 
{
    if (head == null) 
    {
        return 0;
    } 
    else 
    {
        return 1 + size(head.next);
    }
}

/**
 * Wrapper method for finding the size of a list.
 * @return The size of the list
 */
public int size() 
{
    return size(head);
}

/**
 * Returns the string representation of a list.
 * @param head The head of the current list
 * @return The state of the current list
 */
private String toString(Node<Music> head) 
{
    if (head == null) 
    {
        return "";
    } 
    else 
    {
        return head.data + "\n" + toString(head.next);
    }
}

/**
 * Wrapper method for returning the string representation of a list.
 * @return The string representation of the list
 */
@Override
public String toString() 
{
    return toString(head);
}

/**
* Checks if the list is empty
* @return true if empty, false otherwise
*/
public boolean empty()
{
    boolean result = false;
    if (head == null)
    {
    result = true;
    }
    return result;
}

/** Adds a node before another node.
    @param prevNode The node before node
    @param node The node the item will be inserted before
    @param item The data stored in the node
*/
public void insertBefore(Node prevNode, Music nodeData, Music data)
{            
    if (prevNode.next.data == nodeData)
    {
        Node<Music> prevPrevNode = prevNode.prev;
        Node<Music> node = new Node<Music>(data);

        prevPrevNode.next = node;
        prevNode.prev = node;

        node.prev = prevNode.prev;
        node.next = prevNode;
    }
    else
    {
        insertBefore(prevNode.next, nodeData, data); 
    }
}

/** Wrapper class that adds a node before another node.
    @param node The node the item will be inserted before
    @param item The data stored in the node
*/
public void insertBefore(Music nodeData, Music data)
{            
    if (nodeData == head.data)
    {
        addAtHead(data);
    }
    else
    {
        insertBefore(head.next, nodeData, data); 
    }
}

/** Adds a node after another node.
    @param head The head node
    @param nodeData The node the item will be inserted before
    @param data The data stored in the node
*/
public void insertAfter(Node head, Music nodeData, Music data)
{            
    if (nodeData == head.data)
    {
        Node<Music> node = new Node<Music>(data);
        Node<Music> afterHead = head.next;

        node.next = afterHead.next;
        head.next = node;
        node.prev = head;
        afterHead.prev = node;
    }
    else
    {
        insertAfter(head.next, nodeData, data); 
    }
}

/** Wrapper class that adds a node after another node.
    @param nodeData The node the item will be inserted after
    @param data The data stored in the node
*/
public void insertAfter(Music nodeData, Music data)
{
    insertAfter(head, nodeData, data); 
}

/** Adds a node to the front of the list
 *    @param head The front of the list
 *    @param Music The data added
 */
public void addAtHead(Music data)
{
    if (empty())
    {
        head = new Node<Music>(data);
    }
    else
    {
        Node<Music> node = head;
        head = new Node<Music>(data);
        head.next = node;
        node.prev = head;
    }
}

/** Adds a node to the list
 *    @param head The front of the list
 *    @param Music The data added
 */
public void addAtEnd(Node head, Music data)
{
    Node<Music> node;
    if (head.next == null)
    {
        node = new Node<Music>(data);
        head.next = node;
        node.prev = head;
    }
    else
    {
        node = head.next;
        addAtEnd(node, data);
    }
}

/** Wrapper method to add a node to the list
 *    @param Music The data added
 */
public void addAtEnd(Music data)
{
    if (empty())
    {
        head = new Node<Music>(data);
    }
    else
    {
        addAtEnd(head, data);
    }
}

/**
* Return the data of the first Node
* @return The data of the first Node
*/
public Music peekFront()
{
    Music m;
    if (empty()) 
    {
        m = null;
    } 
    else 
    {
        m = head.data;
    }
    return m;
}

/**
* Return the data of the last Node
* @return The data of the last Node
*/

public Music peekEnd(Node<Music> head)
{
    Music m;
    if (head.next != null)
    {
        Node<Music> node = head.next;
        peekEnd(node);
        m = node.data;
    }
    else
    {
        m = head.data;
    }

    return m;
}

/**
* Wrapper method for the data of the last Node
* @return The data of the last Node
*/

public Music peekEnd()
{
    Music m;
    if (head == null)
    {
        m = null;
    } 
    else 
    {
        m = peekEnd(head);
    }
    return m;
}

/** Remove the first node from the list
    @returns The data from the removed node, or null if the list is empty
*/
public Music removeFront()
{
    Music m = null;
    Node<Music> temp = head;
    Node<Music> afterHead = head.next;
    if (head != null)
    {
        m = temp.data;
        head = head.next;
        afterHead.prev = head;

    }
    return m;
}

/** Remove the last node from the list
 * @param head The head of the current list
 * @return The data from the removed node, or null if the list is empty
 */
public Music removeEnd(Node<Music> head)
{
    Music m;
    if (head.next != null)
    {
        Node<Music> node = head.next;
        removeEnd(node);
        m = node.data;
        node.next = null;
    }
    else
    {
        m = head.data;
        head = null;
    }

    return m;
 }

/**
 * Wrapper method for removing the last Node
 * @return The data from the removed node, or null if the list is empty
 */
public Music removeEnd()
{
    Music m;
    if (head == null)
    {
        m = null;
    } 
    else 
    {
        m = removeEnd(head);
    }
    return m;
 }

 } // End of class

There is a play method in the Music class, so I don't understand why I'm getting this error. A previous version (where the playlist was not implemented as a LinkedList) of this class did not have this issue. Please advise how to remedy

You first must get the Music object from the LinkedList.

 for(Music m: head.data)
 {
       m.play();
 }

or

 head.data.get(int index).play()

This is because in your Node class, Music is a template type parameter instead of a class name, and it's no difference from the usually used symbol T . You might get a "type parameter Music is hidding type Music" warnning there. The compiler doesn't know the class of the variable data is a object of class Music . You should remove <Music> of the Node class. You can write the Node class like this:

private static class Node
{

    // Data Fields

    /** The reference to the data. */
    private Music data;
    /** The reference to the next node. */
    private Node next;
    /** The reference to the previous node. */
    private Node prev;

    // Constructors
    /**
    * Creates a new node with null next and previous fields.
    * @param dataItem The data stored
    */
    private Node(Music dataItem)
    {
         data = dataItem;
         next = null;
         prev = null;
    }

/**
 * Creates a new node that references another node.
 * @param dataItem The data stored
 * @param nodeRef The node referenced by new node
 */
    private Node(Music dataItem, Node prevNode)
    {
        Node afterPrevNode = prevNode.next;
        Node node = new Node(dataItem);

        prevNode.next = node;
        prevNode.prev = node;

        node.prev = prevNode;
        node.next = afterPrevNode;
    }
} 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM