Java tutorial
/* State_Home.java Copyright (C) 2014 Shun ITO <movingentity@gmail.com> This file is part of Green Feed Reader. Green Feed Reader 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 (at your option) any later version. Green Feed Reader 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 Green Feed Reader. If not, see <http://www.gnu.org/licenses/>. */ package mypackage; import java.util.Enumeration; import java.util.Hashtable; import java.util.Vector; import org.json.me.JSONArray; import org.json.me.JSONException; import org.json.me.JSONObject; import net.rim.device.api.command.Command; import net.rim.device.api.command.CommandHandler; import net.rim.device.api.command.ReadOnlyCommandMetadata; import net.rim.device.api.ui.TransitionContext; import net.rim.device.api.ui.Ui; import net.rim.device.api.ui.UiApplication; import net.rim.device.api.ui.UiEngineInstance; import net.rim.device.api.ui.component.Dialog; import net.rim.device.api.ui.component.table.RichList; public class State_Home implements State_Base { private FeedlyClient _feedlyclient = null; private FeedlyAPI _feedlyapi = null; private Screen_Home _screen = null; private Vector categories = null; public State_Home(FeedlyClient feedlyclient) { this._feedlyclient = feedlyclient; this._feedlyapi = feedlyclient.getFeedlyAPI(); // // XN?[gWV? // // FADE IN TransitionContext transIN = new TransitionContext(TransitionContext.TRANSITION_FADE); transIN.setIntAttribute(TransitionContext.ATTR_DURATION, 100); // SET UiEngineInstance engine = Ui.getUiEngineInstance(); engine.setTransition(null, _screen, UiEngineInstance.TRIGGER_PUSH, transIN); // FADE OUT TransitionContext transOUT = new TransitionContext(TransitionContext.TRANSITION_FADE); transOUT.setIntAttribute(TransitionContext.ATTR_DURATION, 100); transOUT.setIntAttribute(TransitionContext.ATTR_KIND, TransitionContext.KIND_OUT); // SET engine.setTransition(_screen, null, UiEngineInstance.TRIGGER_POP, transOUT); } public void enter() { //updateStatus("enter()"); //updateStatus("[AT] " + _feedlyclient.getAccessToken()); //updateStatus("[RT] " + _feedlyclient.getRefreshToken()); //updateStatus("[EI] " + _feedlyclient.getExpiresIn()); //updateStatus("[UD] " + _feedlyclient.getUpdate()); // Feedly?OC???AAuthXeCg?X if (!_feedlyclient.isLogin()) { _feedlyclient.changeState(new State_Auth(_feedlyclient)); return; } // HomeXN?[\ if (_screen == null) { _screen = new Screen_Home(this); } _feedlyclient.pushScreen(_screen); // // ?wtB?[h // // ???A?V?B if (categories != null) { return; } // L?MoHmF if (Network.isCoverageSufficient()) { new Thread() { public void run() { try { // ANeBreBCWP?[^?[\ _screen.showActivityIndicator(); // ?wtB?[h JSONArray subscriptions = _feedlyapi.getUserSubscriptions(); // tB?[hJeS categories = doCategorize(subscriptions); // tB?[hXN?[?B for (Enumeration e = categories.elements(); e.hasMoreElements();) { Category tmp_category = (Category) e.nextElement(); tmp_category.doAddCategoryRichList(); } _screen.setFocusToStartPos(); // unread?Aupdated?X?V?B refreshUnreadCounts(); } catch (Exception e) { // G?[?MO updateStatus("enter() " + e.toString()); // ??s???AAv??I UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { //Dialog.alert("An unexpected error occurred."); //_feedlyclient.quitApp(); int select = Dialog.ask("An unexpected error occurred.", new Object[] { "Try again", "Quit", "Show error log" }, 0); switch (select) { case Dialog.CANCEL: _feedlyclient.quitApp(); break; case 0: _feedlyclient.forceLogoutFeedly(); break; case 1: _feedlyclient.quitApp(); break; case 2: showLog(); break; } } }); } finally { // ANeBreBCWP?[^?[?? _screen.deleteActivityIndicator(); } } //run() }.start(); //Thread() // L?MoH?? } else { UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { int select = Dialog.ask( "A communication error has occurred. Please make sure your device is connected to Internet.", new Object[] { "Try again", "Quit" }, 0); switch (select) { case Dialog.CANCEL: _feedlyclient.quitApp(); break; case 0: _feedlyclient.reStartApp(); break; case 1: _feedlyclient.quitApp(); break; } } //run() }); } //if() } //enter() public void exit() { //updateStatus("exit()"); if (_screen != null) { _feedlyclient.popScreen(_screen); } } public void pushHomeScreen() { // foOp _feedlyclient.pushScreen(_screen); } public void close() { if (categories != null) { categories.removeAllElements(); categories = null; } _feedlyclient.quitApp(); } public void showLog() { UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { _feedlyclient.popScreen(_screen); _feedlyclient.showLogField(); } }); } public Command CMD_changeStateToAll() { Command out = new Command(new CommandHandler() { public void execute(ReadOnlyCommandMetadata metadata, Object context) { _feedlyclient.changeState(new State_Stream(_feedlyclient, "user/" + _feedlyclient.getID() + "/category/global.all", "ALL", true)); } //execute() }); return out; } //CMD_changeStateToAll() public Command CMD_changeStateToSaved() { Command out = new Command(new CommandHandler() { public void execute(ReadOnlyCommandMetadata metadata, Object context) { _feedlyclient.changeState(new State_Stream(_feedlyclient, "user/" + _feedlyclient.getID() + "/tag/global.saved", "Saved", false)); } //execute() }); return out; } //CMD_changeStateToSaved() public Command CMD_logout() { Command out = new Command(new CommandHandler() { public void execute(ReadOnlyCommandMetadata metadata, Object context) { // L?MoH??^?[ if (!Network.isCoverageSufficient()) { Dialog.alert( "A communication error has occurred. Please make sure your device is connected to Internet."); return; } // _CA?O?o?smF?B int select = Dialog.ask(Dialog.D_OK_CANCEL, "Do you really want to log out?", Dialog.NO); if (select == Dialog.NO) { return; } // ?OAEg new Thread() { public void run() { try { // ANeBreBCWP?[^?[\ _screen.showActivityIndicator(); // ?OAEg _feedlyclient.logoutFeedly(); } catch (final Exception e) { // G?[?MO updateStatus("CMD_logout() " + e.toString()); // s?I?OAEg _feedlyclient.forceLogoutFeedly(); // s_CA?O\ /*UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { Dialog.alert("An unexpected error occurred while logging out."); } });*/ } finally { // ANeBreBCWP?[^?[?? _screen.deleteActivityIndicator(); } } //run() }.start(); //Thread() } //execute() }); return out; } //CMD_logout() public Command CMD_refresh() { Command out = new Command(new CommandHandler() { public void execute(ReadOnlyCommandMetadata metadata, Object context) { // L?MoH??^?[ if (!Network.isCoverageSufficient()) { Dialog.alert( "A communication error has occurred. Please make sure your device is connected to Internet."); return; } new Thread() { public void run() { _screen.showActivityIndicator(); refreshUnreadCounts(); _screen.deleteActivityIndicator(); } //run() }.start(); //Thread() } //execute() }); return out; } //CMD_refresh() public Command CMD_reload() { Command out = new Command(new CommandHandler() { public void execute(ReadOnlyCommandMetadata metadata, Object context) { // L?MoH??^?[ if (!Network.isCoverageSufficient()) { Dialog.alert( "A communication error has occurred. Please make sure your device is connected to Internet."); return; } categories.removeAllElements(); categories = null; _screen.deleteAllCategories(); _feedlyclient.changeStateToHomeState(); } //execute() }); return out; } //CMD_reload() public Command CMD_toggleShowAndHideFeeds() { Command out = new Command(new CommandHandler() { public void execute(ReadOnlyCommandMetadata metadata, Object context) { new Thread() { public void run() { synchronized (Lock.lock) { // tH?[JXJeSCfbNX int index = _screen.getRowNumberWithFocus(); // index == 0 Global???B if (index == 0) { return; } _screen.showActivityIndicator(); // tH?[JXJeS Category _tmp = (Category) categories.elementAt(index); // XgJ?s _tmp.toggleShowAndHideFeeds(); // XgJ???Aunread?Aupdated?X?V if (!_tmp.isCollapsed()) { refreshUnreadCounts(); } _screen.deleteActivityIndicator(); } } //run() }.start(); //Thread() } //execute() }); return out; } //CMD_toggleShowAndHideFeeds() public void refreshUnreadCounts() { try { // ANeBreBCWP?[^?[\ //_screen.showActivityIndicator(); JSONArray unreadlist = _feedlyapi.getListOfUnreadCounts().getJSONArray("unreadcounts"); // idL?[?AcountupdatednbVe?[u?AnbVe?[u??B Hashtable unreadlist_hash = new Hashtable(); for (int i = 0; i < unreadlist.length(); i++) { JSONObject source = unreadlist.getJSONObject(i); Hashtable tmp = new Hashtable(); tmp.put("count", new Integer(source.getInt("count"))); tmp.put("updated", new Long(source.getLong("updated"))); unreadlist_hash.put(source.get("id"), tmp); } // JeStbV?\bh?s for (Enumeration e = categories.elements(); e.hasMoreElements();) { Category tmp_ctgry = (Category) e.nextElement(); tmp_ctgry.refreshUnreadAndUpdated(unreadlist_hash); } } catch (final Exception e) { // G?[?MO updateStatus("refreshUnreadCounts() " + e.toString()); // s_CA?O\ UiApplication.getUiApplication().invokeLater(new Runnable() { public void run() { Dialog.alert("An unexpected error occurred while refreshing status."); } }); } finally { //_screen.deleteActivityIndicator(); } } //getListOfUnreadCounts() public void updateStatus(final String message) { _feedlyclient.updateStatus("State_Home::" + message); } //updateStatus() private Vector doCategorize(JSONArray subscriptions) throws JSONException { Vector out = new Vector(); // GlobalJeS?[?B out.addElement(new Global("Global")); // ?wtB?[h????AGlobal^?[ if (subscriptions == null) { return out; } // ?wtB?[h???AGlobal^?[ if (subscriptions.length() == 0) { return out; } // UncategorizedJeS?[?? String streamid_uncategorized = "user/" + _feedlyclient.getID() + "/category/global.uncategorized"; Category _uncategorized = new Category("Uncategorized", streamid_uncategorized, true); // ?wtB?[hJeS?U for (int i = 0; i < subscriptions.length(); i++) { // tB?[h? JSONObject feed_jsonObject = subscriptions.getJSONObject(i); Feed _feed = new Feed(feed_jsonObject); // tB?[hJeS? JSONArray categorys = feed_jsonObject.getJSONArray("categories"); // JeSw???AUncategorizedJeS?[o^?B if (categorys.length() == 0) { _uncategorized.addFeed(_feed); continue; } // tB?[hJeSw? label: for (int j = 0; j < categorys.length(); j++) { // tB?[hJeS? JSONObject category = categorys.getJSONObject(j); String category_name = category.getString("label"); String stream_id = category.getString("id"); // JeS? for (Enumeration e = out.elements(); e.hasMoreElements();) { // JeS? Category _ctgry = (Category) e.nextElement(); // ?vJeS???A?B if (_ctgry.getCategoryName().equals(category_name)) { _ctgry.addFeed(_feed); break label; } } // ?vJeS???AJeS?VK???B Category _new_category = new Category(category_name, stream_id, true); _new_category.addFeed(_feed); out.addElement(_new_category); } } //for // ?UncategorizedJeS?[?i1?tB?[h???j if (_uncategorized.getNumOfFeeds() != 0) { out.addElement(_uncategorized); } return out; } //doCategorize() private class Category { private Vector ids = null; private String category_name = ""; private String streamID = ""; private RichList _list = null; private boolean isCollapsed; public Category(String category_name, String streamID, boolean isCollapsed) { this.category_name = category_name; this.streamID = streamID; this.isCollapsed = isCollapsed; // tB?[hi[pxN^?[?? ids = new Vector(); } public void addFeed(Feed feed) { ids.addElement(feed); } public void doDeleteAllFeedsFromRichList() { // b`Xgvf? int num_of_rows = _list.getModel().getNumberOfRows(); // JeS num_of_rows--; // ?? synchronized (UiApplication.getEventLock()) { for (int i = 0; i < num_of_rows; i++) { // 1?sJeS?A2?s???B _list.remove(1); } } } public void doAddCategoryRichList() { synchronized (UiApplication.getEventLock()) { _list = _screen.addCategory(); _list.setCommand(showStreamScreenCMD()); _screen.addCategoryHeader(_list, this.category_name); } if (!isCollapsed) { doAddCategoryRow(); } } public void doAddCategoryRow() { for (Enumeration e = ids.elements(); e.hasMoreElements();) { Feed feed = (Feed) e.nextElement(); // ?B?X?V?B int unread = 0; synchronized (UiApplication.getEventLock()) { _screen.addCategoryRow(_list, feed.getTitle(), unread, feed.getUpdate()); } } } //doAddCategoryRow() public String getCategoryName() { return category_name; } public int getNumOfFeeds() { return ids.size(); } public boolean isCollapsed() { return isCollapsed; } public void refreshUnreadAndUpdated(Hashtable source) { // JeS??X?V Hashtable data_category = (Hashtable) source.get(streamID); if (data_category != null) { int count = ((Integer) data_category.get("count")).intValue(); _screen.refreshCategoryHeaderUnread(_list, category_name, count); } // Xg??tB?[h??X?V if (isCollapsed) { return; } // Feed??X?V for (int i = 0; i < ids.size(); i++) { Feed feed = (Feed) ids.elementAt(i); Hashtable data = (Hashtable) source.get(feed.getId()); // null???X?V??? if (data == null) { continue; } int count = ((Integer) data.get("count")).intValue(); long updated_long = ((Long) data.get("updated")).longValue(); String updated_string = _feedlyapi.getTime(updated_long); // rowIndexwb_?+1?B int rowIndex = i + 1; _screen.refreshUnreadAndUpdated(_list, rowIndex, count, updated_string); } } //refreshUnreadAndUpdated() public void toggleShowAndHideFeeds() { if (isCollapsed) { // tB?[h?B doAddCategoryRow(); isCollapsed = false; } else { // XgtB?[h?? doDeleteAllFeedsFromRichList(); isCollapsed = true; } } //toggleShowAndHideFeeds() private Command showStreamScreenCMD() { Command out = new Command(new CommandHandler() { public void execute(ReadOnlyCommandMetadata metadata, Object context) { // tH?[JXu int focusrow = _list.getFocusRow(); // tH?[JXu0???Awb_tH?[JX???AJeS\?B if (focusrow == 0) { _feedlyclient.changeState(new State_Stream(_feedlyclient, streamID, category_name, false)); return; } // tH?[JXtB?[h?iindexwb_?-1?B?j Feed _feed = (Feed) ids.elementAt(focusrow - 1); // XeCg`FW _feedlyclient .changeState(new State_Stream(_feedlyclient, _feed.getId(), _feed.getTitle(), false)); } //execute() }); return out; } //showStreamScreenCMD() }//Category class Feed { private String id = ""; private String title = ""; private String update = ""; public Feed(JSONObject source) { try { this.id = source.getString("id"); } catch (JSONException e) { // PASS } // try { this.title = source.getString("title"); } catch (JSONException e) { this.title = "Untitled"; } // try { this.update = _feedlyapi.getTime(source.getLong("updated")); } catch (JSONException e) { this.update = "Unknown"; } } public String getId() { return id; } public String getTitle() { return title; } public String getUpdate() { return update; } } private class Global extends Category { public Global(String category_name) { super(category_name, "dummy", false); } public void doAddCategoryRichList() { synchronized (UiApplication.getEventLock()) { super._list = _screen.addCategory(); super._list.setCommand(showStreamScreenCMD()); _screen.addCategoryHeader(super._list, super.category_name); } if (!super.isCollapsed) { doAddCategoryRow(); } } public void doAddCategoryRow() { // // ALL // String title_all = "ALL"; int unread_all = 0; String updated_all = "Unknown"; synchronized (UiApplication.getEventLock()) { _screen.addCategoryRow(super._list, title_all, unread_all, updated_all); } // // Saved // String title_saved = "Saved For Later"; int unread_saved = 0; String updated_saved = "Unknown"; synchronized (UiApplication.getEventLock()) { _screen.addCategoryRow(super._list, title_saved, unread_saved, updated_saved); } } //doAddCategoryRow() public void refreshUnreadAndUpdated(Hashtable source) { String streamId_all = "user/" + _feedlyclient.getID() + "/category/global.all"; Hashtable data = (Hashtable) source.get(streamId_all); // null???X?V??? if (data == null) { return; } int count = ((Integer) data.get("count")).intValue(); long updated_long = ((Long) data.get("updated")).longValue(); String updated_string = _feedlyapi.getTime(updated_long); _screen.refreshUnreadAndUpdated(super._list, 1, count, updated_string); //String streamId_saved = "user/" + _feedlyclient.getID() + "/tag/global.saved"; //_screen.refreshUnreadAndUpdated(super._list, 2, count, updated_string); } //refreshUnreadAndUpdated() public void toggleShowAndHideFeeds() { // PASS } //toggleShowAndHideFeeds() private Command showStreamScreenCMD() { final RichList _list = super._list; Command out = new Command(new CommandHandler() { public void execute(ReadOnlyCommandMetadata metadata, Object context) { // tH?[JXu int focusrow = _list.getFocusRow(); // tH?[JXu0???AALLXg?[\?B if (focusrow == 1) { _feedlyclient.changeState(new State_Stream(_feedlyclient, "user/" + _feedlyclient.getID() + "/category/global.all", "ALL", true)); } else if (focusrow == 2) { // tH?[JXu1???ASavedXg?[\?B _feedlyclient.changeState(new State_Stream(_feedlyclient, "user/" + _feedlyclient.getID() + "/tag/global.saved", "Saved", false)); } } //execute() }); return out; }//showStreamScreenCMD() }//Global private static class Lock { static Object lock = new Object(); } }