cc.pinel.mangue.ui.ChaptersPanel.java Source code

Java tutorial

Introduction

Here is the source code for cc.pinel.mangue.ui.ChaptersPanel.java

Source

/*
 * Copyright 2014 Roque Pinel
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cc.pinel.mangue.ui;

import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URL;
import java.util.NoSuchElementException;

import org.apache.commons.io.IOUtils;
import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.kwt.ui.KWTSelectableLabel;

import cc.pinel.mangue.Main;
import cc.pinel.mangue.handler.ConnectivityHandler;
import cc.pinel.mangue.handler.StorageHandler;
import cc.pinel.mangue.model.Chapter;
import cc.pinel.mangue.model.Manga;
import cc.pinel.mangue.storage.GeneralStorage;
import cc.pinel.mangue.storage.StateStorage;
import cc.pinel.mangue.util.StringUtils;

import com.amazon.kindle.kindlet.event.KindleKeyCodes;
import com.amazon.kindle.kindlet.ui.KBoxLayout;
import com.amazon.kindle.kindlet.ui.KLabel;
import com.amazon.kindle.kindlet.ui.KPages;
import com.amazon.kindle.kindlet.ui.KPanel;
import com.amazon.kindle.kindlet.ui.pages.LocationIterator;
import com.amazon.kindle.kindlet.ui.pages.PageProviders;

/**
 * The panel to displays a manga chapters.
 * 
 * @author Roque Pinel
 *
 */
public class ChaptersPanel extends KPanel {
    private static final long serialVersionUID = 7836204925749827794L;

    private final Main main;

    private final KPages chaptersPages;

    private final ChapterLabelActionListener chapterListener;

    private Manga manga = null;

    /**
     * @param main the main controller
     * @param manga the manga
     */
    public ChaptersPanel(Main main, Manga manga) {
        super(new GridBagLayout());

        this.main = main;

        chaptersPages = new KPages(PageProviders.createKBoxLayoutProvider(KBoxLayout.Y_AXIS));
        chaptersPages.setFocusable(true);
        chaptersPages.setEnabled(true);
        chaptersPages.setPageKeyPolicy(KPages.PAGE_KEYS_LOCAL);

        chapterListener = new ChapterLabelActionListener();

        GridBagConstraints gc = new GridBagConstraints();
        gc.gridx = 0;
        gc.gridy = 0;
        gc.insets = new Insets(20, 20, 20, 20);
        gc.anchor = GridBagConstraints.NORTH;
        gc.weightx = 1.0;
        gc.weighty = 1.0;
        gc.fill = GridBagConstraints.BOTH;

        add(chaptersPages, gc);

        chaptersPages.first();

        loadChapters(manga);
    }

    /**
     * {@inheritDoc}
     */
    public void requestFocus() {
        try {
            ((Component) chaptersPages.getPageModel().getElementAt(0)).requestFocus();
        } catch (NoSuchElementException e) {
            chaptersPages.requestFocus();
        }
    }

    /**
     * Loads all chapters from the given manga.
     * 
     * @param manga the manga
     */
    public void loadChapters(final Manga manga) {
        if (this.manga != null && this.manga.getId().equals(manga.getId()))
            return;

        this.manga = manga;
        rememberManga();

        new StorageHandler(main.getContext(), "Loading mangas...") {
            /**
             * {@inheritDoc}
             */
            public void handleRun() throws Exception {
                final String lastChapterNumber = new StateStorage(main.getContext()).getChapter(manga.getId());

                final ConnectivityHandler handler = new ConnectivityHandler(main.getContext(),
                        "Loading chapters...") {
                    /**
                     * {@inheritDoc}
                     */
                    public void handleConnected() throws Exception {
                        JSONParser parser = new JSONParser();
                        JSONArray chapters = (JSONArray) parser
                                .parse(IOUtils.toString(new URL(manga.getAllChaptersLink()).openStream()));

                        chaptersPages.removeAllItems();
                        for (int i = chapters.size() - 1; i >= 0; i--) {
                            JSONObject chapter = (JSONObject) chapters.get(i);
                            String chapterNumber = chapter.get("chapter").toString();
                            String chapterName = StringUtils.unescapeHtml(chapter.get("chapter_name").toString());
                            String chapterTitle = chapterNumber
                                    + (chapterName != null && chapterName.length() != 0 ? ": " + chapterName : "");

                            final KWTSelectableLabel chapterLabel = new KWTSelectableLabel(chapterTitle);
                            chapterLabel.setName(chapterNumber);
                            chapterLabel.setFocusable(true);
                            chapterLabel.setEnabled(true);
                            chapterLabel.addActionListener(chapterListener);

                            // last read chapter
                            if (lastChapterNumber != null && chapterNumber.equals(lastChapterNumber))
                                highlightLabel(chapterLabel);

                            chaptersPages.addItem(chapterLabel);
                        }

                        EventQueue.invokeAndWait(new Runnable() {
                            public void run() {
                                chaptersPages.first();

                                requestFocus();
                                repaint();
                            }
                        });
                    }
                };

                main.getContext().getConnectivity().submitSingleAttemptConnectivityRequest(handler, true);
            }
        }.start();
    }

    /**
     * Updates the last chapter highlight when
     * the user selects a new chapter to read.
     * 
     * @param lastChapterNumber the last chapter number
     */
    private void updateLastChapter(String lastChapterNumber) {
        for (LocationIterator iter = chaptersPages.getPageModel().locationIterator(-1, true); iter.hasNext();) {
            final KWTSelectableLabel chapterLabel = (KWTSelectableLabel) iter.next();
            if (lastChapterNumber != null && chapterLabel.getName().equals(lastChapterNumber))
                highlightLabel(chapterLabel);
            else
                unhighlightLabel(chapterLabel);
        }
    }

    /**
     * Handles the panel actions.
     * 
     * Basically, when a chapter is selected.
     * 
     * @author Roque Pinel
     *
     */
    private class ChapterLabelActionListener implements ActionListener {
        /**
         * {@inheritDoc}
         */
        public void actionPerformed(ActionEvent event) {
            if (Integer.parseInt(event.getActionCommand()) == KindleKeyCodes.VK_FIVE_WAY_SELECT) {
                String chapterNumber = ((KWTSelectableLabel) event.getSource()).getName();

                updateLastChapter(chapterNumber);
                rememberChapter(chapterNumber);

                Chapter chapter = new Chapter(chapterNumber, manga.getChapterLink(chapterNumber));
                ViewPanel viewPanel = main.getViewPanel();
                if (viewPanel == null)
                    main.setViewPanel(new ViewPanel(main, chapter));
                else
                    viewPanel.loadImage(chapter);
                main.paintViewPanel();
            }
        }

        /**
         * Remembers the chapter to be able to
         * restore it in the future.
         * 
         * @param chapterNumber the chapter number
         */
        private void rememberChapter(final String chapterNumber) {
            new StorageHandler(main.getContext(), "Loading mangas...") {
                /**
                 * {@inheritDoc}
                 */
                public void handleRun() throws Exception {
                    new StateStorage(main.getContext()).setChapter(manga.getId(), chapterNumber);
                }
            }.start();
        }
    }

    /**
     * Remembers the current manga to be able to
     * restore it in the future.
     */
    private void rememberManga() {
        new GeneralStorage(main.getContext()).setCurrentMangaId(manga.getId());
    }

    /**
     * Highlights the label.
     * 
     * @param label the chapter label
     */
    private void highlightLabel(KLabel label) {
        Font font = label.getFont();
        label.setFont(new Font(font.getFamily(), Font.BOLD, font.getSize()));
        label.setForeground(new Color(255, 84, 84));
    }

    /**
     * Unhighlights the label.
     * 
     * @param label the chapter label
     */
    private void unhighlightLabel(KLabel label) {
        Font font = label.getFont();
        label.setFont(new Font(font.getFamily(), Font.PLAIN, font.getSize()));
        label.setForeground(Color.BLACK);
    }
}