OSDN Git Service

情報更新を行った旨をステータスバーに表示するようにした
[nt-manager/nt-manager.git] / src / twitter / gui / action / TweetMainAction.java
index dc7b038..2b46254 100644 (file)
@@ -15,17 +15,17 @@ import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URL;
 import java.net.URLEncoder;
+import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Properties;
 import java.util.Set;
 import java.util.TreeSet;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import javax.swing.ImageIcon;
 
 import javax.swing.JEditorPane;
 import javax.swing.JFrame;
@@ -36,24 +36,32 @@ import javax.swing.JScrollPane;
 import javax.swing.JTabbedPane;
 import javax.swing.JTable;
 import javax.swing.JTextPane;
-import javax.swing.table.TableCellRenderer;
 import javax.swing.table.TableModel;
 import javax.swing.text.Style;
 import javax.swing.text.StyleConstants;
 import javax.swing.text.html.HTMLDocument;
 import javax.swing.text.html.StyleSheet;
+import twitter.action.TweetDirectMessageGetter;
 import twitter.action.TweetGetter;
+import twitter.action.TweetMentionGetter;
 import twitter.action.TweetSearchResultGetter;
+import twitter.action.TweetSendDirectMessageGetter;
+import twitter.action.TweetTimelineGetter;
 
-import twitter.gui.component.TweetCommentRenderer;
 import twitter.gui.component.TweetTabbedTable;
 import twitter.gui.component.TweetTableModel;
 import twitter.gui.form.AboutDialog;
 import twitter.gui.form.AccountDialog;
 import twitter.gui.form.ConfigurationDialog;
 import twitter.gui.form.DirectMessageDialog;
+import twitter.gui.form.KeywordSearchDialog;
 import twitter.manage.TweetConfiguration;
 import twitter.manage.TweetManager;
+import twitter.task.ExistTimerIDException;
+import twitter.task.TimerID;
+import twitter.task.TweetTaskException;
+import twitter.task.TweetTaskManager;
+import twitter.task.TweetUpdateTask;
 import twitter4j.Status;
 import twitter4j.TwitterException;
 
@@ -65,114 +73,6 @@ import twitter4j.TwitterException;
  */
 public class TweetMainAction {
 
-    /**
-     * 一定時間毎にtweet情報をアップデートするタスク
-     *
-     * @author nishio
-     *
-     */
-    private class TweetAutoUpdateTask implements Runnable {
-
-        TweetAutoUpdateTask() {
-        }
-
-        public void run() {
-            // 一定時間ごとにTweet情報をアップデート
-            try {
-                if (currentGetTimelinePeriodNum == 0) {
-                    // Tweetテーブルの情報を更新
-                    actionTweetTableUpdate();
-                }
-                currentGetTimelinePeriodNum = (currentGetTimelinePeriodNum + 1)
-                        % getTimelinePeriodNum;
-
-                if (currentGetMentionPeriodNum == 0) {
-                    // Mentionテーブルの情報を更新
-                    actionMentionTableUpdate();
-                }
-                currentGetMentionPeriodNum = (currentGetMentionPeriodNum + 1)
-                        % getMentionPeriodNum;
-
-                if (currentGetDirectMessagePeriodNum == 0) {
-                    // DirectMessageテーブルの情報を更新
-                    actionDirectMessageTableUpdate();
-                }
-                currentGetDirectMessagePeriodNum = (currentGetDirectMessagePeriodNum + 1)
-                        % getDirectMessagePeriodNum;
-
-                if (currentGetSendDirectMessagePeriodNum == 0) {
-                    // SendDirectMessageテーブルの情報を更新
-                    actionSendDirectMessageTableUpdate();
-                }
-                currentGetSendDirectMessagePeriodNum = (currentGetSendDirectMessagePeriodNum + 1)
-                        % getSendDirectMessagePeriodNum;
-
-                //設定ファイルを保存
-                saveProperties();
-
-            } catch (Exception e1) {
-                e1.printStackTrace();
-            }
-        }
-    }
-
-    /**
-     * 一定時間毎にtweet情報をアップデートする
-     *
-     * @author nishio
-     *
-     */
-    private class TweetAutoUpdateTimer {
-
-        private ScheduledFuture<?> future;
-        private final ScheduledExecutorService scheduler;
-        private final Runnable task;
-        private long time = 0;
-
-        public TweetAutoUpdateTimer() {
-            task = new TweetAutoUpdateTask();
-            scheduler = Executors.newSingleThreadScheduledExecutor();
-        }
-
-        /**
-         * 更新リセット
-         */
-        public void reset() {
-            stop();
-            if (future != null) {
-                future = scheduler.scheduleAtFixedRate(task, time, time,
-                        TimeUnit.SECONDS);
-            }
-        }
-
-        /**
-         * シャットダウン
-         */
-        public void shutdown() {
-            scheduler.shutdown();
-        }
-
-        /**
-         * 一定時間毎にTweetUpdateTaskを実行
-         *
-         * @param time
-         *            second単位
-         */
-        public void start(long time) {
-            future = scheduler.scheduleAtFixedRate(task, 2, time,
-                    TimeUnit.SECONDS);
-            this.time = time;
-        }
-
-        /**
-         * タスク終了
-         */
-        public void stop() {
-            if (future != null) {
-                future.cancel(true);
-            }
-        }
-    }
     // 基本設定を保存するファイル名
     public static final String BASIC_SETTING_FILENAME = TweetConfiguration.BASIC_SETTING_FILENAME;
     // httpのパターン
@@ -193,38 +93,22 @@ public class TweetMainAction {
     public static final String TAB_MENTION_STRING = "Mention";
     // タイムラインタブに表示する文字
     public static final String TAB_TIMELINE_STRING = "Timeline";
+    //Send Direct Messageタブに表示する文字
+    public static final String TAB_SEND_DIRECT_MESSAGE_STRING = "Send";
     // テーブルのデータ量が以下の値を超えたら古いデータから削除
     private static final int TABLE_ELEMENT_MAX_SIZE = 200;
     // twitterの公式URL
     private static final String TWITTER_URL = "http://twitter.com/";
-    // Tweet情報自動更新タイマー
-    private TweetAutoUpdateTimer autoUpdateTimer = null;
     // 基本設定用ダイアログ
     private ConfigurationDialog configurationDialog = null;
-    private int currentGetDirectMessagePeriodNum = 0;
-    private int currentGetMentionPeriodNum = 0;
-    private int currentGetSendDirectMessagePeriodNum = 0;
-    private int currentGetTimelinePeriodNum = 0;
     // 現在選択しているStatus情報
     private Status currentStatus = null;
     // 詳細情報パネル
     private JPanel detailInfoPanel = null;
     // ダイレクトメッセージ送信用ダイアログ
     private DirectMessageDialog directMessageDialog = null;
-    // directMessageを表示するテーブル
-    private JTable directMessageTable = null;
-    // directMessageのtweetを表示するテーブルモデル
-    private TweetTableModel directMessageTableModel = null;
-    // 情報アップデート間隔(分)
-    private int updatePeriod = 1;
-    // DirectMessageの取得間隔
-    private int getDirectMessagePeriodNum = 10;
-    // Mentionの取得間隔
-    private int getMentionPeriodNum = 5;
-    // SendDirectMessageの取得間隔
-    private int getSendDirectMessagePeriodNum = 30;
-    // Timelineの取得間隔
-    private int getTimelinePeriodNum = 1;
+    //Twitter全体からキーワード検索ダイアログ
+    private KeywordSearchDialog keywordSearchDialog = null;
     // 新しく取得した部分のテーブルカラー
     private Color newTableColor = new Color(224, 255, 255);
     // TLのフォント名
@@ -243,22 +127,12 @@ public class TweetMainAction {
     private int mainFrameHeight = 629;
     // MainFrame
     private JFrame mainFrame = null;
-    // メインのtweetを表示するテーブル
-    private JTable mainTweetTable = null;
-    // mentionを表示するテーブル
-    private JTable mentionTable = null;
-    // mentionのtweetを表示するテーブルモデル
-    private TweetTableModel mentionTableModel = null;
     // 設定
     private Properties property = null;
     // 現在テーブルで選択しているユーザ画像のURL
     private URL selectedUserImageURL = null;
     // 現在テーブルで選択しているユーザの名前
     private String selectedUsername = null;
-    // sendDirectMessageを表示するテーブル
-    private JTable sendDirectMessageTable = null;
-    // sendDirectMessageのtweetを表示するテーブル
-    private TweetTableModel sendDirectMessageTableModel = null;
     // ステータス表示ラベル
     private JLabel statusBarLabel = null;
     // 自分がつぶやきをかく領域
@@ -273,10 +147,21 @@ public class TweetMainAction {
     private JEditorPane tweetMessageBox = null;
     // つぶやくことができる文字数を表示するラベル
     private JLabel tweetMessageCountLabel = null;
-    // メインのtweetを表示するテーブルモデル
-    private TweetTableModel tweetTableModel = null;
     private int uncheckedDirectMessageCount = 0;
     private int uncheckedMentionTweetCount = 0;
+
+    //Tweetの詳細情報を表示する部分
+    private JLabel userImageLabel = null;
+    private JLabel userNameLabel = null;
+    private JLabel updateTimeLabel = null;
+    private JLabel followerLabel = null;
+    private JLabel followingLabel = null;
+    private JLabel locationLabel = null;
+    private JEditorPane clientNameLabel = null;
+    private JLabel updateLabel = null;
+    private JEditorPane userIntroBox = null;
+    private JEditorPane userWebBox = null;
+
     // 新しく取得したtweetでまだ参照していない数
     private int uncheckedTimelineTweetCount = 0;
     private AboutDialog aboutDialog = null;
@@ -284,31 +169,67 @@ public class TweetMainAction {
     private AccountDialog accountDialog;
     //ツイートを表示するテーブル管理
     private List<TweetTabbedTable> tweetTabbedTableList = new ArrayList<TweetTabbedTable>();
+    //ツイートテーブルの情報を一定間隔で更新するクラスを作成
+    private TweetTaskManager tweetTaskManager = new TweetTaskManager();
+
+    //情報更新間隔[sec]
+    private int getTimelinePeriod = 60;
+    private int getMentionPeriod = 60 * 3;
+    private int getDirectMessagePeriod = 60 * 15;
+    private int getSendDirectMessagePeriod = 60 * 30;
 
     /**
      *
+     * @param mainFrame
+     * @param tweetManager
      * @param statusBarLabel
+     * @param tweetTableModel
+     * @param mentionTableModel
+     * @param directMessageTableModel
+     * @param sendDirectMessageTableModel
+     * @param mainTweetTable
+     * @param mentionTable
+     * @param directMessageTable
+     * @param sendDirectMessageTable
+     * @param tweetBoxPane
+     * @param tweetBoxScrollPane
+     * @param tweetMessageCountLabel
+     * @param detailInfoPanel
+     * @param tweetMainTab
+     * @param tweetMessageBox
+     * @param userImageLabel
+     * @param userNameLabel
+     * @param updateTimeLabel
+     * @param followerLabel
+     * @param followingLabel
+     * @param locationLabel
+     * @param clientNameLabel
+     * @param updateLabel
+     * @param userIntroBox
+     * @param userWebBox
      */
-    public TweetMainAction(JFrame mainFrame, TweetManager tweetManager,
-            JLabel statusBarLabel, TweetTableModel tweetTableModel,
-            TweetTableModel mentionTableModel,
-            TweetTableModel directMessageTableModel,
-            TweetTableModel sendDirectMessageTableModel, JTable mainTweetTable,
-            JTable mentionTable, JTable directMessageTable,
-            JTable sendDirectMessageTable, JTextPane tweetBoxPane, JScrollPane tweetBoxScrollPane,
-            JLabel tweetMessageCountLabel, JPanel detailInfoPanel,
-            JTabbedPane tweetMainTab, JEditorPane tweetMessageBox) {
+    public TweetMainAction(JFrame mainFrame,
+            TweetManager tweetManager,
+            JLabel statusBarLabel,
+            JTextPane tweetBoxPane,
+            JScrollPane tweetBoxScrollPane,
+            JLabel tweetMessageCountLabel,
+            JPanel detailInfoPanel,
+            JTabbedPane tweetMainTab,
+            JEditorPane tweetMessageBox,
+            JLabel userImageLabel,
+            JLabel userNameLabel,
+            JLabel updateTimeLabel,
+            JLabel followerLabel,
+            JLabel followingLabel,
+            JLabel locationLabel,
+            JEditorPane clientNameLabel,
+            JLabel updateLabel,
+            JEditorPane userIntroBox,
+            JEditorPane userWebBox) {
         this.mainFrame = mainFrame;
         this.tweetManager = tweetManager;
         this.statusBarLabel = statusBarLabel;
-        this.tweetTableModel = tweetTableModel;
-        this.mentionTableModel = mentionTableModel;
-        this.directMessageTableModel = directMessageTableModel;
-        this.sendDirectMessageTableModel = sendDirectMessageTableModel;
-        this.mainTweetTable = mainTweetTable;
-        this.mentionTable = mentionTable;
-        this.directMessageTable = directMessageTable;
-        this.sendDirectMessageTable = sendDirectMessageTable;
         this.tweetBoxPane = tweetBoxPane;
         this.tweetMessageCountLabel = tweetMessageCountLabel;
         this.detailInfoPanel = detailInfoPanel;
@@ -316,6 +237,18 @@ public class TweetMainAction {
         this.tweetMessageBox = tweetMessageBox;
         this.tweetBoxScrollPane = tweetBoxScrollPane;
 
+        //詳細情報部分
+        this.userImageLabel = userImageLabel;
+        this.userNameLabel = userNameLabel;
+        this.updateTimeLabel = updateTimeLabel;
+        this.userIntroBox = userIntroBox;
+        this.followerLabel = followerLabel;
+        this.followingLabel = followingLabel;
+        this.locationLabel = locationLabel;
+        this.userWebBox = userWebBox;
+        this.clientNameLabel = clientNameLabel;
+        this.updateLabel = updateLabel;
+
         // 設定ファイルの読み込み
         try {
             loadProperties();
@@ -332,6 +265,29 @@ public class TweetMainAction {
         mainFrame.setPreferredSize(new Dimension(this.mainFrameWidth, this.mainFrameHeight));
     }
 
+    /**
+     * Timeline, Mention , DM, SendDMの情報更新間隔を取得し,その情報をテーブルに反映
+     */
+    public void updatePeriodInformationToComponent() {
+        //すべてのテーブルにフォント情報を反映
+        for (TweetTabbedTable t : this.tweetTabbedTableList) {
+            String timerID = t.getTimerID();
+            if( timerID.equals( TimerID.createTimelineID() ) ) {
+                //TLの周期情報更新
+                this.tweetTaskManager.updateTaskPeriod(timerID, this.getGetTimelinePeriod());
+            }else if( timerID.equals( TimerID.createMentionID() ) ) {
+                //Mentionの周期情報更新
+                this.tweetTaskManager.updateTaskPeriod(timerID, this.getGetMentionPeriod() );
+            }else if( timerID.equals( TimerID.createDirectMessageID() ) ) {
+                //DMの周期情報更新
+                this.tweetTaskManager.updateTaskPeriod(timerID, this.getGetDirectMessagePeriod());
+            }else if( timerID.equals( TimerID.createSendDirectMessageID() ) ) {
+                //SendDMの周期情報更新
+                this.tweetTaskManager.updateTaskPeriod(timerID, this.getGetSendDirectMessagePeriod());
+            }
+        }
+    }
+
     // フォント情報をコンポーネントに反映
     public void updateFontInformationToComponent() {
         try {
@@ -344,10 +300,11 @@ public class TweetMainAction {
                 detailFont = new Font(this.detailFontName, Font.PLAIN,
                         this.detailFontSize);
             }
-            this.mainTweetTable.setFont(tlFont);
-            this.mentionTable.setFont(tlFont);
-            this.directMessageTable.setFont(tlFont);
-            this.sendDirectMessageTable.setFont(tlFont);
+
+            //すべてのテーブルにフォント情報を反映
+            for( TweetTabbedTable t : this.tweetTabbedTableList) {
+                t.getTable().setFont(tlFont);
+            }
 
             // tweetメッセージボックスのフォントはhtmlレベルで変更する必要がある
             this.tweetMessageBox.setFont(detailFont);
@@ -368,22 +325,146 @@ public class TweetMainAction {
     }
 
     /**
-     * ツイート検索結果を表示するタブを新しく追加
-     * @param searchWord
+     * 新しいタブを追加
+     * @param timerID TimerIDクラスで生成したタイマーID
+     * @param period 情報更新間隔[sec]
+     * @param tweetGetter 実行するアクション
+     * @param tabTitle 追加するタブのタイトル
      */
-    public void actionAddNewSearchResultTab(String searchWord) {
+    public void actionAddTab(String timerID, int period, TweetGetter tweetGetter, String tabTitle) {
         int numOfTab = this.tweetTabbedTableList.size();
         //すでに追加されているタブの数
-        //TODO:ここはあとで変更する必要がある.なぜなら既に追加されているタブの数は変わる可能性があるから
-        int alreadyExistTabNum = 4;
-        //指定したワードを検索してくるアクション
-        TweetGetter tweetGetter = new TweetSearchResultGetter(this.tweetManager, searchWord);
-        //検索したワードを表示するテーブルを作成,及びタブにそのテーブルを追加
-        TweetTabbedTable searchTable = new TweetTabbedTable(tweetGetter, searchWord,
-                this.tweetMainTab, numOfTab + alreadyExistTabNum,
-                this.tableElementHeight, this.tweetManager,
-                this, newTableColor, tableElementHeight);
-        searchTable.updateTweetTable();
+
+        //周期的に情報を更新する
+        if( period > 0 ) {
+            try {
+                //テーブルを作成
+                final TweetTabbedTable table = new TweetTabbedTable(tweetGetter, tabTitle,
+                        this.tweetMainTab, numOfTab,
+                        this.tableElementHeight, this.tweetManager,
+                        this, newTableColor, tableElementHeight, timerID);
+
+                this.tweetTaskManager.addTask(timerID, new TweetUpdateTask() {
+
+                    @Override
+                    public void runTask() throws TweetTaskException {
+                        //ツイート情報を一定間隔で更新
+                        table.updateTweetTable();
+                    }
+                });
+                //更新開始
+                this.tweetTaskManager.startTask(timerID, period * 1000L);
+
+                //タブにテーブルを追加
+                table.addTableToTab();
+                //タブリストに追加
+                this.tweetTabbedTableList.add(table);
+                //searchTable.updateTweetTable();
+            } catch (TweetTaskException ex) {
+                Logger.getLogger(TweetMainAction.class.getName()).log(Level.SEVERE, null, ex);
+            }
+        }
+
+        //フォント情報を更新
+        this.updateFontInformationToComponent();
+        //テーブルの高さをすべて更新
+        this.updateTableHeight( this.getTableElementHeight() );
+    }
+
+    /**
+     * mentionタブを追加する
+     * @param period 情報更新間隔[sec]
+     */
+    public void actionAddMentionTab(int period) {
+        TimerID timerID = TimerID.getInstance();
+        String id = TimerID.createMentionID();
+        try {
+            //既にIDが存在していたらここで例外発生
+            timerID.addID(id);
+            //検索結果を表示するタブを生成
+            actionAddTab(id, period, new TweetMentionGetter(tweetManager),
+                    TweetMainAction.TAB_MENTION_STRING);
+        } catch (ExistTimerIDException ex) {
+            JOptionPane.showMessageDialog(null, "そのタブは既に存在しています",
+                    "Error", JOptionPane.ERROR_MESSAGE);
+        }
+    }
+
+    /**
+     * timelineタブを追加する
+     * @param period[sec]
+     */
+    public void actionAddTimelineTab(int period) {
+        TimerID timerID = TimerID.getInstance();
+        String id = TimerID.createTimelineID();
+        try {
+            //既にIDが存在していたらここで例外発生
+            timerID.addID(id);
+            //検索結果を表示するタブを生成
+            actionAddTab(id, period, new TweetTimelineGetter(tweetManager),
+                    TweetMainAction.TAB_TIMELINE_STRING);
+        } catch (ExistTimerIDException ex) {
+            JOptionPane.showMessageDialog(null, "そのタブは既に存在しています",
+                    "Error", JOptionPane.ERROR_MESSAGE);
+        }
+    }
+
+    /**
+     * ダイレクトメッセージタブを追加する
+     * @param period 更新間隔[sec]
+     */
+    public void actionAddDirectMessageTab(int period) {
+        TimerID timerID = TimerID.getInstance();
+        String id = TimerID.createDirectMessageID();
+        try {
+            //既にIDが存在していたらここで例外発生
+            timerID.addID(id);
+            //検索結果を表示するタブを生成
+            actionAddTab(id, period, new TweetDirectMessageGetter(tweetManager),
+                    TweetMainAction.TAB_DIRECT_MESSAGE_STRING);
+        } catch (ExistTimerIDException ex) {
+            JOptionPane.showMessageDialog(null, "そのタブは既に存在しています",
+                    "Error", JOptionPane.ERROR_MESSAGE);
+        }
+    }
+
+    /**
+     * SendDMタブを追加する
+     * @param period
+     */
+    public void actionAddSendDirectMessageTab(int period) {
+        TimerID timerID = TimerID.getInstance();
+        String id = TimerID.createSendDirectMessageID();
+        try {
+            //既にIDが存在していたらここで例外発生
+            timerID.addID(id);
+            //検索結果を表示するタブを生成
+            actionAddTab(id, period, new TweetSendDirectMessageGetter(tweetManager),
+                    TweetMainAction.TAB_SEND_DIRECT_MESSAGE_STRING);
+        } catch (ExistTimerIDException ex) {
+            JOptionPane.showMessageDialog(null, "そのタブは既に存在しています",
+                    "Error", JOptionPane.ERROR_MESSAGE);
+        }
+    }
+
+
+    /**
+     * ツイート検索結果を表示するタブを新しく追加
+     * @param searchWord
+     * @param period 更新周期[sec] 0以下の場合は更新しない
+     */
+    public void actionAddNewSearchResultTab(String searchWord, int period) {
+        TimerID timerID = TimerID.getInstance();
+        String id = TimerID.createSearchTimerID(searchWord);
+        try {
+            //既にIDが存在していたらここで例外発生
+            timerID.addID(id);
+            //検索結果を表示するタブを生成
+            actionAddTab(id, period, new TweetSearchResultGetter(this.tweetManager, searchWord), searchWord);
+        } catch (ExistTimerIDException ex) {
+            JOptionPane.showMessageDialog(null, "そのタブは既に存在しています",
+                    "Error", JOptionPane.ERROR_MESSAGE);
+        }
     }
 
     /**
@@ -435,40 +516,34 @@ public class TweetMainAction {
     }
 
     /**
-     * DirectMessageテーブルの更新
+     * 選択しているタブを削除
      */
-    public void actionDirectMessageTableUpdate() {
-        try {
-            // API残り回数を取得
-            int remainingHits = tweetManager.getRateLimitStatus().getRemainingHits();
-            if (remainingHits <= 0) {
-                information("API制限です.リクエストの残数が0となりました.");
-                return;
-            }
-
-            // Direct Message情報
-
-            // DirectMessageを追加
-            List<Status> directMessages = tweetManager.getNewDirectMessages();
-            // まだ見ていないdirectMessage数を追加
-            uncheckedDirectMessageCount += directMessages.size();
-            // まだ見ていないmentionの数をタブに表示
-            if (uncheckedDirectMessageCount > 0) {
-                tweetMainTab.setTitleAt(2, TAB_DIRECT_MESSAGE_STRING + "("
-                        + uncheckedDirectMessageCount + ")");
-            }
-            for (Status t : directMessages) {
-                directMessageTableModel.insertTweet(t);
-                directMessageTable.setRowHeight(0, tableElementHeight);
+    public void actionRemoveFocusedTabbedTable() {
+        int selected = this.tweetMainTab.getSelectedIndex();
+        int deleteTabIndex = selected;
+        
+        if( deleteTabIndex >= 0 ) {
+            //タブを削除
+            this.tweetMainTab.remove(deleteTabIndex);
+            int tabSetNum = this.tweetTabbedTableList.get(deleteTabIndex).getTabSetNum();
+            //タブのタイマーID
+            String timerID = this.tweetTabbedTableList.get(deleteTabIndex).getTimerID();
+
+            //削除
+            this.tweetTabbedTableList.remove(deleteTabIndex);
+
+            //削除した分,既存のタブ番号を1つずつずらさなければならない
+            int tabNum = this.tweetTabbedTableList.size();
+            for(int i = tabSetNum; i < tabNum; i++) {
+                TweetTabbedTable table = this.tweetTabbedTableList.get( i );
+                table.setTabSetNum( table.getTabSetNum() - 1);
             }
-            // 古いデータを削除
-            directMessageTableModel.removeOldTweet(TABLE_ELEMENT_MAX_SIZE);
 
-            directMessageTableModel.refreshTime();
-        } catch (TwitterException e1) {
-            e1.printStackTrace();
-        } catch (Exception e) {
-            e.printStackTrace();
+            //自動更新しているタブを削除
+            this.tweetTaskManager.shutdownTask( timerID );
+            //ID削除
+            TimerID idManager = TimerID.getInstance();
+            idManager.removeID(timerID);
         }
     }
 
@@ -482,53 +557,6 @@ public class TweetMainAction {
     }
 
     /**
-     * Mentionテーブル情報を更新
-     */
-    public void actionMentionTableUpdate() {
-        try {
-            // API残り回数を取得
-            int remainingHits = tweetManager.getRateLimitStatus().getRemainingHits();
-            if (remainingHits <= 0) {
-                information("API制限です.リクエストの残数が0となりました.");
-                return;
-            }
-
-            // Mention情報
-
-            // Mentionを追加
-            List<Status> mention = tweetManager.getNewMentionData();
-            // まだ見ていないmention数を追加
-            uncheckedMentionTweetCount += mention.size();
-            // まだ見ていないmentionの数をタブに表示
-            if (uncheckedMentionTweetCount > 0) {
-                tweetMainTab.setTitleAt(1, TAB_MENTION_STRING + "("
-                        + uncheckedMentionTweetCount + ")");
-            }
-            for (Status t : mention) {
-                mentionTableModel.insertTweet(t);
-                mentionTable.setRowHeight(0, tableElementHeight);
-            }
-            // 新規した部分の背景色を変更
-            TableCellRenderer renderer2 = mentionTable.getCellRenderer(0, 2);
-            if (renderer2 instanceof TweetCommentRenderer) {
-                if (this.uncheckedMentionTweetCount - 1 >= 0) {
-                    ((TweetCommentRenderer) renderer2).updateNewCellRow(
-                            this.uncheckedMentionTweetCount, newTableColor);
-                } else {
-                    ((TweetCommentRenderer) renderer2).updateNewCellRow(-1,
-                            newTableColor);
-                }
-            }
-            // 古いデータを削除
-            mentionTableModel.removeOldTweet(TABLE_ELEMENT_MAX_SIZE);
-
-            mentionTableModel.refreshTime();
-        } catch (TwitterException e1) {
-            e1.printStackTrace();
-        }
-    }
-
-    /**
      * 選択した発言をブラウザで開く
      */
     public void actionOpenStatusURL() {
@@ -564,7 +592,13 @@ public class TweetMainAction {
      * Tweet取得時間情報を更新
      */
     public void actionRefreshTime() {
-        tweetTableModel.refreshTime();
+        //タブに存在する時間情報を更新
+        for(TweetTabbedTable t : this.tweetTabbedTableList ) {
+            TweetTableModel model = t.getModel();
+            if( model != null ) {
+                model.refreshTime();
+            }
+        }
     }
 
     /**
@@ -691,36 +725,8 @@ public class TweetMainAction {
      */
     public void updateTableHeight(int height) {
         this.tableElementHeight = height;
-        mainTweetTable.setRowHeight(tableElementHeight);
-        mentionTable.setRowHeight(tableElementHeight);
-        directMessageTable.setRowHeight(tableElementHeight);
-        sendDirectMessageTable.setRowHeight(tableElementHeight);
-    }
-
-    /**
-     * SendDirectMessageテーブルを更新
-     */
-    public void actionSendDirectMessageTableUpdate() {
-        try {
-            // API残り回数を取得
-            int remainingHits = tweetManager.getRateLimitStatus().getRemainingHits();
-            if (remainingHits <= 0) {
-                information("API制限です.リクエストの残数が0となりました.");
-                return;
-            }
-            // Direct Message情報
-
-            List<Status> sendDirectMessages = tweetManager.getNewSendDirectMessages();
-            for (Status t : sendDirectMessages) {
-                sendDirectMessageTableModel.insertTweet(t);
-                sendDirectMessageTable.setRowHeight(0, tableElementHeight);
-            }
-            // 古いデータを削除
-            sendDirectMessageTableModel.removeOldTweet(TABLE_ELEMENT_MAX_SIZE);
-
-            sendDirectMessageTableModel.refreshTime();
-        } catch (TwitterException e1) {
-            e1.printStackTrace();
+        for( TweetTabbedTable t : this.tweetTabbedTableList) {
+            t.getTable().setRowHeight(tableElementHeight);
         }
     }
 
@@ -764,6 +770,16 @@ public class TweetMainAction {
     }
 
     /**
+     * Twitter全体からキーワード検索ダイアログを表示
+     */
+    public void actionShowKeywordSearchDialog() {
+        Point loc = getDirectMessageDialog().getLocation();
+        KeywordSearchDialog dialog = getKeywordSearchDialog();
+        dialog.setLocationRelativeTo(null);
+        dialog.setVisible(true);
+    }
+
+    /**
      * tweetBoxPaneに書かれた文字をつぶやく
      */
     public void actionTweet() {
@@ -772,71 +788,22 @@ public class TweetMainAction {
     }
 
     /**
-     * Tweetテーブルの情報を更新
+     * Tweet情報を更新
+     *
+     * @param e
      */
-    public void actionTweetTableUpdate() {
+    public void actionUpdateButton(java.awt.event.ActionEvent e) {
         try {
-            // API残り回数を取得
-            int remainingHits = tweetManager.getRateLimitStatus().getRemainingHits();
-            if (remainingHits <= 0) {
-                information("API制限です.リクエストの残数が0となりました.");
-                return;
-            }
-
-            // Timeline情報
-            List<Status> tweet = tweetManager.getNewTimelineData();
-            // まだ見ていないtweet数を追加
-            uncheckedTimelineTweetCount += tweet.size();
-            // まだチェックしていないtweetの数をタブにも表示
-            if (uncheckedTimelineTweetCount > 0) {
-                tweetMainTab.setTitleAt(0, TAB_TIMELINE_STRING + "("
-                        + uncheckedTimelineTweetCount + ")");
-            }
-            // Timelineをテーブルに追加
-            for (Status t : tweet) {
-                tweetTableModel.insertTweet(t);
-                mainTweetTable.setRowHeight(0, tableElementHeight);
-            }
-            // 新規した部分の背景色を変更
-            TableCellRenderer renderer = mainTweetTable.getCellRenderer(0, 2);
-            if (renderer instanceof TweetCommentRenderer) {
-                if (this.uncheckedTimelineTweetCount - 1 >= 0) {
-                    ((TweetCommentRenderer) renderer).updateNewCellRow(
-                            this.uncheckedTimelineTweetCount, newTableColor);
-                } else {
-                    ((TweetCommentRenderer) renderer).updateNewCellRow(-1,
-                            newTableColor);
-                }
+            //タブ上に存在するテーブルの情報を更新
+            for(TweetTabbedTable t : this.tweetTabbedTableList ) {
+                t.updateTweetTable();
             }
-            // 古いデータを削除
-            tweetTableModel.removeOldTweet(TABLE_ELEMENT_MAX_SIZE);
 
+            // API残り回数を取得
+            int remainingHits = tweetManager.getRateLimitStatus().getRemainingHits();
             // 取得したコメント数をステータスバーに表示
-            information(uncheckedTimelineTweetCount
-                    + " 件の新しいツイートを取得しました. (APIリクエスト残数は" + remainingHits
+            information("新しいツイートを取得しました. (APIリクエスト残数は" + remainingHits
                     + "回です)");
-
-            tweetTableModel.refreshTime();
-        } catch (TwitterException e1) {
-            e1.printStackTrace();
-        }
-    }
-
-    /**
-     * メインTweet情報を更新
-     *
-     * @param e
-     */
-    public void actionUpdateButton(java.awt.event.ActionEvent e) {
-        try {
-            // Tweetテーブルの情報を更新
-            actionTweetTableUpdate();
-            // Mentionテーブルの情報を更新
-            actionMentionTableUpdate();
-            // DirectMessageテーブルの情報を更新
-            actionDirectMessageTableUpdate();
-            // SendDirectMessageテーブルの情報を更新
-            actionSendDirectMessageTableUpdate();
         } catch (Exception e1) {
             e1.printStackTrace();
         }
@@ -868,6 +835,17 @@ public class TweetMainAction {
     }
 
     /**
+     * twitter全体からキーワード検索ダイアログを表示
+     * @return
+     */
+    public KeywordSearchDialog getKeywordSearchDialog() {
+        if( keywordSearchDialog == null ) {
+            keywordSearchDialog = new KeywordSearchDialog(mainFrame, true, this);
+        }
+        return keywordSearchDialog;
+    }
+
+    /**
      * アカウント情報設定ダイアログを取得
      * @return
      */
@@ -891,66 +869,68 @@ public class TweetMainAction {
         return directMessageDialog;
     }
 
-    public AboutDialog getAboutDialog() {
-        if (aboutDialog == null) {
-            aboutDialog = new AboutDialog(mainFrame, true);
-        }
-        return aboutDialog;
-    }
-
     /**
-     * updatePeriodを取得します。
-     *
-     * @return updatePeriod
+     * テーブルで選択したツイートを詳細情報としてセット
+     * @param table
      */
-    public int getUpdatePeriod() {
-        return updatePeriod;
-    }
-
-    /**
-     * updatePeriodを設定します。
-     *
-     * @param updatePeriod
-     *            updatePeriod
-     */
-    public void setUpdatePeriod(int updatePeriod) {
-        this.updatePeriod = updatePeriod;
-    }
-
-    /**
-     * getDirectMessagePeriodNumを取得します。
-     *
-     * @return getDirectMessagePeriodNum
-     */
-    public int getGetDirectMessagePeriodNum() {
-        return getDirectMessagePeriodNum;
-    }
-
-    /**
-     * getMentionPeriodNumを取得します。
-     *
-     * @return getMentionPeriodNum
-     */
-    public int getGetMentionPeriodNum() {
-        return getMentionPeriodNum;
-    }
-
-    /**
-     * getSendDirectMessagePeriodNumを取得します。
-     *
-     * @return getSendDirectMessagePeriodNum
-     */
-    public int getGetSendDirectMessagePeriodNum() {
-        return getSendDirectMessagePeriodNum;
+    public void setDetailInformationFromTable(JTable table) {
+        int sc = table.getSelectedRowCount();
+        String infoMessage = "";
+
+        if (sc == 1) {
+            Status st = getTweetTableInformation(table, table.getModel());
+            infoMessage = st.getText();
+            // tweetMessageBox内のURLをhtmlリンクへ変換
+            infoMessage = actionReplaceTweetMessageBoxURLLink(infoMessage);
+            // @ユーザ情報をhtmlリンクへ変換
+            infoMessage = actionReplaceTweetMessageBoxUserInfo(infoMessage);
+            // #ハッシュタグ情報をhtmlリンクへ変換
+            infoMessage = actionReplaceTweetMessageBoxHashTab(infoMessage);
+            // 詳細情報にテーブルで選択した人のツイート情報を表示
+            tweetMessageBox.setText(infoMessage);
+            // user icon
+            userImageLabel.setIcon(new ImageIcon(st.getUser().getProfileImageURL()));
+            // user name and id
+            userNameLabel.setText(st.getUser().getName()
+                    + " / " + st.getUser().getScreenName());
+            // update Time
+            updateTimeLabel.setText(DateFormat.getInstance().format( st.getCreatedAt() ));
+            // ユーザ自己紹介文
+            userIntroBox.setText(st.getUser().getDescription());
+            // フォローされている数
+            followerLabel.setText(st.getUser().getFollowersCount()
+                    + "");
+            // フォローしている数
+            followingLabel.setText(st.getUser().getFriendsCount()
+                    + "");
+            // 現在地
+            locationLabel.setText(st.getUser().getLocation());
+            // Web
+            if (st.getUser().getURL() != null) {
+                userWebBox.setText("<a href=\""
+                        + st.getUser().getURL() + "\">"
+                        + st.getUser().getScreenName()
+                        + "のWebを開く" + "</a>");
+            } else {
+                userWebBox.setText("");
+            }
+            // client
+            clientNameLabel.setText(" via " + st.getSource());
+            // Update
+            updateLabel.setText(st.getUser().getStatusesCount()
+                    + "");
+        }
     }
 
     /**
-     * getTimelinePeriodNumを取得します。
      *
-     * @return getTimelinePeriodNum
+     * @return
      */
-    public int getGetTimelinePeriodNum() {
-        return getTimelinePeriodNum;
+    public AboutDialog getAboutDialog() {
+        if (aboutDialog == null) {
+            aboutDialog = new AboutDialog(mainFrame, true);
+        }
+        return aboutDialog;
     }
 
     /**
@@ -978,7 +958,7 @@ public class TweetMainAction {
      *
      * @param message
      */
-    private void information(String message) {
+    public void information(String message) {
         statusBarLabel.setText(message);
     }
 
@@ -995,11 +975,11 @@ public class TweetMainAction {
         property.load(new FileInputStream("./" + PROPERTIES_DIRECTORY + "/"
                 + BASIC_SETTING_FILENAME));
         // 設定読み込み
-        String gtpn = this.property.getProperty("getTimelinePeriodNum");
-        String gmpn = this.property.getProperty("getMentionPeriodNum");
-        String gdmpn = this.property.getProperty("getDirectMessagePeriodNum");
-        String gsdmpn = this.property.getProperty("getSendDirectMessagePeriodNum");
-        String up = this.property.getProperty("updatePeriod");
+        String gtp = this.property.getProperty("getTimelinePeriod");
+        String gmp = this.property.getProperty("getMentionPeriod");
+        String gdmp = this.property.getProperty("getDirectMessagePeriod");
+        String gsdmp = this.property.getProperty("getSendDirectMessagePeriod");
+
         String ntrgb = this.property.getProperty("newTableColorRGB");
 
         this.tlFontName = this.property.getProperty("tlFontName");
@@ -1014,32 +994,24 @@ public class TweetMainAction {
         String mfh = this.property.getProperty("mainFrameHeight");
 
         try {
-            this.getTimelinePeriodNum = Integer.parseInt(gtpn);
-            this.getMentionPeriodNum = Integer.parseInt(gmpn);
-            this.getDirectMessagePeriodNum = Integer.parseInt(gdmpn);
-            this.getSendDirectMessagePeriodNum = Integer.parseInt(gsdmpn);
-            this.updatePeriod = Integer.parseInt(up);
             this.newTableColor = new Color(Integer.parseInt(ntrgb));
             this.tlFontSize = Integer.parseInt(tfs);
             this.detailFontSize = Integer.parseInt(dfs);
             this.tableElementHeight = Integer.parseInt(teh);
             this.mainFrameWidth = Integer.parseInt(mfw);
             this.mainFrameHeight = Integer.parseInt(mfh);
+
+            //更新間隔
+            this.getTimelinePeriod = Integer.parseInt(gtp);
+            this.getMentionPeriod = Integer.parseInt(gmp);
+            this.getDirectMessagePeriod = Integer.parseInt(gdmp);
+            this.getSendDirectMessagePeriod = Integer.parseInt(gsdmp);
         } catch (NumberFormatException e) {
             e.printStackTrace();
         }
     }
 
     /**
-     * Tweet情報の自動更新のタイムをリセット
-     */
-    public void resetTweetAutoUpdate() {
-        if (this.autoUpdateTimer != null) {
-            this.autoUpdateTimer.reset();
-        }
-    }
-
-    /**
      * 設定ファイルを保存する
      *
      * @throws IOException
@@ -1057,16 +1029,13 @@ public class TweetMainAction {
         if (property == null) {
             this.property = new Properties();
         }
-        // since idを保存
-        this.property.setProperty("getTimelinePeriodNum",
-                this.getTimelinePeriodNum + "");
-        this.property.setProperty("getMentionPeriodNum",
-                this.getMentionPeriodNum + "");
-        this.property.setProperty("getDirectMessagePeriodNum",
-                this.getDirectMessagePeriodNum + "");
-        this.property.setProperty("getSendDirectMessagePeriodNum",
-                this.getSendDirectMessagePeriodNum + "");
-        this.property.setProperty("updatePeriod", this.updatePeriod + "");
+
+        //情報更新間隔
+        this.property.setProperty("getTimelinePeriod", this.getTimelinePeriod + "");
+        this.property.setProperty("getMentionPeriod", this.getMentionPeriod + "");
+        this.property.setProperty("getDirectMessagePeriod", this.getDirectMessagePeriod + "");
+        this.property.setProperty("getSendDirectMessagePeriod", this.getSendDirectMessagePeriod + "");
+
         this.property.setProperty("newTableColorRGB", newTableColor.getRGB()
                 + "");
         this.property.setProperty("tlFontName", this.tlFontName);
@@ -1089,62 +1058,6 @@ public class TweetMainAction {
     }
 
     /**
-     * getDirectMessagePeriodNumを設定します。
-     *
-     * @param getDirectMessagePeriodNum
-     *            getDirectMessagePeriodNum
-     */
-    public void setGetDirectMessagePeriodNum(int getDirectMessagePeriodNum) {
-        this.getDirectMessagePeriodNum = getDirectMessagePeriodNum;
-    }
-
-    /**
-     * getMentionPeriodNumを設定します。
-     *
-     * @param getMentionPeriodNum
-     *            getMentionPeriodNum
-     */
-    public void setGetMentionPeriodNum(int getMentionPeriodNum) {
-        this.getMentionPeriodNum = getMentionPeriodNum;
-    }
-
-    /**
-     * getSendDirectMessagePeriodNumを設定します。
-     *
-     * @param getSendDirectMessagePeriodNum
-     *            getSendDirectMessagePeriodNum
-     */
-    public void setGetSendDirectMessagePeriodNum(
-            int getSendDirectMessagePeriodNum) {
-        this.getSendDirectMessagePeriodNum = getSendDirectMessagePeriodNum;
-    }
-
-    /**
-     * getTimelinePeriodNumを設定します。
-     *
-     * @param getTimelinePeriodNum
-     *            getTimelinePeriodNum
-     */
-    public void setGetTimelinePeriodNum(int getTimelinePeriodNum) {
-        this.getTimelinePeriodNum = getTimelinePeriodNum;
-    }
-
-    /**
-     * Tweet情報の自動更新スタート
-     *
-     * @param second
-     */
-    public void startTweetAutoUpdate() {
-        if (this.autoUpdateTimer == null) {
-            this.autoUpdateTimer = new TweetAutoUpdateTimer();
-        }
-        // 一度タイマーストップ
-        this.autoUpdateTimer.stop();
-        // 自動更新開始
-        this.autoUpdateTimer.start(updatePeriod * 60);
-    }
-
-    /**
      * newTableColorを取得します。
      *
      * @return newTableColor
@@ -1257,4 +1170,60 @@ public class TweetMainAction {
     public void setTableElementHeight(int tableElementHeight) {
         this.tableElementHeight = tableElementHeight;
     }
+
+    /**
+     * @return the getTimelinePeriod
+     */
+    public int getGetTimelinePeriod() {
+        return getTimelinePeriod;
+    }
+
+    /**
+     * @param getTimelinePeriod the getTimelinePeriod to set
+     */
+    public void setGetTimelinePeriod(int getTimelinePeriod) {
+        this.getTimelinePeriod = getTimelinePeriod;
+    }
+
+    /**
+     * @return the getMentionPeriod
+     */
+    public int getGetMentionPeriod() {
+        return getMentionPeriod;
+    }
+
+    /**
+     * @param getMentionPeriod the getMentionPeriod to set
+     */
+    public void setGetMentionPeriod(int getMentionPeriod) {
+        this.getMentionPeriod = getMentionPeriod;
+    }
+
+    /**
+     * @return the getDirectMessagePeriod
+     */
+    public int getGetDirectMessagePeriod() {
+        return getDirectMessagePeriod;
+    }
+
+    /**
+     * @param getDirectMessagePeriod the getDirectMessagePeriod to set
+     */
+    public void setGetDirectMessagePeriod(int getDirectMessagePeriod) {
+        this.getDirectMessagePeriod = getDirectMessagePeriod;
+    }
+
+    /**
+     * @return the getSendDirectMessagePeriod
+     */
+    public int getGetSendDirectMessagePeriod() {
+        return getSendDirectMessagePeriod;
+    }
+
+    /**
+     * @param getSendDirectMessagePeriod the getSendDirectMessagePeriod to set
+     */
+    public void setGetSendDirectMessagePeriod(int getSendDirectMessagePeriod) {
+        this.getSendDirectMessagePeriod = getSendDirectMessagePeriod;
+    }
 }