/* * Copyright © 2013 Nokia Corporation. All rights reserved. * Nokia and Nokia Connecting People are registered trademarks of Nokia Corporation. * Oracle and Java are trademarks or registered trademarks of Oracle and/or its * affiliates. Other product and company names mentioned herein may be trademarks * or trade names of their respective owners. * See LICENSE.TXT for license information. */ package com.nokia.example.favouriteartists; import java.io.IOException; import java.util.Vector; import java.util.Random; import javax.microedition.lcdui.*; import com.nokia.example.favouriteartists.tool.Log; /** * This class controls the operation of the MIDlet, including command handling and view creation etc. */ public class Control implements CommandHandler, ImageProvider { // Constants /** Alert timeout in milliseconds. */ private static final int ALERT_TIMEOUT = 3000; /** Enabled value for the JAD attributes. */ public static final String ATTR_ENABLED = "true"; /** Images for testing purposes */ private static final String[] TEST_IMG_NAMES = { "midlets/favouriteartists/images/artist_1.png", "midlets/favouriteartists/images/artist_2.png", "midlets/favouriteartists/images/artist_3.png", "midlets/favouriteartists/images/artist_4.png", }; /** Comments for testing. */ private static final String[] COMMENTS = { "This artist sucks!", "This artist is bad.", "This artist is average.", "This artist is ok.", "This artist rocks!", }; // Inner classes /** * Data structure class for image cache **/ private class ImageData{ /** Filename of the image, used as identifier */ public String fileName; /** The image object */ public Image image; } // Member data /** Reference of the midlet class.*/ private FavouriteArtistsMIDlet mainApp; /** A <code>Display</code> object.*/ private Display display; /** Favourite artists view, main view of the app. */ private FavouriteArtistsView favouritesView; /** Image cache. */ private Vector imageCache; /** Artist data. */ private ArtistData[] artistDatas; /** Favourite data. */ private Vector favouriteDatas; // Methods /** * Constructor. * * @param app reference to the main midlet. */ public Control(FavouriteArtistsMIDlet app){ mainApp = app; } /** * Separate initialization function for convenience. */ public void initialize(){ if (Log.TEST) Log.note("[Control#initialize]-->"); display = Display.getDisplay(mainApp); imageCache = new Vector(); // Hard-coded artist data for testing purposes artistDatas = new ArtistData[50]; for (int i = 0; i < artistDatas.length; i++) { ArtistData artistData = new ArtistData(); artistData.setName("Artist " + i); artistData.setGenres(new String[]{"Genre " + i}); artistData.setShortDescription("Descr. " + i); artistData.setActiveMembers(new String[]{"Active members " + i}); artistData.setFormerMembers(new String[]{"Former members " + i}); artistData.setSignificantAlbums(new String[]{"Sgnf. albums " + i}); artistData.setSignificantSongs(new String[]{"Sgnf. songs " + i}); artistData.setSimilarArtists(new String[]{"Similar artists " + i}); String imageFileName = TEST_IMG_NAMES[i % TEST_IMG_NAMES.length]; artistData.setImageFileName(imageFileName); artistDatas[i] = artistData; } // Hard-coded favourite data for testing purposes favouriteDatas = new Vector(15); Random generator = new Random(); generator.setSeed(System.currentTimeMillis()); for (int i = 0; i < 15; i++) { FavouriteData favouriteData = new FavouriteData(artistDatas[i]); short rating = (short)generator.nextInt(4); favouriteData.setRating(rating); favouriteData.setComment(COMMENTS[rating]); favouriteDatas.addElement(favouriteData); } // Initialize main view try { favouritesView = new FavouriteArtistsView(this, display, this); } catch (FavouriteArtistsException e) { if (Log.TEST) Log.error("[Control#initialize] exception: " + e); return; } // Update main view updateFavouritesView(false); // Display main view display.setCurrent(favouritesView); } /** * Updates the favourites view with new data * * @param repaint If true, a repaint is initiated for the view. */ private void updateFavouritesView(boolean repaint){ if (Log.TEST) Log.note("[Control#updateFavouritesView]-->"); FavouriteData[] favArray = new FavouriteData[favouriteDatas.size()]; favouriteDatas.copyInto(favArray); favouritesView.updateView(favArray, repaint); } /** * Retrieves image from cache if already loaded or creates new image from file. * * @see ImageProvider#getImage(String) */ public Image getImage(String imageFilename){ if (Log.TEST) Log.note("[Control#getImage]-->"); if(imageFilename == null){ if (Log.TEST) Log.note("[Control#getImage] null param"); return null; } // Search for image for(int i = 0; i < imageCache.size(); i++){ ImageData imageData = (ImageData)imageCache.elementAt(i); if(imageFilename.equals(imageData.fileName)){ if (Log.TEST) Log.note("[Control#getImage] image found from cahce"); return imageData.image; } } // Create new image ImageData imgData = new ImageData(); try{ if (Log.TEST) Log.note("[Control#getImage] creating new image"); imgData.image = Image.createImage("/" + imageFilename); imgData.fileName = imageFilename; imageCache.addElement(imgData); } catch (IOException e) { if (Log.TEST) Log.error("[Control#getImage] Exception: " + e.getMessage()); } return imgData.image; } /** * Set a view to the current display. * * @param disp a view to set. */ public void setCurrent(Displayable disp){ if (display == null) display = Display.getDisplay(mainApp); display.setCurrent(disp); } /** * @see CommandListener#commandAction(Command, Displayable) */ public void commandAction(Command c, Displayable d) { if (Log.TEST) Log.note("[Control#commandAction]--> CommandListener"); ActionCommand ac = (ActionCommand) c; short actionId = ac.getActionId(); handleAction(actionId, null, d); } /** * @see ItemCommandListener#commandAction(Command, Item) */ public void commandAction(Command c, Item item) { if (Log.TEST) Log.note("[Control#commandAction]--> ItemCommandListener"); ActionCommand ac = (ActionCommand) c; short actionId = ac.getActionId(); handleAction(actionId, item, null); } /** * @see com.nokia.example.favouriteartists.CommandHandler#handleAction(short, Item, Displayable) */ public synchronized void handleAction(short actionId, Item item, Displayable view) { if (Log.TEST) Log.note("[Control#handleAction]-->"); switch(actionId) { case Actions.EXIT_MIDLET:{ if (Log.TEST) Log.note("[Control#handleAction] Actions.EXIT_MIDLET"); exitMidlet(); break; } case Actions.BACK:{ if (Log.TEST) Log.note("[Control#handleAction] Actions.BACK"); // Favourites view is always the view to go back to displayFavouritesView(); break; } case Actions.SHOW_RATING:{ if (Log.TEST) Log.note("[Control#handleAction] Actions.SHOW_RATING"); // Get selected item from the view. Should be valid during action handling. FavouriteData favData = favouritesView.getSelectedItem(); try { RatingView ratingView = new RatingView(favData, this, this); display.setCurrent(ratingView); } catch (FavouriteArtistsException e) { displayNote(null, "Operation failed!", AlertType.ERROR); } break; } case Actions.RATING_DONE:{ if (Log.TEST) Log.note("[Control#handleAction] Actions.RATING_DONE"); // Rating is done, get the fav data that needs to be changed. RatingView ratingView = (RatingView)view; FavouriteData favData = ratingView.getFavouriteData(); // Item in the Favourites view has reference to same object, so we can // modify it directly. favData.setName(ratingView.getName()); favData.setRating(ratingView.getRatingValue()); favData.setComment(ratingView.getComment()); displayFavouritesView(); break; } case Actions.SHOW_ADD_FAVOURITE:{ if (Log.TEST) Log.note("[Control#handleAction] Actions.SHOW_ADD_FAVOURITE"); // Open add fav view AddFavouriteView addFavView = null; try { addFavView = new AddFavouriteView(this, display, this, artistDatas); } catch (FavouriteArtistsException e) { displayNote(null, "Operation failed!", AlertType.ERROR); break; } display.setCurrent(addFavView); break; } case Actions.ADD_FAVOURITE:{ if (Log.TEST) Log.note("[Control#handleAction] Actions.ADD_FAVOURITE"); AddFavouriteView addFavView = (AddFavouriteView)view; // Get selected artist ArtistData artistData = addFavView.getSelectedItem().getData(); // Create a new favourite from the artist FavouriteData favData = new FavouriteData(artistData); // Set some default comment for the favourite, for testing purposes. favData.setComment(COMMENTS[favData.getRating()]); favouriteDatas.addElement(favData); // Update favourites view, needed because amount of items has changed. updateFavouritesView(false); displayFavouritesView(); break; } case Actions.REMOVE_FAVOURITE:{ if (Log.TEST) Log.note("[Control#handleAction] Actions.REMOVE_FAVOURITE"); RatingView ratingView = (RatingView)view; // Get the item and remove it FavouriteData favToRemove = ratingView.getFavouriteData(); favouriteDatas.removeElement(favToRemove); // Update favourites view, needed because amount of items has changed. updateFavouritesView(false); displayFavouritesView(); break; } case Actions.ARRANGE_FAVOURITES:{ arrangeFavourites(); updateFavouritesView(true); break; } } } /** * Show the main view. */ private void displayFavouritesView() { if (Log.TEST) Log.note("[Control#displayFavouritesView]-->"); display.setCurrent(favouritesView); } /** * Called when the user has chosen to exit the MIDlet or when * the MIDlet receives a <code>destroyApp()</code> call. */ public final void exitMidlet() { if (Log.TEST) Log.note("[Control#exitMidlet]-->"); mainApp.closeLogging(); mainApp.notifyDestroyed(); } /** * Displays an alert that times out after {@link #ALERT_TIMEOUT} milliseconds. * The shown alert has no command and it will not trigger any action. */ public void displayNote(String title, String msg, AlertType type) { Alert alert = new Alert(title, msg, null, type); alert.setTimeout(ALERT_TIMEOUT); displayAlert(alert); } /** * Display an alert. * * @param alert The alert to display. */ private void displayAlert(Alert alert) { try { display.setCurrent(alert, favouritesView); } catch (Exception e) { if (Log.TEST) Log.error("[Control#displayAlert] error:", e); } } /** * Arrange favourites by rating. */ private void arrangeFavourites(){ boolean swapped; do{ swapped = false; for( int i = 0; i <= favouriteDatas.size() - 2; i++){ FavouriteData element1 = (FavouriteData)favouriteDatas.elementAt(i); FavouriteData element2 = (FavouriteData)favouriteDatas.elementAt(i + 1); if( element1.rating < element2.rating ){ favouriteDatas.setElementAt(element2, i); favouriteDatas.setElementAt(element1, i + 1); swapped = true; } } } while (swapped == true); } }