OSDN Git Service

指定したユーザのツイートを取得できるように改良 refs #25030
[nt-manager/nt-manager.git] / src / twitter / gui / action / TweetMainAction.java
1 package twitter.gui.action;
2
3 import java.awt.Color;
4 import java.awt.Desktop;
5 import java.awt.Dimension;
6 import java.awt.Font;
7 import java.awt.Point;
8 import java.awt.TrayIcon;
9 import java.awt.event.ActionEvent;
10 import java.io.File;
11 import java.io.FileInputStream;
12 import java.io.FileNotFoundException;
13 import java.io.FileOutputStream;
14 import java.io.IOException;
15 import java.io.UnsupportedEncodingException;
16 import java.net.URI;
17 import java.net.URL;
18 import java.net.URLEncoder;
19 import java.text.DateFormat;
20 import java.util.ArrayList;
21 import java.util.Comparator;
22 import java.util.List;
23 import java.util.Locale;
24 import java.util.Properties;
25 import java.util.Set;
26 import java.util.TreeSet;
27 import java.util.logging.Level;
28 import java.util.logging.Logger;
29 import java.util.regex.Matcher;
30 import java.util.regex.Pattern;
31 import javax.swing.ImageIcon;
32 import javax.swing.JCheckBoxMenuItem;
33
34 import javax.swing.JEditorPane;
35 import javax.swing.JFrame;
36 import javax.swing.JLabel;
37 import javax.swing.JOptionPane;
38 import javax.swing.JPanel;
39 import javax.swing.JTabbedPane;
40 import javax.swing.JTable;
41 import javax.swing.JTextPane;
42 import javax.swing.JToggleButton;
43 import javax.swing.table.TableModel;
44 import javax.swing.text.Style;
45 import javax.swing.text.StyleConstants;
46 import javax.swing.text.html.HTMLDocument;
47 import javax.swing.text.html.StyleSheet;
48 import twitter.action.TweetDirectMessageGetter;
49 import twitter.action.TweetFavoriteGetter;
50 import twitter.action.TweetGetter;
51 import twitter.action.TweetListGetter;
52 import twitter.action.TweetMentionGetter;
53 import twitter.action.TweetSearchResultGetter;
54 import twitter.action.TweetSendDirectMessageGetter;
55 import twitter.action.TweetTimelineGetter;
56 import twitter.action.TweetUserTimelineGetter;
57 import twitter.action.list.ListGetterSelection;
58 import twitter.action.list.UserListGetter;
59 import twitter.action.list.UserListMembershipsGetter;
60 import twitter.action.list.UserListSpecificUserListsGetter;
61 import twitter.action.list.UserListSubscriptionGetter;
62 import twitter.cache.TwitterImageCache;
63 import twitter.gui.component.DnDTabbedPane;
64
65 import twitter.gui.component.TweetTabbedTable;
66 import twitter.gui.component.TweetTableModel;
67 import twitter.gui.form.AboutDialog;
68 import twitter.gui.form.AccountDialog;
69 import twitter.gui.form.ConfigurationDialog;
70 import twitter.gui.form.DirectMessageDialog;
71 import twitter.gui.form.HashtagSearchDialog;
72 import twitter.gui.form.KeywordSearchDialog;
73 import twitter.gui.form.UserListDialog;
74 import twitter.gui.form.UserSearchDialog;
75 import twitter.manage.TweetConfiguration;
76 import twitter.manage.TweetManager;
77 import twitter.task.ExistTimerIDException;
78 import twitter.task.TimerID;
79 import twitter.task.TweetTaskException;
80 import twitter.task.TweetTaskManager;
81 import twitter.task.TweetUpdateTask;
82 import twitter.util.HTMLEncode;
83 import twitter4j.Status;
84 import twitter4j.TwitterException;
85
86 /**
87  * GUIのアクション部分
88  * 
89  * @author nishio
90  * 
91  */
92 public class TweetMainAction {
93
94         // 基本設定を保存するファイル名
95         public static final String BASIC_SETTING_FILENAME = TweetConfiguration.BASIC_SETTING_FILENAME;
96         // httpのパターン
97         private static final Pattern convURLLinkPtn = Pattern.compile(
98                         "(http://|https://){1}[\\w\\.\\-/:\\#\\?\\=\\&\\;\\%\\~\\+]+",
99                         Pattern.CASE_INSENSITIVE);
100         // default char encoding
101         private static final String DEFAULT_CHARACTER_ENCODING = "UTF-8";
102         // 設定ファイルを保存するディレクトリ名
103         public static final String PROPERTIES_DIRECTORY = "properties";
104         // search twitterのクエリ
105         private static final String SEARCH_QUERY = "search?q=";
106         // search twitterのURL
107         private static final String SEARCH_TWITTER_URL = "http://"
108                         + TweetConfiguration.SEARCH_TWITTER_HOSTNAME + "/";
109         // Direct Messageタブに表示する文字
110         public static final String TAB_DIRECT_MESSAGE_STRING = "Message";
111         // Mentionタブに表示する文字
112         public static final String TAB_MENTION_STRING = "Mention";
113         // タイムラインタブに表示する文字
114         public static final String TAB_TIMELINE_STRING = "Timeline";
115         // Send Direct Messageタブに表示する文字
116         public static final String TAB_SEND_DIRECT_MESSAGE_STRING = "Send";
117         // テーブルのデータ量が以下の値を超えたら古いデータから削除
118         private static final int TABLE_ELEMENT_MAX_SIZE = 200;
119         // twitterの公式URL
120         private static final String TWITTER_URL = "http://twitter.com/";
121         // 基本設定用ダイアログ
122         private ConfigurationDialog configurationDialog = null;
123         // 現在選択しているStatus情報
124         private Status currentStatus = null;
125         // reply予定のStatus
126         private Status replyStatus = null;
127         // 詳細情報パネル
128         private JPanel detailInfoPanel = null;
129         // ダイレクトメッセージ送信用ダイアログ
130         private DirectMessageDialog directMessageDialog = null;
131         // Twitter全体からキーワード検索ダイアログ
132         private KeywordSearchDialog keywordSearchDialog = null;
133         // hashtag search dialog
134         private HashtagSearchDialog hashtagSearchDialog = null;
135         // 新しく取得した部分のテーブルカラー
136         private Color newTableColor = new Color(224, 255, 255);
137         // TLのフォント名
138         private String tlFontName = "Takao Pゴシック";
139         // TLのフォントサイズ
140         private int tlFontSize = 13;
141         // 詳細情報のフォント名
142         private String detailFontName = "Takao Pゴシック";
143         // 詳細情報のフォントサイズ
144         private int detailFontSize = 13;
145         // テーブル1要素の高さ
146         private int tableElementHeight = 50;
147         // メインフレームの幅
148         private int mainFrameWidth = 729;
149         // メインフレームの高さ
150         private int mainFrameHeight = 629;
151         // MainFrame
152         private JFrame mainFrame = null;
153         // 設定
154         private Properties property = null;
155         // 現在テーブルで選択しているユーザ画像のURL
156         private URL selectedUserImageURL = null;
157         // 現在テーブルで選択しているユーザの名前
158         private String selectedUsername = null;
159         // ステータス表示ラベル
160         private JLabel statusBarLabel = null;
161         // 自分がつぶやきをかく領域
162         private JTextPane tweetBoxPane = null;
163         // 自分がつぶやきを書く領域のスクロールペーン
164         private JPanel tweetBoxRegionPane = null;
165         // tweet情報などを表示するタブ
166         private JTabbedPane tweetMainTab = null;
167         // Tweet管理
168         private TweetManager tweetManager = null;
169         // tweetを表示するTextPane
170         private JEditorPane tweetMessageBox = null;
171         // つぶやくことができる文字数を表示するラベル
172         private JLabel tweetMessageCountLabel = null;
173         private int uncheckedDirectMessageCount = 0;
174         private int uncheckedMentionTweetCount = 0;
175         // 自分宛のメッセージを通知バーに表示するか
176         private boolean isNotifyMentionMessage = true;
177         private boolean isNotifyDirectMessage = true;
178         //前回開いていたタブの情報を復活する際に利用する(最初の一回だけ利用)
179         private boolean isTempOpenedTimelineTab = true;
180         private boolean isTempOpenedMentionTab = true;
181         private boolean isTempOpenedDMTab = true;
182         private boolean isTempOpenedSendDMTab = true;
183
184         // Tweetの詳細情報を表示する部分
185         private JLabel userImageLabel = null;
186         private JLabel userNameLabel = null;
187         private JLabel updateTimeLabel = null;
188         private JLabel followerLabel = null;
189         private JLabel followingLabel = null;
190         private JLabel locationLabel = null;
191         private JEditorPane clientNameLabel = null;
192         private JLabel updateLabel = null;
193         private JEditorPane userIntroBox = null;
194         private JEditorPane userWebBox = null;
195         // トレイアイコン
196         private TrayIcon trayIcon = null;
197
198         // checkbox関係
199         private javax.swing.JToggleButton timelineToggleButton;
200         private javax.swing.JToggleButton mentionToggleButton;
201         private javax.swing.JToggleButton dmToggleButton;
202         private javax.swing.JToggleButton sendDMToggleButton;
203
204         private javax.swing.JCheckBoxMenuItem timelineCheckBoxMenuItem;
205         private javax.swing.JCheckBoxMenuItem mentionCheckBoxMenuItem;
206         private javax.swing.JCheckBoxMenuItem dmCheckBoxMenuItem;
207         private javax.swing.JCheckBoxMenuItem sendCheckBoxMenuItem;
208
209         // 新しく取得したtweetでまだ参照していない数
210         private int uncheckedTimelineTweetCount = 0;
211         private AboutDialog aboutDialog = null;
212         // アカウント情報表示ダイアログ
213         private AccountDialog accountDialog;
214         // ツイートを表示するテーブル管理
215         private List<TweetTabbedTable> tweetTabbedTableList = new ArrayList<TweetTabbedTable>();
216         // ツイートテーブルの情報を一定間隔で更新するクラスを作成
217         private TweetTaskManager tweetTaskManager = new TweetTaskManager();
218
219         // リストダイアログ
220         private UserListDialog userListDialog = null;
221         //ユーザサーチダイアログ
222         private UserSearchDialog userSearchDialog = null;
223
224         // 情報更新間隔[sec]
225         private int getTimelinePeriod = 60;
226         private int getMentionPeriod = 60 * 3;
227         private int getDirectMessagePeriod = 60 * 15;
228         private int getSendDirectMessagePeriod = 60 * 30;
229
230         /**
231          * 
232          * @param mainFrame
233          * @param tweetManager
234          * @param statusBarLabel
235          * @param tweetTableModel
236          * @param mentionTableModel
237          * @param directMessageTableModel
238          * @param sendDirectMessageTableModel
239          * @param mainTweetTable
240          * @param mentionTable
241          * @param directMessageTable
242          * @param sendDirectMessageTable
243          * @param tweetBoxPane
244          * @param tweetBoxScrollPane
245          * @param tweetMessageCountLabel
246          * @param detailInfoPanel
247          * @param tweetMainTab
248          * @param tweetMessageBox
249          * @param userImageLabel
250          * @param userNameLabel
251          * @param updateTimeLabel
252          * @param followerLabel
253          * @param followingLabel
254          * @param locationLabel
255          * @param clientNameLabel
256          * @param updateLabel
257          * @param userIntroBox
258          * @param userWebBox
259          */
260         public TweetMainAction(JFrame mainFrame, TweetManager tweetManager,
261                         JLabel statusBarLabel, JTextPane tweetBoxPane,
262                         JPanel tweetBoxScrollPane, JLabel tweetMessageCountLabel,
263                         JPanel detailInfoPanel, JTabbedPane tweetMainTab,
264                         JEditorPane tweetMessageBox, JLabel userImageLabel,
265                         JLabel userNameLabel, JLabel updateTimeLabel, JLabel followerLabel,
266                         JLabel followingLabel, JLabel locationLabel,
267                         JEditorPane clientNameLabel, JLabel updateLabel,
268                         JEditorPane userIntroBox, JEditorPane userWebBox,
269                         JToggleButton timelineToggleButton,
270                         JToggleButton mentionToggleButton, JToggleButton dmToggleButton,
271                         JToggleButton sendToggleButton,
272                         JCheckBoxMenuItem timelineCheckBoxMenuItem,
273                         JCheckBoxMenuItem mentionCheckBoxMenuItem,
274                         JCheckBoxMenuItem dmCheckBoxMenuItem,
275                         JCheckBoxMenuItem sendCheckBoxMenuItem, TrayIcon trayIcon) {
276                 this.mainFrame = mainFrame;
277                 this.tweetManager = tweetManager;
278                 this.statusBarLabel = statusBarLabel;
279                 this.tweetBoxPane = tweetBoxPane;
280                 this.tweetMessageCountLabel = tweetMessageCountLabel;
281                 this.detailInfoPanel = detailInfoPanel;
282                 this.tweetMainTab = tweetMainTab;
283                 this.tweetMessageBox = tweetMessageBox;
284                 this.tweetBoxRegionPane = tweetBoxScrollPane;
285
286                 // 詳細情報部分
287                 this.userImageLabel = userImageLabel;
288                 this.userNameLabel = userNameLabel;
289                 this.updateTimeLabel = updateTimeLabel;
290                 this.userIntroBox = userIntroBox;
291                 this.followerLabel = followerLabel;
292                 this.followingLabel = followingLabel;
293                 this.locationLabel = locationLabel;
294                 this.userWebBox = userWebBox;
295                 this.clientNameLabel = clientNameLabel;
296                 this.updateLabel = updateLabel;
297
298                 this.timelineCheckBoxMenuItem = timelineCheckBoxMenuItem;
299                 this.timelineToggleButton = timelineToggleButton;
300                 this.mentionCheckBoxMenuItem = mentionCheckBoxMenuItem;
301                 this.mentionToggleButton = mentionToggleButton;
302                 this.dmCheckBoxMenuItem = dmCheckBoxMenuItem;
303                 this.dmToggleButton = dmToggleButton;
304                 this.sendCheckBoxMenuItem = sendCheckBoxMenuItem;
305                 this.sendDMToggleButton = sendToggleButton;
306
307                 // トレイアイコン
308                 this.trayIcon = trayIcon;
309
310                 // 罰ボタンを押した時のイベントを追加
311                 if (this.tweetMainTab instanceof DnDTabbedPane) {
312                         ((DnDTabbedPane) this.tweetMainTab).setMainAction(this);
313                 }
314
315                 // 設定ファイルの読み込み
316                 try {
317                         loadProperties();
318                 } catch (FileNotFoundException e) {
319                         e.printStackTrace();
320                 } catch (IOException e) {
321                         e.printStackTrace();
322                 }
323                 // フォント情報を反映
324                 updateFontInformationToComponent();
325
326                 // フレームの大きさを反映
327                 mainFrame.setSize(this.mainFrameWidth, this.mainFrameHeight);
328                 mainFrame.setPreferredSize(new Dimension(this.mainFrameWidth,
329                                 this.mainFrameHeight));
330         }
331
332         /**
333          * チェックボックスの状態を更新
334          */
335         public void updateCheckboxInformation() {
336                 boolean timeline = this.isExistTimelineTab();
337                 boolean mention = this.isExistMentionTab();
338                 boolean dm = this.isExistDirectMessageTab();
339                 boolean send = this.isExistSendDirectMessageTab();
340
341                 this.timelineCheckBoxMenuItem.setSelected(timeline);
342                 this.timelineToggleButton.setSelected(timeline);
343                 this.mentionCheckBoxMenuItem.setSelected(mention);
344                 this.mentionToggleButton.setSelected(mention);
345                 this.dmCheckBoxMenuItem.setSelected(dm);
346                 this.dmToggleButton.setSelected(dm);
347                 this.sendCheckBoxMenuItem.setSelected(send);
348                 this.sendDMToggleButton.setSelected(send);
349         }
350
351         /**
352          * Timeline, Mention , DM, SendDMの情報更新間隔を取得し,その情報をテーブルに反映
353          */
354         public void updatePeriodInformationToComponent() {
355                 // すべてのテーブルにフォント情報を反映
356                 for (TweetTabbedTable t : this.tweetTabbedTableList) {
357                         String timerID = t.getTimerID();
358                         if (timerID.equals(TimerID.createTimelineID())) {
359                                 // TLの周期情報更新
360                                 this.tweetTaskManager.updateTaskPeriod(timerID, this
361                                                 .getGetTimelinePeriod(), false);
362                         } else if (timerID.equals(TimerID.createMentionID())) {
363                                 // Mentionの周期情報更新
364                                 this.tweetTaskManager.updateTaskPeriod(timerID, this
365                                                 .getGetMentionPeriod(), false);
366                         } else if (timerID.equals(TimerID.createDirectMessageID())) {
367                                 // DMの周期情報更新
368                                 this.tweetTaskManager.updateTaskPeriod(timerID, this
369                                                 .getGetDirectMessagePeriod(), false);
370                         } else if (timerID.equals(TimerID.createSendDirectMessageID())) {
371                                 // SendDMの周期情報更新
372                                 this.tweetTaskManager.updateTaskPeriod(timerID, this
373                                                 .getGetSendDirectMessagePeriod(), false);
374                         }
375                 }
376         }
377
378         // フォント情報をコンポーネントに反映
379         public void updateFontInformationToComponent() {
380                 try {
381                         Font tlFont = null;
382                         if (this.tlFontName != null) {
383                                 tlFont = new Font(this.tlFontName, Font.PLAIN, this.tlFontSize);
384                         }
385                         Font detailFont = null;
386                         if (this.detailFontName != null) {
387                                 detailFont = new Font(this.detailFontName, Font.PLAIN,
388                                                 this.detailFontSize);
389                         }
390
391                         // すべてのテーブルにフォント情報を反映
392                         for (TweetTabbedTable t : this.tweetTabbedTableList) {
393                                 t.getTable().setFont(tlFont);
394                         }
395
396                         // tweetメッセージボックスのフォントはhtmlレベルで変更する必要がある
397                         this.tweetMessageBox.setFont(detailFont);
398                         // htmlフォント変更
399                         HTMLDocument doc = (HTMLDocument) this.tweetMessageBox
400                                         .getDocument();
401                         StyleSheet[] style = doc.getStyleSheet().getStyleSheets();
402                         for (int i = style.length - 1; i >= 0; i--) {
403                                 Style body = style[i].getStyle("body");
404                                 if (body != null) {
405                                         StyleConstants
406                                                         .setFontFamily(body, detailFont.getFontName());
407                                         StyleConstants.setFontSize(body, detailFont.getSize());
408                                 }
409                         }
410
411                 } catch (Exception e) {
412                         e.printStackTrace();
413                 }
414         }
415
416         /**
417          * 新しいタブを追加
418          * 
419          * @param timerID
420          *            TimerIDクラスで生成したタイマーID
421          * @param period
422          *            情報更新間隔[sec]
423          * @param tweetGetter
424          *            実行するアクション
425          * @param tabTitle
426          *            追加するタブのタイトル
427          */
428         public void actionAddTab(String timerID, int period,
429                         TweetGetter tweetGetter, String tabTitle) {
430                 // 周期的に情報を更新する
431                 if (period > 0) {
432                         try {
433                                 // テーブルを作成
434                                 final TweetTabbedTable table = new TweetTabbedTable(
435                                                 tweetGetter, tabTitle, this.tweetMainTab,
436                                                 this.tableElementHeight, this.tweetManager, this,
437                                                 newTableColor, TABLE_ELEMENT_MAX_SIZE, timerID);
438
439                                 this.tweetTaskManager.addTask(timerID, new TweetUpdateTask() {
440
441                                         @Override
442                                         public void runTask() throws TweetTaskException {
443                                                 // ツイート情報を一定間隔で更新
444                                                 table.updateTweetTable();
445                                         }
446                                 });
447                                 // 更新開始
448                                 this.tweetTaskManager.startTask(timerID, period * 1000L);
449
450                                 // タブにテーブルを追加
451                                 table.addTableToTab();
452                                 // タブリストに追加
453                                 this.tweetTabbedTableList.add(table);
454                                 //設定を保存
455                                 this.saveProperties();
456                                 // searchTable.updateTweetTable();
457                                 // フォーカスを新しいタブに移す
458                                 this.actionRequestForusToLastTab();
459                         } catch (TweetTaskException ex) {
460                                 Logger.getLogger(TweetMainAction.class.getName()).log(
461                                                 Level.SEVERE, null, ex);
462                         } catch (IOException e) {
463                                 e.printStackTrace();
464                         }
465                 }
466
467                 // フォント情報を更新
468                 this.updateFontInformationToComponent();
469                 // テーブルの高さをすべて更新
470                 this.updateTableHeight(this.getTableElementHeight());
471         }
472
473         /**
474          * mentionタブを追加する
475          * 
476          * @param period
477          *            情報更新間隔[sec]
478          */
479         public void actionAddMentionTab(int period) {
480                 TimerID timerID = TimerID.getInstance();
481                 String id = TimerID.createMentionID();
482                 try {
483                         // 既にIDが存在していたらここで例外発生
484                         timerID.addID(id);
485                         // 検索結果を表示するタブを生成
486                         if (this.isNotifyMentionMessage) {
487                                 // メッセージが到着したら通知を行う
488                                 actionAddTab(id, period, new TweetMentionGetter(tweetManager,
489                                                 this.trayIcon), TweetMainAction.TAB_MENTION_STRING);
490                         } else {
491                                 actionAddTab(id, period, new TweetMentionGetter(tweetManager),
492                                                 TweetMainAction.TAB_MENTION_STRING);
493                         }
494                 } catch (ExistTimerIDException ex) {
495                         JOptionPane.showMessageDialog(null, "そのタブは既に存在しています", "Error",
496                                         JOptionPane.ERROR_MESSAGE);
497                 }
498         }
499
500         /**
501          * お気に入りタブを追加
502          * 
503          * @param screenName
504          *            nullで自分自身を取得,指定するとscreenNameのFav取得
505          */
506         public void actionAddFavoriteTab(String screenName) {
507                 TimerID timerID = TimerID.getInstance();
508                 String id = TimerID.createFavoriteID(screenName);
509                 try {
510                         // 既にIDが存在していたらここで例外発生
511                         timerID.addID(id);
512                         String favTitle;
513                         if (screenName == null) {
514                                 favTitle = "お気に入り";
515                         } else {
516                                 favTitle = screenName + "のお気に入り";
517                         }
518                         // 検索結果を表示するタブを生成
519                         actionAddTab(id, Integer.MAX_VALUE, new TweetFavoriteGetter(
520                                         tweetManager, screenName), favTitle);
521                 } catch (ExistTimerIDException ex) {
522                         JOptionPane.showMessageDialog(null, "そのタブは既に存在しています", "Error",
523                                         JOptionPane.ERROR_MESSAGE);
524                 }
525         }
526
527         /**
528          * timelineタブを追加する
529          * 
530          * @param period
531          *            [sec]
532          */
533         public void actionAddTimelineTab(int period) {
534                 TimerID timerID = TimerID.getInstance();
535                 String id = TimerID.createTimelineID();
536                 try {
537                         // 既にIDが存在していたらここで例外発生
538                         timerID.addID(id);
539                         // 検索結果を表示するタブを生成
540                         actionAddTab(id, period, new TweetTimelineGetter(tweetManager),
541                                         TweetMainAction.TAB_TIMELINE_STRING);
542                 } catch (ExistTimerIDException ex) {
543                         JOptionPane.showMessageDialog(null, "そのタブは既に存在しています", "Error",
544                                         JOptionPane.ERROR_MESSAGE);
545                 }
546         }
547
548         /**
549          * ダイレクトメッセージタブを追加する
550          * 
551          * @param period
552          *            更新間隔[sec]
553          */
554         public void actionAddDirectMessageTab(int period) {
555                 TimerID timerID = TimerID.getInstance();
556                 String id = TimerID.createDirectMessageID();
557                 try {
558                         // 既にIDが存在していたらここで例外発生
559                         timerID.addID(id);
560                         // 検索結果を表示するタブを生成
561                         if (this.isNotifyDirectMessage == true) {
562                                 actionAddTab(id, period, new TweetDirectMessageGetter(
563                                                 tweetManager, this.trayIcon),
564                                                 TweetMainAction.TAB_DIRECT_MESSAGE_STRING);
565                         } else {
566                                 actionAddTab(id, period, new TweetDirectMessageGetter(
567                                                 tweetManager),
568                                                 TweetMainAction.TAB_DIRECT_MESSAGE_STRING);
569                         }
570                 } catch (ExistTimerIDException ex) {
571                         JOptionPane.showMessageDialog(null, "そのタブは既に存在しています", "Error",
572                                         JOptionPane.ERROR_MESSAGE);
573                 }
574         }
575
576         /**
577          * SendDMタブを追加する
578          * 
579          * @param period
580          */
581         public void actionAddSendDirectMessageTab(int period) {
582                 TimerID timerID = TimerID.getInstance();
583                 String id = TimerID.createSendDirectMessageID();
584                 try {
585                         // 既にIDが存在していたらここで例外発生
586                         timerID.addID(id);
587                         // 検索結果を表示するタブを生成
588                         actionAddTab(id, period, new TweetSendDirectMessageGetter(
589                                         tweetManager),
590                                         TweetMainAction.TAB_SEND_DIRECT_MESSAGE_STRING);
591                 } catch (ExistTimerIDException ex) {
592                         JOptionPane.showMessageDialog(null, "そのタブは既に存在しています", "Error",
593                                         JOptionPane.ERROR_MESSAGE);
594                 }
595         }
596
597         /**
598          * 指定したリストをタブに追加
599          * 
600          * @param username
601          * @param listID
602          * @param listFullname
603          * @param period
604          */
605         public void actionAddListTab(String username, int listID,
606                         String listFullname, int period) {
607                 TimerID timerID = TimerID.getInstance();
608                 String id = TimerID.createUserListID(username, listID);
609                 try {
610                         // 既にIDが存在していたらここで例外発生
611                         timerID.addID(id);
612                         // 検索結果を表示するタブを生成
613                         actionAddTab(id, period, new TweetListGetter(tweetManager,
614                                         username, listID), listFullname);
615                 } catch (ExistTimerIDException ex) {
616                         JOptionPane.showMessageDialog(null, "そのタブは既に存在しています", "Error",
617                                         JOptionPane.ERROR_MESSAGE);
618                 }
619         }
620
621         /**
622          * ツイート検索結果を表示するタブを新しく追加
623          * 
624          * @param searchWord
625          * @param period
626          *            更新周期[sec] 0以下の場合は更新しない
627          */
628         public void actionAddNewSearchResultTab(String searchWord, int period) {
629                 TimerID timerID = TimerID.getInstance();
630                 String id = TimerID.createSearchTimerID(searchWord);
631                 try {
632                         // 既にIDが存在していたらここで例外発生
633                         timerID.addID(id);
634                         // 検索結果を表示するタブを生成
635                         actionAddTab(id, period, new TweetSearchResultGetter(
636                                         this.tweetManager, searchWord), searchWord);
637                 } catch (ExistTimerIDException ex) {
638                         JOptionPane.showMessageDialog(null, "そのタブは既に存在しています", "Error",
639                                         JOptionPane.ERROR_MESSAGE);
640                 }
641         }
642
643         /**
644          * 指定したユーザの発言を表示
645          * 
646          * @param username
647          *            タブのタイトルにつけるユーザ名
648          * @param period
649          *            更新周期[sec]
650          */
651         public void actionAddUserTimelineTab(String username,
652                         int period) {
653                 TimerID timerID = TimerID.getInstance();
654                 String id = TimerID.createUserTimelineID(username);
655                 try {
656                         // 既にIDが存在していたらここで例外発生
657                         timerID.addID(id);
658                         // 検索結果を表示するタブを生成
659                         actionAddTab(id, period, new TweetUserTimelineGetter(tweetManager,
660                                         username), username + "の発言");
661                 } catch (ExistTimerIDException ex) {
662                         JOptionPane.showMessageDialog(null, "そのタブは既に存在しています", "Error",
663                                         JOptionPane.ERROR_MESSAGE);
664                 }
665         }
666
667         /**
668          * タイムラインタブが存在しているか
669          * 
670          * @return
671          */
672         public boolean isExistTimelineTab() {
673                 TimerID timerID = TimerID.getInstance();
674                 String id = TimerID.createTimelineID();
675                 return timerID.contains(id);
676         }
677
678         /**
679          * Mentionタブが存在するか
680          * 
681          * @return
682          */
683         public boolean isExistMentionTab() {
684                 TimerID timerID = TimerID.getInstance();
685                 String id = TimerID.createMentionID();
686                 return timerID.contains(id);
687         }
688
689         /**
690          * DMタブが存在するか
691          * 
692          * @return
693          */
694         public boolean isExistDirectMessageTab() {
695                 TimerID timerID = TimerID.getInstance();
696                 String id = TimerID.createDirectMessageID();
697                 return timerID.contains(id);
698         }
699
700         /**
701          * 送信済みDMタブが存在するか
702          * 
703          * @return
704          */
705         public boolean isExistSendDirectMessageTab() {
706                 TimerID timerID = TimerID.getInstance();
707                 String id = TimerID.createSendDirectMessageID();
708                 return timerID.contains(id);
709         }
710
711         /**
712          * 基本設定ダイアログを開く
713          */
714         public void actionBasicSettingDialog() {
715                 // ダイレクトメッセージ送信用ダイアログを開く
716                 Point loc = getConfigurationDialog().getLocation();
717                 loc.translate(20, 20);
718                 ConfigurationDialog dialog = getConfigurationDialog();
719                 dialog.setLocation(loc);
720                 dialog.setVisible(true);
721         }
722
723         /**
724          * reply設定
725          */
726         public void actionSetReplyStatusToTweetBoxPane() {
727                 // 選択した部分
728                 this.setReplyStatus(currentStatus);
729
730                 Status s = this.getCurrentStatus();
731                 if (s.isRetweet()) {
732                         s = s.getRetweetedStatus();
733                 }
734                 // コメントしたユーザ名
735                 String username = s.getUser().getScreenName();
736                 this.tweetBoxPane.setText("@" + username + " ");
737
738                 // 情報表示
739                 this.information(username + "さんに返信");
740         }
741
742         /**
743          * reply All設定
744          */
745         public void actionSetReplyAllStatusToTweetBoxPane() {
746                 // 選択し多分
747                 this.setReplyStatus(null);
748
749                 Status s = this.getCurrentStatus();
750                 if (s.isRetweet()) {
751                         s = s.getRetweetedStatus();
752                 }
753                 // コメントしたユーザ名
754                 String username = s.getUser().getScreenName();
755                 this.tweetBoxPane.setText("@" + username + " ");
756
757                 // 情報表示
758                 this.information(username + "さんに返信");
759         }
760
761         /**
762          * 引用Tweet
763          */
764         public void actionSetQuoteStatusToTweetBoxPane() {
765                 // 選択した部分
766                 this.setReplyStatus(currentStatus);
767                 Status s = this.getCurrentStatus();
768                 if (s.isRetweet()) {
769                         s = s.getRetweetedStatus();
770                 }
771                 // コメントしたユーザ名
772                 String username = s.getUser().getScreenName();
773                 // コメント
774                 String message = s.getText();
775                 this.tweetBoxPane.setText("QT @" + username + ": " + message);
776
777                 // 情報表示
778                 this.information(username + "さんのメッセージを引用ツイート");
779         }
780
781         /**
782          * 選択したtweetを非公式RT
783          */
784         public void actionCopySelectedStatusToTweetBoxPane() {
785                 Status s = this.getCurrentStatus();
786                 if (s.isRetweet()) {
787                         s = s.getRetweetedStatus();
788                 }
789                 // コメントしたユーザ名
790                 String username = s.getUser().getScreenName();
791                 // コメント
792                 String message = s.getText();
793                 this.tweetBoxPane.setText("RT @" + username + ": " + message);
794         }
795
796         /**
797          * 詳細情報表示ボタンを押した時の動作
798          * 
799          * @param e
800          */
801         public void actionDetailInfoButton(ActionEvent e) {
802                 if (detailInfoPanel.isVisible()) {
803                         detailInfoPanel.setVisible(false);
804                 } else {
805                         detailInfoPanel.setVisible(true);
806                 }
807         }
808
809         /**
810          * 詳細情報ボタンが表示されているか
811          * 
812          * @return
813          */
814         public boolean isDetailInfoPanelVisible() {
815                 return detailInfoPanel.isVisible();
816         }
817
818         /**
819          * 書き込みメッセージボックスの表示ONOFFボタンを押した時の動作
820          * 
821          * @param e
822          */
823         public void actionShowTweetboxButton(ActionEvent e) {
824                 if (this.tweetBoxRegionPane.isVisible()) {
825                         this.tweetBoxRegionPane.setVisible(false);
826                 } else {
827                         this.tweetBoxRegionPane.setVisible(true);
828                 }
829         }
830
831         /**
832          * 書き込みメッセージボックス領域が表示されているか
833          */
834         public boolean isShowTweetBoxVisible() {
835                 return this.tweetBoxRegionPane.isVisible();
836         }
837
838         /**
839          * 選択しているタブを削除
840          */
841         public void actionRemoveFocusedTabbedTable() {
842                 int selected = this.tweetMainTab.getSelectedIndex();
843                 actionRemoveTabbedTable(selected);
844         }
845
846         /**
847          * 指定したIDのタブを削除
848          * 
849          * @param timerID
850          */
851         public void actionRemoveTabbedTable(String timerID) {
852                 int deleteTabIndex = -1;
853
854                 for (int i = 0; i < tweetTabbedTableList.size(); i++) {
855                         TweetTabbedTable table = tweetTabbedTableList.get(i);
856                         if (table.getTimerID().equals(timerID)) {
857                                 // 消したいタブが見つかった
858                                 deleteTabIndex = i;
859                                 break;
860                         }
861                 }
862
863                 if (deleteTabIndex >= 0) {
864                         int selected = this.tweetTabbedTableList.get(deleteTabIndex)
865                                         .getTabSetNum();
866                         // タブを削除
867                         this.tweetMainTab.remove(selected);
868                         // 削除
869                         this.tweetTabbedTableList.remove(deleteTabIndex);
870                         // 自動更新しているタブを削除
871                         this.tweetTaskManager.shutdownTask(timerID);
872                         // ID削除
873                         TimerID idManager = TimerID.getInstance();
874                         idManager.removeID(timerID);
875
876                         // checkboxの状態更新
877                         this.updateCheckboxInformation();
878                         //設定保存
879                         try {
880                                 saveProperties();
881                         } catch (IOException e) {
882                                 e.printStackTrace();
883                         }
884                 }
885         }
886
887         /**
888          * 指定した場所にあるタブを削除
889          * 
890          * @param removeTabIndex
891          */
892         public void actionRemoveTabbedTable(int removeTabIndex) {
893                 int selected = removeTabIndex;
894                 // タブの何番目に消したいテーブルがあるのかと,tweetTabbedTableListの何番目に消したいテーブルがあるのかは違う
895                 // これを探してくる必要がある
896
897                 // 選択したタブのテーブルを取得
898                 int deleteTabIndex = -1;
899                 for (int i = 0; i < tweetTabbedTableList.size(); i++) {
900                         TweetTabbedTable table = tweetTabbedTableList.get(i);
901                         if (selected == table.getTabSetNum()) {
902                                 // 消したいタブが見つかった
903                                 deleteTabIndex = i;
904                                 break;
905                         }
906                 }
907
908                 if (deleteTabIndex >= 0) {
909                         // タブを削除
910                         this.tweetMainTab.remove(selected);
911                         // タブのタイマーID
912                         String timerID = this.tweetTabbedTableList.get(deleteTabIndex)
913                                         .getTimerID();
914                         // 削除
915                         this.tweetTabbedTableList.remove(deleteTabIndex);
916                         // 自動更新しているタブを削除
917                         this.tweetTaskManager.shutdownTask(timerID);
918                         // ID削除
919                         TimerID idManager = TimerID.getInstance();
920                         idManager.removeID(timerID);
921
922                         // checkboxの状態更新
923                         this.updateCheckboxInformation();
924                         //設定保存
925                         try {
926                                 saveProperties();
927                         } catch (IOException e) {
928                                 e.printStackTrace();
929                         }
930                 }
931         }
932
933         /**
934          * 終了ボタンを押した時の動作
935          * 
936          * @param e
937          */
938         public void actionExitButton(ActionEvent e) {
939                 System.exit(0);
940         }
941
942         /**
943          * 選択した発言をブラウザで開く
944          */
945         public void actionOpenStatusURL() {
946                 try {
947                         // ユーザ名
948                         String userName = this.getCurrentStatus().getUser().getScreenName();
949                         // 発言のstatusID
950                         long statusID = this.getCurrentStatus().getId();
951                         Desktop.getDesktop().browse(
952                                         new URI(TWITTER_URL + userName + "/statuses/" + statusID));
953                 } catch (Exception ex) {
954                         ex.printStackTrace();
955                         JOptionPane.showMessageDialog(null, "エラーによりブラウザを起動できませんでした.",
956                                         "Error", JOptionPane.ERROR_MESSAGE);
957                 }
958         }
959
960         /**
961          * 選択したユーザのFavを開く
962          */
963         public void actionOpenUserFav() {
964                 try {
965                         Status s = this.getCurrentStatus();
966                         if (s.isRetweet()) {
967                                 s = s.getRetweetedStatus();
968                         }
969                         String userName = s.getUser().getScreenName();
970                         this.actionAddFavoriteTab(userName);
971                 } catch (Exception ex) {
972                         ex.printStackTrace();
973                 }
974         }
975
976         /**
977          * 自分自身のFavを開く
978          */
979         public void actionOpenFav() {
980                 String username = this.tweetManager.getScreenName();
981                 this.actionAddFavoriteTab(username);
982         }
983
984         /**
985          * 選択したユーザ情報をブラウザで開く
986          */
987         public void actionOpenUserURL() {
988                 try {
989                         Status s = this.getCurrentStatus();
990                         if (s.isRetweet()) {
991                                 s = s.getRetweetedStatus();
992                         }
993                         String userName = s.getUser().getScreenName();
994                         Desktop.getDesktop().browse(new URI(TWITTER_URL + userName));
995                 } catch (Exception ex) {
996                         ex.printStackTrace();
997                         JOptionPane.showMessageDialog(null, "エラーによりブラウザを起動できませんでした.",
998                                         "Error", JOptionPane.ERROR_MESSAGE);
999                 }
1000         }
1001
1002         /**
1003          * Tweet取得時間情報を更新
1004          */
1005         public void actionRefreshTime() {
1006                 // タブに存在する時間情報を更新
1007                 for (TweetTabbedTable t : this.tweetTabbedTableList) {
1008                         TweetTableModel model = t.getModel();
1009                         if (model != null) {
1010                                 model.refreshTime();
1011                         }
1012                 }
1013         }
1014
1015         /**
1016          * TweetMessageBox内にある#ハッシュタグ の部分をa hrefリンクに変換
1017          * 
1018          * @param message
1019          */
1020         public String actionReplaceTweetMessageBoxHashTab(String message) {
1021                 // #で始まる情報
1022                 Pattern userPtn = Pattern.compile("#[0-9A-Z_]+",
1023                                 Pattern.CASE_INSENSITIVE);
1024                 Matcher matcher = userPtn.matcher(message);
1025
1026                 // #で始まる情報一覧を抜き出す
1027                 Set<String> findList = new TreeSet<String>();
1028                 while (matcher.find()) {
1029                         findList.add(matcher.group(0));
1030                 }
1031                 // 指定した情報をすべてリンクへ変更
1032                 for (String f : findList) {
1033                         try {
1034                                 message = message.replaceAll(f + "$|" + f + "\\s", "<a href=\""
1035                                                 + SEARCH_TWITTER_URL + SEARCH_QUERY
1036                                                 + URLEncoder.encode(f, DEFAULT_CHARACTER_ENCODING)
1037                                                 + "\">" + "$0</a>");
1038                         } catch (UnsupportedEncodingException e) {
1039                                 e.printStackTrace();
1040                         }
1041                 }
1042                 return message;
1043         }
1044
1045         /**
1046          * TweetMessageBox内にあるリンクをa hrefリンクに変換
1047          * 
1048          * @param message
1049          */
1050         public String actionReplaceTweetMessageBoxURLLink(String message) {
1051                 Matcher matcher = convURLLinkPtn.matcher(message);
1052                 return matcher.replaceAll("<a href=\"$0\">$0</a>");
1053         }
1054
1055         /**
1056          * @ユーザ名の部分をa hrefリンクに変換
1057          * @param message
1058          */
1059         public String actionReplaceTweetMessageBoxUserInfo(String message) {
1060                 // @で始まる情報
1061                 Pattern userPtn = Pattern.compile("@[0-9A-Z_]+",
1062                                 Pattern.CASE_INSENSITIVE);
1063                 Matcher matcher = userPtn.matcher(message);
1064                 // @で始まるユーザ名一覧を抜き出す
1065                 Set<String> findList = new TreeSet<String>();
1066                 while (matcher.find()) {
1067                         findList.add(matcher.group(0));
1068                 }
1069                 // 指定したユーザ名をすべてリンクへ変更
1070                 for (String f : findList) {
1071                         message = message.replaceAll(f, "<a href=\"" + TWITTER_URL
1072                                         + f.substring(1) + "\">" + f + "</a>");
1073                 }
1074                 return message;
1075         }
1076
1077         /**
1078          * まだ見ていないdirectMessage数を0にする
1079          */
1080         public void actionResetUncheckedDirectMessageCount() {
1081                 uncheckedDirectMessageCount = 0;
1082                 tweetMainTab.setTitleAt(2, TAB_DIRECT_MESSAGE_STRING);
1083         }
1084
1085         /**
1086          * まだ見ていないmention数を0にする
1087          */
1088         public void actionResetUncheckedMentionTweetCount() {
1089                 uncheckedMentionTweetCount = 0;
1090                 tweetMainTab.setTitleAt(1, TAB_MENTION_STRING);
1091         }
1092
1093         /**
1094          * まだ見ていないtweet数を0にする
1095          */
1096         public void actionResetUncheckedTimelineTweetCount() {
1097                 uncheckedTimelineTweetCount = 0;
1098                 tweetMainTab.setTitleAt(0, TAB_TIMELINE_STRING);
1099         }
1100
1101         /**
1102          * 選択したユーザの発言を開く
1103          */
1104         public void actionSelectedUserTimeline() {
1105                 Status status = null;
1106                 if (this.getCurrentStatus().isRetweet()) {
1107                         status = this.getCurrentStatus().getRetweetedStatus();
1108                 } else {
1109                         status = this.getCurrentStatus();
1110                 }
1111                 String username = status.getUser().getScreenName();
1112                 // ユーザ
1113                 actionAddUserTimelineTab(username, this.getGetTimelinePeriod());
1114         }
1115
1116         /**
1117          * 選択したユーザが作成したリスト一覧を表示
1118          * 
1119          * @param selection
1120          */
1121         public void actionShowSelectedUserList(ListGetterSelection selection) {
1122                 Status status = null;
1123                 if (this.getCurrentStatus().isRetweet()) {
1124                         status = this.getCurrentStatus().getRetweetedStatus();
1125                 } else {
1126                         status = this.getCurrentStatus();
1127                 }
1128                 String username = status.getUser().getScreenName();
1129                 actionShowUserListDialog(status.getUser().getScreenName(), selection);
1130         }
1131
1132         /**
1133          * 選択しているツイートをお気に入りに追加
1134          */
1135         public void actionCreateFavorite() {
1136                 Status status = null;
1137                 if (this.getCurrentStatus().isRetweet()) {
1138                         status = this.getCurrentStatus().getRetweetedStatus();
1139                 } else {
1140                         status = this.getCurrentStatus();
1141                 }
1142                 // 選択しているtweetのstatus id
1143                 long statusID = status.getId();
1144                 // コメントしたユーザ名
1145                 String username = status.getUser().getScreenName();
1146                 // コメント
1147                 String message = status.getText();
1148                 // 発言が長すぎる場合,後半をカット
1149                 if (message.length() > 30) {
1150                         message = message.substring(0, 30) + " ...(以下略)";
1151                 }
1152                 // Retweetしていいかどうかの確認
1153                 int ret = JOptionPane.showConfirmDialog(mainFrame, username + " さんの発言:"
1154                                 + message + "\nをお気に入りに追加しますか?", "Favの確認",
1155                                 JOptionPane.YES_NO_OPTION);
1156                 if (ret == JOptionPane.YES_OPTION) {
1157                         try {
1158                                 // Retweetを行う
1159                                 this.tweetManager.createFavorite(statusID);
1160                         } catch (TwitterException e) {
1161                                 JOptionPane.showMessageDialog(null, "エラーによりお気に入りに追加できませんでした.",
1162                                                 "Fav Error", JOptionPane.ERROR_MESSAGE);
1163                         }
1164                 }
1165         }
1166
1167         /**
1168          * 選択しているツイートをお気に入りから外す
1169          */
1170         public void actionDestroyFavorite() {
1171                 Status status = null;
1172                 if (this.getCurrentStatus().isRetweet()) {
1173                         status = this.getCurrentStatus().getRetweetedStatus();
1174                 } else {
1175                         status = this.getCurrentStatus();
1176                 }
1177                 // 選択しているtweetのstatus id
1178                 long statusID = status.getId();
1179                 // コメントしたユーザ名
1180                 String username = status.getUser().getScreenName();
1181                 // コメント
1182                 String message = status.getText();
1183                 // 発言が長すぎる場合,後半をカット
1184                 if (message.length() > 30) {
1185                         message = message.substring(0, 30) + " ...(以下略)";
1186                 }
1187                 // Retweetしていいかどうかの確認
1188                 int ret = JOptionPane.showConfirmDialog(mainFrame, username + " さんの発言:"
1189                                 + message + "\nをお気に入りから削除しますか?", "Favの確認",
1190                                 JOptionPane.YES_NO_OPTION);
1191                 if (ret == JOptionPane.YES_OPTION) {
1192                         try {
1193                                 // Retweetを行う
1194                                 this.tweetManager.destroyFavorite(statusID);
1195                         } catch (TwitterException e) {
1196                                 JOptionPane.showMessageDialog(null, "エラーによりお気に入りから削除できませんでした.",
1197                                                 "Fav Error", JOptionPane.ERROR_MESSAGE);
1198                         }
1199                 }
1200         }
1201
1202         /**
1203          * 現在選択しているステータスを公式Retweet
1204          */
1205         public void actionRetweet() {
1206                 Status status = null;
1207                 if (this.getCurrentStatus().isRetweet()) {
1208                         status = this.getCurrentStatus().getRetweetedStatus();
1209                 } else {
1210                         status = this.getCurrentStatus();
1211                 }
1212
1213                 // 選択しているtweetのstatus id
1214                 long statusID = status.getId();
1215                 // コメントしたユーザ名
1216                 String username = status.getUser().getScreenName();
1217                 // コメント
1218                 String message = status.getText();
1219                 // 発言が長すぎる場合,後半をカット
1220                 if (message.length() > 30) {
1221                         message = message.substring(0, 30) + " ...(以下略)";
1222                 }
1223                 // Retweetしていいかどうかの確認
1224                 int ret = JOptionPane.showConfirmDialog(mainFrame, username + " さんの発言:"
1225                                 + message + "\nをRetweetしますか?", "Retweetの確認",
1226                                 JOptionPane.YES_NO_OPTION);
1227                 if (ret == JOptionPane.YES_OPTION) {
1228                         try {
1229                                 // Retweetを行う
1230                                 this.tweetManager.retweet(statusID);
1231                         } catch (TwitterException e) {
1232                                 JOptionPane.showMessageDialog(null, "エラーによりRetweetできませんでした.",
1233                                                 "Retweet Error", JOptionPane.ERROR_MESSAGE);
1234                         }
1235                 }
1236         }
1237
1238         /**
1239          * テーブルの高さを更新
1240          * 
1241          * @param height
1242          */
1243         public void updateTableHeight(int height) {
1244                 this.tableElementHeight = height;
1245                 for (TweetTabbedTable t : this.tweetTabbedTableList) {
1246                         t.getTable().setRowHeight(tableElementHeight);
1247                 }
1248         }
1249
1250         /**
1251          * ダイレクトメッセージダイアログ表示
1252          */
1253         public void actionShowDirectMessageDialog() {
1254                 // ダイレクトメッセージ送信用ダイアログを開く
1255                 Point loc = getDirectMessageDialog().getLocation();
1256                 // loc.translate(20, 20);
1257                 DirectMessageDialog dialog = getDirectMessageDialog();
1258                 // dialog.setLocation(loc);
1259                 dialog.setLocationRelativeTo(null);
1260                 dialog.setVisible(true);
1261                 dialog.setUserInformation(this.selectedUsername,
1262                                 this.selectedUserImageURL, this.tweetManager);
1263         }
1264
1265         /**
1266          * Aboutダイアログを表示
1267          */
1268         public void actionShowAboutDialog() {
1269                 Point loc = getDirectMessageDialog().getLocation();
1270                 // loc.translate(20, 20);
1271                 AboutDialog dialog = getAboutDialog();
1272                 dialog.setLocationRelativeTo(null);
1273                 // dialog.setLocation(loc);
1274                 dialog.setVisible(true);
1275         }
1276
1277         /**
1278          * アカウントダイアログを表示
1279          */
1280         public void actionShowAccountDialog() {
1281                 // TODO: location取得のコードおかしい
1282                 Point loc = getDirectMessageDialog().getLocation();
1283                 // loc.translate(20, 20);
1284                 AccountDialog dialog = getAccountDialog();
1285                 dialog.setLocationRelativeTo(null);
1286                 // dialog.setLocation(loc);
1287                 dialog.setVisible(true);
1288         }
1289
1290         /**
1291          * Twitter全体からキーワード検索ダイアログを表示
1292          */
1293         public void actionShowKeywordSearchDialog() {
1294                 Point loc = getDirectMessageDialog().getLocation();
1295                 KeywordSearchDialog dialog = getKeywordSearchDialog();
1296                 dialog.setSearchWord("");
1297                 dialog.setLocationRelativeTo(null);
1298                 dialog.setVisible(true);
1299         }
1300
1301         /**
1302          * Twitter全体からキーワード検索ダイアログを表示
1303          * 
1304          * @param searchWord
1305          *            searchwordボックスに予め設定するワード
1306          */
1307         public void actionShowKeywordSearchDialog(String searchWord) {
1308                 Point loc = getDirectMessageDialog().getLocation();
1309                 KeywordSearchDialog dialog = getKeywordSearchDialog();
1310                 dialog.setSearchWord(searchWord);
1311                 dialog.setLocationRelativeTo(null);
1312                 dialog.setVisible(true);
1313         }
1314
1315         /**
1316          * 指定したユーザ検索ダイアログを表示
1317          */
1318         public void actionShowUserSearchDialog() {
1319             UserSearchDialog dialog = getUserSearchDialog();
1320             dialog.setLocationRelativeTo(null);
1321             dialog.setVisible(true);
1322         }
1323
1324         /**
1325          * ハッシュタグ検索ダイアログを表示
1326          */
1327         public void actionShowHashtagSearchDialog() {
1328                 Point loc = getDirectMessageDialog().getLocation();
1329                 HashtagSearchDialog dialog = getHashtagSearchDialog();
1330                 dialog.setLocationRelativeTo(null);
1331                 dialog.setVisible(true);
1332         }
1333
1334         /**
1335          * リストダイアログを表示
1336          * 
1337          * @param listUserName
1338          *            リストを保持しているユーザの名前
1339          * @param selection
1340          *            CREATED: 指定したユーザが作成したリスト SUBSCRIPTION: 指定したユーザがフォローしているリスト
1341          *            MEMBERSHIPS: 指定したユーザが追加されているリスト
1342          */
1343         public void actionShowUserListDialog(String listUserName,
1344                         ListGetterSelection selection) {
1345                 UserListDialog dialog = getUserListDialog(listUserName, selection);
1346                 Point loc = dialog.getLocation();
1347                 dialog.setLocationRelativeTo(null);
1348                 dialog.setVisible(true);
1349         }
1350
1351         /**
1352          * tweetBoxPaneに書かれた文字をつぶやく
1353          */
1354         public void actionTweet() {
1355                 boolean isTweet = false;
1356                 try {
1357                         if (this.replyStatus != null) {
1358                                 tweetManager.replyTweet(tweetBoxPane.getText(),
1359                                                 this.replyStatus.getId());
1360                         } else {
1361                                 tweetManager.tweet(tweetBoxPane.getText());
1362                         }
1363                         isTweet = true;
1364                 } catch (Exception e) {
1365                         e.printStackTrace();
1366                 }
1367
1368                 if (isTweet) {
1369                         // ツイートした旨を表示
1370                         this.information("メッセージをつぶやきました. 発言:" + tweetBoxPane.getText());
1371                         tweetBoxPane.setText(""); // テキストをクリア
1372                 } else {
1373                         this.information("つぶやきに失敗しました");
1374                         JOptionPane.showMessageDialog(null,
1375                                         "つぶやきに失敗しました。文字数がオーバーしているか、ツイッターに接続ができませんでした。",
1376                                         "Tweet Error", JOptionPane.ERROR_MESSAGE);
1377                 }
1378
1379         }
1380
1381         /**
1382          * Tweet情報を更新
1383          * 
1384          * @param e
1385          */
1386         public void actionUpdateButton(java.awt.event.ActionEvent e) {
1387                 try {
1388                         // タブ上に存在するテーブルの情報を更新
1389                         for (TweetTabbedTable t : this.tweetTabbedTableList) {
1390                                 String timerID = t.getTimerID();
1391                                 this.tweetTaskManager.resetTask(timerID, true);
1392                         }
1393
1394                         // API残り回数を取得
1395                         int remainingHits = tweetManager.getRateLimitStatus()
1396                                         .getRemainingHits();
1397                         // 取得したコメント数をステータスバーに表示
1398                         information("新しいツイートを取得しました. (APIリクエスト残数は" + remainingHits + "回です)");
1399                 } catch (Exception e1) {
1400                         e1.printStackTrace();
1401                 }
1402         }
1403
1404         /**
1405          * 新しく追加したタブにフォーカスを移す
1406          */
1407         public void actionRequestForusToLastTab() {
1408                 int lasttab = this.tweetMainTab.getTabCount() - 1;
1409                 if (lasttab >= 0) {
1410                         this.tweetMainTab.setSelectedIndex(lasttab);
1411                 }
1412         }
1413
1414         /**
1415          * 指定した番号のタブにフォーカスを移す
1416          * 
1417          * @param index
1418          */
1419         public void actionRequestFocusToTab(int index) {
1420                 if (index >= 0) {
1421                         this.tweetMainTab.setSelectedIndex(index);
1422                 }
1423         }
1424
1425         /**
1426          * 選択しているタブにあるテーブル情報だけを更新
1427          */
1428         public void actionFocusedTableUpdate() {
1429                 int selected = this.tweetMainTab.getSelectedIndex();
1430                 try {
1431                         if (selected >= 0) {
1432                                 // タブ上に存在するテーブルの情報を更新
1433                                 TweetTabbedTable t = this.tweetTabbedTableList.get(selected);
1434                                 String timerID = t.getTimerID();
1435                                 this.tweetTaskManager.resetTask(timerID, true);
1436                                 // API残り回数を取得
1437                                 int remainingHits = tweetManager.getRateLimitStatus()
1438                                                 .getRemainingHits();
1439                                 // 取得したコメント数をステータスバーに表示
1440                                 information(t.getTitle() + "タブのツイートを" + t.getUncheckedTweet()
1441                                                 + "件取得しました. (APIリクエスト残数は" + remainingHits + "回です)");
1442                         }
1443                 } catch (Exception e1) {
1444                         e1.printStackTrace();
1445                 }
1446         }
1447
1448         /**
1449          * つぶやける残り文字数の更新
1450          * 
1451          * @param e
1452          */
1453         public void actionUpdateTweetMessageCount() {
1454                 int len = 140 - (tweetBoxPane.getText().length());
1455                 boolean over = false;
1456                 if (len < 0) {
1457                         // len = 0;
1458                         over = true;
1459                 }
1460
1461                 if (over) {
1462                         tweetMessageCountLabel.setForeground(Color.RED);
1463                         // オーバーしたことを伝える
1464                         tweetMessageCountLabel.setText("Over(" + len + ")");
1465                 } else {
1466                         tweetMessageCountLabel.setForeground(Color.BLACK);
1467                         // 残り文字数
1468                         tweetMessageCountLabel.setText(len + "");
1469                 }
1470
1471                 // 残りつぶやき数140の場合,reply状態も解除する
1472                 if (len == 140) {
1473                         this.setReplyStatus(null);
1474                 }
1475         }
1476
1477         /**
1478          * 基本設定用ダイアログを取得
1479          * 
1480          * @return
1481          */
1482         public ConfigurationDialog getConfigurationDialog() {
1483                 if (configurationDialog == null) {
1484                         configurationDialog = new ConfigurationDialog(mainFrame, true, this);
1485                 }
1486                 return configurationDialog;
1487         }
1488
1489         /**
1490          * リストダイアログを取得
1491          * 
1492          * @param listUserName
1493          *            リストを保持しているユーザの名前
1494          * @param selection
1495          * @return
1496          */
1497         public UserListDialog getUserListDialog(String listUserName,
1498                         ListGetterSelection selection) {
1499                 UserListGetter getter = null;
1500                 switch (selection) {
1501                 case CREATED:
1502                         getter = new UserListSpecificUserListsGetter(tweetManager);
1503                         break;
1504                 case MEMBERSHIPS:
1505                         getter = new UserListMembershipsGetter(tweetManager);
1506                         break;
1507                 case SUBSCRIPTION: /* fall through */
1508                 default:
1509                         getter = new UserListSubscriptionGetter(tweetManager);
1510                         break;
1511                 }
1512                 userListDialog = new UserListDialog(mainFrame, true, this, getter,
1513                                 listUserName);
1514                 return userListDialog;
1515         }
1516
1517         /**
1518          * 自身のスクリーン名を取得
1519          * 
1520          * @return
1521          */
1522         public String getScreenName() {
1523                 return tweetManager.getScreenName();
1524         }
1525
1526         /**
1527          * twitter全体からキーワード検索ダイアログを表示
1528          * 
1529          * @return
1530          */
1531         public KeywordSearchDialog getKeywordSearchDialog() {
1532                 if (keywordSearchDialog == null) {
1533                         keywordSearchDialog = new KeywordSearchDialog(mainFrame, true, this);
1534                 }
1535                 return keywordSearchDialog;
1536         }
1537
1538         /**
1539          * ユーザ検索ダイアログを表示
1540          * @return
1541          */
1542         public UserSearchDialog getUserSearchDialog() {
1543             if( this.userSearchDialog == null ) {
1544                 this.userSearchDialog = new UserSearchDialog(mainFrame, true, this);
1545             }
1546             return this.userSearchDialog;
1547         }
1548
1549         /**
1550          * hashtag検索ダイアログ
1551          * 
1552          * @return
1553          */
1554         public HashtagSearchDialog getHashtagSearchDialog() {
1555                 if (hashtagSearchDialog == null) {
1556                         hashtagSearchDialog = new HashtagSearchDialog(mainFrame, true,
1557                                         this, tweetManager);
1558                 }
1559                 return hashtagSearchDialog;
1560         }
1561
1562         /**
1563          * アカウント情報設定ダイアログを取得
1564          * 
1565          * @return
1566          */
1567         public AccountDialog getAccountDialog() {
1568                 if (accountDialog == null) {
1569                         accountDialog = new AccountDialog(mainFrame, true, tweetManager,
1570                                         this);
1571                 }
1572                 return accountDialog;
1573         }
1574
1575         /**
1576          * ダイレクトメッセージ送信用ダイアログを取得
1577          * 
1578          * @return
1579          */
1580         public DirectMessageDialog getDirectMessageDialog() {
1581                 if (directMessageDialog == null) {
1582                         directMessageDialog = new DirectMessageDialog(mainFrame);
1583                         directMessageDialog.setTitle("ダイレクトメッセージを送信");
1584                 }
1585                 return directMessageDialog;
1586         }
1587
1588         /**
1589          * テーブルで選択したツイートを詳細情報としてセット
1590          * 
1591          * @param table
1592          */
1593         public void setDetailInformationFromTable(JTable table) {
1594                 int sc = table.getSelectedRowCount();
1595                 String infoMessage = "";
1596
1597                 // 選択している行が1行だけの場合,情報を表示する
1598                 if (sc == 1 && table != null) {
1599                         Status st = getTweetTableInformation(table, table.getModel());
1600                         // RTの場合,もとの発言を表示
1601                         if (st.isRetweet()) {
1602                                 st = st.getRetweetedStatus();
1603                         }
1604                         infoMessage = st.getText();
1605                         // メッセージのHTMLエンコードを行う
1606                         infoMessage = HTMLEncode.encode(infoMessage);
1607                         // tweetMessageBox内のURLをhtmlリンクへ変換
1608                         infoMessage = actionReplaceTweetMessageBoxURLLink(infoMessage);
1609                         // @ユーザ情報をhtmlリンクへ変換
1610                         infoMessage = actionReplaceTweetMessageBoxUserInfo(infoMessage);
1611                         // #ハッシュタグ情報をhtmlリンクへ変換
1612                         infoMessage = actionReplaceTweetMessageBoxHashTab(infoMessage);
1613                         // 詳細情報にテーブルで選択した人のツイート情報を表示
1614                         tweetMessageBox.setText(infoMessage);
1615                         // user icon
1616                         // アイコンをキャッシュから取得
1617                         ImageIcon icon = TwitterImageCache.getInstance().getProfileImage(
1618                                         st.getUser().getProfileImageURL().toString());
1619                         userImageLabel.setIcon(icon);
1620                         // user name and id
1621                         userNameLabel.setText(st.getUser().getName() + " / "
1622                                         + st.getUser().getScreenName());
1623                         // update Time
1624                         updateTimeLabel.setText(DateFormat.getInstance().format(
1625                                         st.getCreatedAt()));
1626                         // ユーザ自己紹介文
1627                         userIntroBox.setText(st.getUser().getDescription());
1628                         // フォローされている数
1629                         followerLabel.setText(st.getUser().getFollowersCount() + "");
1630                         // フォローしている数
1631                         followingLabel.setText(st.getUser().getFriendsCount() + "");
1632                         // 現在地
1633                         locationLabel.setText(st.getUser().getLocation());
1634                         // Web
1635                         if (st.getUser().getURL() != null) {
1636                                 userWebBox.setText("<a href=\"" + st.getUser().getURL() + "\">"
1637                                                 + st.getUser().getScreenName() + "のWebを開く" + "</a>");
1638                         } else {
1639                                 userWebBox.setText("");
1640                         }
1641                         // client
1642                         clientNameLabel.setText(" via " + st.getSource());
1643                         // Update
1644                         updateLabel.setText(st.getUser().getStatusesCount() + "");
1645                 }
1646         }
1647
1648         /**
1649          * 
1650          * @return
1651          */
1652         public AboutDialog getAboutDialog() {
1653                 if (aboutDialog == null) {
1654                         aboutDialog = new AboutDialog(mainFrame, true);
1655                 }
1656                 return aboutDialog;
1657         }
1658
1659         /**
1660          * テーブルで選択した場所のTweet情報を取得
1661          * 
1662          * @return
1663          */
1664         public Status getTweetTableInformation(JTable table, TableModel model) {
1665                 int index = table.convertRowIndexToModel(table.getSelectedRow());
1666                 Status status = null;
1667                 if (model instanceof TweetTableModel) {
1668                         status = ((TweetTableModel) model).getTweetStatus(index);
1669                         // 現在選択したセルのユーザ名を保存しておく
1670                         this.selectedUsername = status.getUser().getScreenName();
1671                         // 現在選択したセルのユーザURLを保存しておく
1672                         this.selectedUserImageURL = status.getUser().getProfileImageURL();
1673                         // 選択したStatusを保存しておく
1674                         this.setCurrentStatus(status);
1675                 }
1676                 return status;
1677         }
1678
1679         /**
1680          * ステータスバーに情報を表示する
1681          * 
1682          * @param message
1683          */
1684         public void information(String message) {
1685                 statusBarLabel.setText(message);
1686         }
1687
1688         /**
1689          * 前回タイムラインタブを開いていたか
1690          * @return
1691          */
1692         public boolean isTempOpenedTimelineTab() {
1693                 return isTempOpenedTimelineTab;
1694         }
1695
1696         /**
1697          * 前回メンションタブを開いていたか
1698          * @return
1699          */
1700         public boolean isTempOpenedMentionTab() {
1701                 return isTempOpenedMentionTab;
1702         }
1703
1704         /**
1705          * 前回DMタブを開いていたか
1706          * @return
1707          */
1708         public boolean isTempOpenedDMTab() {
1709                 return isTempOpenedDMTab;
1710         }
1711
1712         /**
1713          * 前回SendDMタブを開いていたか
1714          * @return
1715          */
1716         public boolean isTempOpenedSendDMTab() {
1717                 return isTempOpenedSendDMTab;
1718         }
1719
1720         /**
1721          * 設定ファイルを読み込む
1722          * 
1723          * @throws IOException
1724          * @throws FileNotFoundException
1725          */
1726         public void loadProperties() throws FileNotFoundException, IOException {
1727                 if (property == null) {
1728                         this.property = new Properties();
1729                 }
1730                 property.load(new FileInputStream("./" + PROPERTIES_DIRECTORY + "/"
1731                                 + BASIC_SETTING_FILENAME));
1732                 // 設定読み込み
1733                 String gtp = this.property.getProperty("getTimelinePeriod");
1734                 String gmp = this.property.getProperty("getMentionPeriod");
1735                 String gdmp = this.property.getProperty("getDirectMessagePeriod");
1736                 String gsdmp = this.property.getProperty("getSendDirectMessagePeriod");
1737
1738                 String ntrgb = this.property.getProperty("newTableColorRGB");
1739
1740                 this.tlFontName = this.property.getProperty("tlFontName");
1741                 this.detailFontName = this.property.getProperty("detailFontName");
1742
1743                 String tfs = this.property.getProperty("tlFontSize");
1744                 String dfs = this.property.getProperty("detailFontSize");
1745                 String teh = this.property.getProperty("tableElementHeight");
1746
1747                 // メインフレームの大きさ
1748                 String mfw = this.property.getProperty("mainFrameWidth");
1749                 String mfh = this.property.getProperty("mainFrameHeight");
1750
1751                 // メッセージ通知を行うか
1752                 String nm = this.property.getProperty("notifyMention");
1753                 String ndm = this.property.getProperty("notifyDirectMessage");
1754                 
1755                 //前回開いていたタブの情報
1756                 String ptl = this.property.getProperty("openTimelineTab");
1757                 String pm = this.property.getProperty("openMentionTab");
1758                 String podm = this.property.getProperty("openDirectMessageTab");
1759                 String posdmt = this.property.getProperty("openSendDirectMessageTab");
1760
1761                 try {
1762                         this.newTableColor = new Color(Integer.parseInt(ntrgb));
1763                         this.tlFontSize = Integer.parseInt(tfs);
1764                         this.detailFontSize = Integer.parseInt(dfs);
1765                         this.tableElementHeight = Integer.parseInt(teh);
1766                         this.mainFrameWidth = Integer.parseInt(mfw);
1767                         this.mainFrameHeight = Integer.parseInt(mfh);
1768
1769                         // 更新間隔
1770                         this.getTimelinePeriod = Integer.parseInt(gtp);
1771                         this.getMentionPeriod = Integer.parseInt(gmp);
1772                         this.getDirectMessagePeriod = Integer.parseInt(gdmp);
1773                         this.getSendDirectMessagePeriod = Integer.parseInt(gsdmp);
1774
1775                         // 通知関係
1776                         this.isNotifyMentionMessage = Boolean.parseBoolean(nm);
1777                         this.isNotifyDirectMessage = Boolean.parseBoolean(ndm);
1778                         
1779                         //前回開いていたタブ情報
1780                         this.isTempOpenedTimelineTab = Boolean.parseBoolean(ptl);
1781                         this.isTempOpenedMentionTab = Boolean.parseBoolean(pm);
1782                         this.isTempOpenedDMTab = Boolean.parseBoolean(podm);
1783                         this.isTempOpenedSendDMTab = Boolean.parseBoolean(posdmt);
1784                 } catch (NumberFormatException e) {
1785                         e.printStackTrace();
1786                 }
1787         }
1788
1789         /**
1790          * 設定ファイルを保存する
1791          * 
1792          * @throws IOException
1793          */
1794         public void saveProperties() throws IOException {
1795                 // 設定ファイルディレクトリを作成
1796                 File logDir = new File("./" + PROPERTIES_DIRECTORY);
1797                 if (!logDir.exists()) {
1798                         // ディレクトリが存在しないので作成する
1799                         if (logDir.mkdir() == false) {
1800                                 throw new IOException(PROPERTIES_DIRECTORY
1801                                                 + "ディレクトリを作成できませんでした.");
1802                         }
1803                 }
1804                 if (property == null) {
1805                         this.property = new Properties();
1806                 }
1807
1808                 // 情報更新間隔
1809                 this.property.setProperty("getTimelinePeriod", this.getTimelinePeriod
1810                                 + "");
1811                 this.property.setProperty("getMentionPeriod", this.getMentionPeriod
1812                                 + "");
1813                 this.property.setProperty("getDirectMessagePeriod",
1814                                 this.getDirectMessagePeriod + "");
1815                 this.property.setProperty("getSendDirectMessagePeriod",
1816                                 this.getSendDirectMessagePeriod + "");
1817
1818                 this.property.setProperty("newTableColorRGB", newTableColor.getRGB()
1819                                 + "");
1820                 this.property.setProperty("tlFontName", this.tlFontName);
1821                 this.property.setProperty("tlFontSize", this.tlFontSize + "");
1822                 this.property.setProperty("detailFontName", this.detailFontName);
1823                 this.property.setProperty("detailFontSize", this.detailFontSize + "");
1824                 this.property.setProperty("tableElementHeight", this.tableElementHeight
1825                                 + "");
1826
1827                 // main frame size
1828                 if (this.mainFrame.getExtendedState() == JFrame.NORMAL) {
1829                         this.mainFrameWidth = this.mainFrame.getWidth();
1830                         this.mainFrameHeight = this.mainFrame.getHeight();
1831                 }
1832                 this.property.setProperty("mainFrameWidth", this.mainFrameWidth + "");
1833                 this.property.setProperty("mainFrameHeight", this.mainFrameHeight + "");
1834
1835                 // メッセージ通知を行うか
1836                 this.property.setProperty("notifyMention", this.isNotifyMentionMessage
1837                                 + "");
1838                 this.property.setProperty("notifyDirectMessage",
1839                                 this.isNotifyDirectMessage + "");
1840                 
1841                 //タブの保存
1842                 this.property.setProperty("openTimelineTab", this.isExistTimelineTab() + "");
1843                 this.property.setProperty("openMentionTab", this.isExistMentionTab() + "");
1844                 this.property.setProperty("openDirectMessageTab", this.isExistDirectMessageTab() + "");
1845                 this.property.setProperty("openSendDirectMessageTab", this.isExistSendDirectMessageTab() + "");
1846
1847                 // プロパティのリストを保存
1848                 property.store(new FileOutputStream("./" + PROPERTIES_DIRECTORY + "/"
1849                                 + BASIC_SETTING_FILENAME), null);
1850         }
1851
1852         /**
1853          * newTableColorを取得します。
1854          * 
1855          * @return newTableColor
1856          */
1857         public Color getNewTableColor() {
1858                 return newTableColor;
1859         }
1860
1861         /**
1862          * newTableColorを設定します。
1863          * 
1864          * @param newTableColor
1865          *            newTableColor
1866          */
1867         public void setNewTableColor(Color newTableColor) {
1868                 this.newTableColor = newTableColor;
1869         }
1870
1871         /**
1872          * tlFontNameを取得します。
1873          * 
1874          * @return tlFontName
1875          */
1876         public String getTlFontName() {
1877                 return tlFontName;
1878         }
1879
1880         /**
1881          * tlFontNameを設定します。
1882          * 
1883          * @param tlFontName
1884          *            tlFontName
1885          */
1886         public void setTlFontName(String tlFontName) {
1887                 this.tlFontName = tlFontName;
1888         }
1889
1890         /**
1891          * tlFontSizeを取得します。
1892          * 
1893          * @return tlFontSize
1894          */
1895         public int getTlFontSize() {
1896                 return tlFontSize;
1897         }
1898
1899         /**
1900          * tlFontSizeを設定します。
1901          * 
1902          * @param tlFontSize
1903          *            tlFontSize
1904          */
1905         public void setTlFontSize(int tlFontSize) {
1906                 this.tlFontSize = tlFontSize;
1907         }
1908
1909         /**
1910          * detailFontNameを取得します。
1911          * 
1912          * @return detailFontName
1913          */
1914         public String getDetailFontName() {
1915                 return detailFontName;
1916         }
1917
1918         /**
1919          * detailFontNameを設定します。
1920          * 
1921          * @param detailFontName
1922          *            detailFontName
1923          */
1924         public void setDetailFontName(String detailFontName) {
1925                 this.detailFontName = detailFontName;
1926         }
1927
1928         /**
1929          * detailFontSizeを取得します。
1930          * 
1931          * @return detailFontSize
1932          */
1933         public int getDetailFontSize() {
1934                 return detailFontSize;
1935         }
1936
1937         /**
1938          * detailFontSizeを設定します。
1939          * 
1940          * @param detailFontSize
1941          *            detailFontSize
1942          */
1943         public void setDetailFontSize(int detailFontSize) {
1944                 this.detailFontSize = detailFontSize;
1945         }
1946
1947         /**
1948          * tableElementHeightを取得します。
1949          * 
1950          * @return tableElementHeight
1951          */
1952         public int getTableElementHeight() {
1953                 return tableElementHeight;
1954         }
1955
1956         /**
1957          * tableElementHeightを設定します。
1958          * 
1959          * @param tableElementHeight
1960          *            tableElementHeight
1961          */
1962         public void setTableElementHeight(int tableElementHeight) {
1963                 this.tableElementHeight = tableElementHeight;
1964         }
1965
1966         /**
1967          * @return the getTimelinePeriod
1968          */
1969         public int getGetTimelinePeriod() {
1970                 return getTimelinePeriod;
1971         }
1972
1973         /**
1974          * 
1975          * @param notify
1976          */
1977         public void setNotifyMention(boolean notify) {
1978                 this.isNotifyMentionMessage = notify;
1979         }
1980
1981         /**
1982          * 
1983          * @return
1984          */
1985         public boolean getNotifyMention() {
1986                 return this.isNotifyMentionMessage;
1987         }
1988
1989         /**
1990          * 
1991          * @param notify
1992          * @return
1993          */
1994         public void setNotifyDirectMessage(boolean notify) {
1995                 this.isNotifyDirectMessage = notify;
1996         }
1997
1998         /**
1999          * 
2000          * @return
2001          */
2002         public boolean getNotifyDirectMessage() {
2003                 return this.isNotifyDirectMessage;
2004         }
2005
2006         /**
2007          * @param getTimelinePeriod
2008          *            the getTimelinePeriod to set
2009          */
2010         public void setGetTimelinePeriod(int getTimelinePeriod) {
2011                 this.getTimelinePeriod = getTimelinePeriod;
2012         }
2013
2014         /**
2015          * @return the getMentionPeriod
2016          */
2017         public int getGetMentionPeriod() {
2018                 return getMentionPeriod;
2019         }
2020
2021         /**
2022          * @param getMentionPeriod
2023          *            the getMentionPeriod to set
2024          */
2025         public void setGetMentionPeriod(int getMentionPeriod) {
2026                 this.getMentionPeriod = getMentionPeriod;
2027         }
2028
2029         /**
2030          * @return the getDirectMessagePeriod
2031          */
2032         public int getGetDirectMessagePeriod() {
2033                 return getDirectMessagePeriod;
2034         }
2035
2036         /**
2037          * @param getDirectMessagePeriod
2038          *            the getDirectMessagePeriod to set
2039          */
2040         public void setGetDirectMessagePeriod(int getDirectMessagePeriod) {
2041                 this.getDirectMessagePeriod = getDirectMessagePeriod;
2042         }
2043
2044         /**
2045          * @return the getSendDirectMessagePeriod
2046          */
2047         public int getGetSendDirectMessagePeriod() {
2048                 return getSendDirectMessagePeriod;
2049         }
2050
2051         /**
2052          * @param getSendDirectMessagePeriod
2053          *            the getSendDirectMessagePeriod to set
2054          */
2055         public void setGetSendDirectMessagePeriod(int getSendDirectMessagePeriod) {
2056                 this.getSendDirectMessagePeriod = getSendDirectMessagePeriod;
2057         }
2058
2059         /**
2060          * @return the currentStatus
2061          */
2062         public Status getCurrentStatus() {
2063                 return currentStatus;
2064         }
2065
2066         /**
2067          * @param currentStatus
2068          *            the currentStatus to set
2069          */
2070         public void setCurrentStatus(Status currentStatus) {
2071                 this.currentStatus = currentStatus;
2072         }
2073
2074         /**
2075          * 
2076          * @return
2077          */
2078         public Status getReplyStatus() {
2079                 return replyStatus;
2080         }
2081
2082         /**
2083          * 
2084          * @param status
2085          * @return
2086          */
2087         public void setReplyStatus(Status status) {
2088                 this.replyStatus = status;
2089         }
2090 }