/*
* Jajuk
* Copyright (C) The Jajuk Team
* http://jajuk.info
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
package org.jajuk.ui.views;
import ext.services.lastfm.ArtistInfo;
import ext.services.lastfm.LastFmService;
import java.awt.Dimension;
import java.awt.Insets;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
import org.apache.commons.lang.StringUtils;
import org.jajuk.base.Artist;
import org.jajuk.events.JajukEvent;
import org.jajuk.events.JajukEvents;
import org.jajuk.events.ObservationManager;
import org.jajuk.services.players.QueueModel;
import org.jajuk.services.players.StackItem;
import org.jajuk.ui.helpers.TwoStepsDisplayable;
import org.jajuk.ui.thumbnails.LastFmArtistThumbnail;
import org.jajuk.util.Conf;
import org.jajuk.util.Const;
import org.jajuk.util.Messages;
import org.jajuk.util.UtilFeatures;
import org.jajuk.util.UtilGUI;
import org.jajuk.util.log.Log;
import org.jdesktop.swingx.JXBusyLabel;
/**
* Display Artist bio and albums.
*/
public class ArtistView extends SuggestionView implements TwoStepsDisplayable {
/** Generated serialVersionUID. */
private static final long serialVersionUID = 1L;
/** The artist picture + labels. */
private LastFmArtistThumbnail artistThumb;
/** The artist bio (from last.fm wiki) */
private JTextArea jtaArtistDesc;
private JScrollPane jspAlbums;
private String bio;
private ArtistInfo artistInfo;
/*
* (non-Javadoc)
*
* @see org.jajuk.ui.views.IView#getDesc()
*/
@Override
public String getDesc() {
return Messages.getString("ArtistView.0");
}
/*
* (non-Javadoc)
*
* @see org.jajuk.ui.views.IView#initUI()
*/
@Override
public void initUI() {
// register to player events
ObservationManager.register(this);
// by default, show reseted view
reset();
// Update initial status
UtilFeatures.updateStatus(this);
}
/*
* (non-Javadoc)
*
* @see org.jajuk.events.Observer#getRegistrationKeys()
*/
@Override
public Set<JajukEvents> getRegistrationKeys() {
Set<JajukEvents> eventSubjectSet = new HashSet<JajukEvents>();
eventSubjectSet.add(JajukEvents.WEBRADIO_LAUNCHED);
eventSubjectSet.add(JajukEvents.ZERO);
eventSubjectSet.add(JajukEvents.FILE_LAUNCHED);
return eventSubjectSet;
}
/**
* Build the GUI for a given artist
* <p>
* Must be called from the EDT
* </p>.
*/
private void displayArtist() {
UtilGUI.populate(this);
}
/*
* (non-Javadoc)
*
* @see org.jajuk.events.Observer#update(org.jajuk.events.JajukEvent)
*/
@Override
public void update(final JajukEvent event) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
// If internet access or lastfm is disable, just reset
if (Conf.getBoolean(Const.CONF_NETWORK_NONE_INTERNET_ACCESS)
|| !Conf.getBoolean(Const.CONF_LASTFM_INFO)) {
reset();
return;
}
JajukEvents subject = event.getSubject();
if (JajukEvents.WEBRADIO_LAUNCHED.equals(subject)
|| JajukEvents.ZERO.equals(event.getSubject())) {
reset();
} else if (JajukEvents.FILE_LAUNCHED.equals(subject)) {
// If no playing track, reset the view
StackItem currentItem = QueueModel.getCurrentItem();
if (currentItem == null) {
reset();
return;
}
Artist artist = currentItem.getFile().getTrack().getArtist();
// If we already display the artist, leave
if (artist.getName().equals(ArtistView.this.artist)) {
return;
} else {
// Display a busy panel in the mean-time
setLayout(new MigLayout("ins 5", "[grow]", "[grow]"));
JXBusyLabel busy1 = new JXBusyLabel(new Dimension(50, 50));
busy1.setBusy(true);
removeAll();
add(busy1, "center");
revalidate();
repaint();
ArtistView.this.artist = artist.getName();
// Display the panel only if the artist is not unknown
if (!artist.seemsUnknown()) {
// This is done in a swing worker
displayArtist();
} else {
reset();
}
}
}
}
});
}
/* (non-Javadoc)
* @see org.jajuk.ui.views.SuggestionView#onPerspectiveSelection()
*/
@Override
public void onPerspectiveSelection() {
// override the suggestion view behavior
}
/**
* Show reseted view (show a message)
* <p>
* Must be called from the EDT
* </p>.
*/
private void reset() {
ArtistView.this.artist = null;
removeAll();
setLayout(new MigLayout("ins 5,gapy 5", "[grow]"));
add(getNothingFoundPanel());
revalidate();
repaint();
}
/*
* (non-Javadoc)
*
* @see org.jajuk.ui.helpers.TwoStepsDisplayable#longCall()
*/
@Override
public Object longCall() {
// Call last.fm wiki
bio = LastFmService.getInstance().getWikiText(artist);
artistInfo = LastFmService.getInstance().getArtist(artist);
// Prefetch artist thumbs
try {
preFetchOthersAlbum();
preFetchSimilarArtists();
} catch (UnknownHostException e) {
Log.warn("Could not contact host for loading album information: {{" + e.getMessage() + "}}");
} catch (IOException e) {
if (e.getMessage().contains(" 403 ")) {
// server responded with code "forbidden"
Log.warn("Server returned an error while fetching images: " + e.getMessage());
} else {
// other exception
Log.error(e);
}
} catch (Exception e) {
Log.error(e);
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.jajuk.ui.helpers.TwoStepsDisplayable#shortCall(java.lang.Object)
*/
@Override
public void shortCall(Object in) {
removeAll();
jspAlbums = getLastFMSuggestionsPanel(SuggestionType.OTHERS_ALBUMS, true);
// Artist unknown from last.fm, leave
if (artistInfo == null
// If image url is void, last.fm doesn't provide enough data about this
// artist, we reset the view
|| StringUtils.isBlank(artistInfo.getImageUrl())) {
reset();
return;
}
artistThumb = new LastFmArtistThumbnail(artistInfo);
// No known icon next to artist thumb
artistThumb.setArtistView(true);
artistThumb.populate();
jtaArtistDesc = new JTextArea(bio) {
private static final long serialVersionUID = 9217998016482118852L;
// We set the margin this way, setMargin() doesn't work due to
// existing border
@Override
public Insets getInsets() {
return new Insets(2, 4, 0, 4);
}
};
jtaArtistDesc.setBorder(null);
jtaArtistDesc.setEditable(false);
jtaArtistDesc.setLineWrap(true);
jtaArtistDesc.setWrapStyleWord(true);
jtaArtistDesc.setOpaque(false);
JScrollPane jspWiki = new JScrollPane(jtaArtistDesc);
jspWiki.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
jspWiki.setBorder(null);
jspWiki.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
// Add items, layout is different according wiki text availability
if (StringUtils.isNotBlank(jtaArtistDesc.getText())) {
setLayout(new MigLayout("ins 5,gapy 5", "[grow]", "[grow][20%!][grow]"));
add(artistThumb, "center,wrap");
// don't add the textarea if no wiki text available
add(jspWiki, "growx,wrap");
add(jspAlbums, "grow,wrap");
} else {
setLayout(new MigLayout("ins 5,gapy 5", "[grow]"));
add(artistThumb, "center,wrap");
// don't add the textarea if no wiki text available
add(jspAlbums, "grow,wrap");
}
revalidate();
repaint();
}
}