1 package twitter.gui.action;
4 import java.awt.Desktop;
5 import java.awt.Dimension;
8 import java.awt.event.ActionEvent;
10 import java.io.FileInputStream;
11 import java.io.FileNotFoundException;
12 import java.io.FileOutputStream;
13 import java.io.IOException;
14 import java.io.UnsupportedEncodingException;
17 import java.net.URLEncoder;
18 import java.text.DateFormat;
19 import java.util.ArrayList;
20 import java.util.List;
21 import java.util.Properties;
23 import java.util.TreeSet;
24 import java.util.concurrent.Executors;
25 import java.util.concurrent.ScheduledExecutorService;
26 import java.util.concurrent.ScheduledFuture;
27 import java.util.concurrent.TimeUnit;
28 import java.util.regex.Matcher;
29 import java.util.regex.Pattern;
30 import javax.swing.ImageIcon;
32 import javax.swing.JEditorPane;
33 import javax.swing.JFrame;
34 import javax.swing.JLabel;
35 import javax.swing.JOptionPane;
36 import javax.swing.JPanel;
37 import javax.swing.JScrollPane;
38 import javax.swing.JTabbedPane;
39 import javax.swing.JTable;
40 import javax.swing.JTextPane;
41 import javax.swing.table.TableCellRenderer;
42 import javax.swing.table.TableModel;
43 import javax.swing.text.Style;
44 import javax.swing.text.StyleConstants;
45 import javax.swing.text.html.HTMLDocument;
46 import javax.swing.text.html.StyleSheet;
47 import twitter.action.TweetGetter;
48 import twitter.action.TweetSearchResultGetter;
50 import twitter.gui.component.TweetCommentRenderer;
51 import twitter.gui.component.TweetTabbedTable;
52 import twitter.gui.component.TweetTableModel;
53 import twitter.gui.form.AboutDialog;
54 import twitter.gui.form.AccountDialog;
55 import twitter.gui.form.ConfigurationDialog;
56 import twitter.gui.form.DirectMessageDialog;
57 import twitter.manage.TweetConfiguration;
58 import twitter.manage.TweetManager;
59 import twitter4j.Status;
60 import twitter4j.TwitterException;
68 public class TweetMainAction {
71 * 一定時間毎にtweet情報をアップデートするタスク
76 private class TweetAutoUpdateTask implements Runnable {
78 TweetAutoUpdateTask() {
82 // 一定時間ごとにTweet情報をアップデート
84 if (currentGetTimelinePeriodNum == 0) {
86 actionTweetTableUpdate();
88 currentGetTimelinePeriodNum = (currentGetTimelinePeriodNum + 1)
89 % getTimelinePeriodNum;
91 if (currentGetMentionPeriodNum == 0) {
93 actionMentionTableUpdate();
95 currentGetMentionPeriodNum = (currentGetMentionPeriodNum + 1)
96 % getMentionPeriodNum;
98 if (currentGetDirectMessagePeriodNum == 0) {
99 // DirectMessageテーブルの情報を更新
100 actionDirectMessageTableUpdate();
102 currentGetDirectMessagePeriodNum = (currentGetDirectMessagePeriodNum + 1)
103 % getDirectMessagePeriodNum;
105 if (currentGetSendDirectMessagePeriodNum == 0) {
106 // SendDirectMessageテーブルの情報を更新
107 actionSendDirectMessageTableUpdate();
109 currentGetSendDirectMessagePeriodNum = (currentGetSendDirectMessagePeriodNum + 1)
110 % getSendDirectMessagePeriodNum;
115 } catch (Exception e1) {
116 e1.printStackTrace();
122 * 一定時間毎にtweet情報をアップデートする
127 private class TweetAutoUpdateTimer {
129 private ScheduledFuture<?> future;
130 private final ScheduledExecutorService scheduler;
131 private final Runnable task;
132 private long time = 0;
134 public TweetAutoUpdateTimer() {
135 task = new TweetAutoUpdateTask();
136 scheduler = Executors.newSingleThreadScheduledExecutor();
142 public void reset() {
144 if (future != null) {
145 future = scheduler.scheduleAtFixedRate(task, time, time,
153 public void shutdown() {
154 scheduler.shutdown();
158 * 一定時間毎にTweetUpdateTaskを実行
163 public void start(long time) {
164 future = scheduler.scheduleAtFixedRate(task, 2, time,
173 if (future != null) {
179 public static final String BASIC_SETTING_FILENAME = TweetConfiguration.BASIC_SETTING_FILENAME;
181 private static final Pattern convURLLinkPtn = Pattern.compile(
182 "(http://|https://){1}[\\w\\.\\-/:\\#\\?\\=\\&\\;\\%\\~\\+]+",
183 Pattern.CASE_INSENSITIVE);
184 // default char encoding
185 private static final String DEFAULT_CHARACTER_ENCODING = "UTF-8";
186 // 設定ファイルを保存するディレクトリ名
187 public static final String PROPERTIES_DIRECTORY = "properties";
188 // search twitterのクエリ
189 private static final String SEARCH_QUERY = "search?q=";
190 // search twitterのURL
191 private static final String SEARCH_TWITTER_URL = "http://search.twitter.com/";
192 // Direct Messageタブに表示する文字
193 public static final String TAB_DIRECT_MESSAGE_STRING = "Message";
195 public static final String TAB_MENTION_STRING = "Mention";
197 public static final String TAB_TIMELINE_STRING = "Timeline";
198 // テーブルのデータ量が以下の値を超えたら古いデータから削除
199 private static final int TABLE_ELEMENT_MAX_SIZE = 200;
201 private static final String TWITTER_URL = "http://twitter.com/";
203 private TweetAutoUpdateTimer autoUpdateTimer = null;
205 private ConfigurationDialog configurationDialog = null;
206 private int currentGetDirectMessagePeriodNum = 0;
207 private int currentGetMentionPeriodNum = 0;
208 private int currentGetSendDirectMessagePeriodNum = 0;
209 private int currentGetTimelinePeriodNum = 0;
211 private Status currentStatus = null;
213 private JPanel detailInfoPanel = null;
214 // ダイレクトメッセージ送信用ダイアログ
215 private DirectMessageDialog directMessageDialog = null;
216 // directMessageを表示するテーブル
217 private JTable directMessageTable = null;
218 // directMessageのtweetを表示するテーブルモデル
219 private TweetTableModel directMessageTableModel = null;
221 private int updatePeriod = 1;
222 // DirectMessageの取得間隔
223 private int getDirectMessagePeriodNum = 10;
225 private int getMentionPeriodNum = 5;
226 // SendDirectMessageの取得間隔
227 private int getSendDirectMessagePeriodNum = 30;
229 private int getTimelinePeriodNum = 1;
231 private Color newTableColor = new Color(224, 255, 255);
233 private String tlFontName = "Takao Pゴシック";
235 private int tlFontSize = 13;
237 private String detailFontName = "Takao Pゴシック";
239 private int detailFontSize = 13;
241 private int tableElementHeight = 50;
243 private int mainFrameWidth = 729;
245 private int mainFrameHeight = 629;
247 private JFrame mainFrame = null;
248 // メインのtweetを表示するテーブル
249 private JTable mainTweetTable = null;
251 private JTable mentionTable = null;
252 // mentionのtweetを表示するテーブルモデル
253 private TweetTableModel mentionTableModel = null;
255 private Properties property = null;
256 // 現在テーブルで選択しているユーザ画像のURL
257 private URL selectedUserImageURL = null;
258 // 現在テーブルで選択しているユーザの名前
259 private String selectedUsername = null;
260 // sendDirectMessageを表示するテーブル
261 private JTable sendDirectMessageTable = null;
262 // sendDirectMessageのtweetを表示するテーブル
263 private TweetTableModel sendDirectMessageTableModel = null;
265 private JLabel statusBarLabel = null;
267 private JTextPane tweetBoxPane = null;
268 //自分がつぶやきを書く領域のスクロールペーン
269 private JScrollPane tweetBoxScrollPane = null;
271 private JTabbedPane tweetMainTab = null;
273 private TweetManager tweetManager = null;
274 // tweetを表示するTextPane
275 private JEditorPane tweetMessageBox = null;
276 // つぶやくことができる文字数を表示するラベル
277 private JLabel tweetMessageCountLabel = null;
278 // メインのtweetを表示するテーブルモデル
279 private TweetTableModel tweetTableModel = null;
280 private int uncheckedDirectMessageCount = 0;
281 private int uncheckedMentionTweetCount = 0;
284 private JLabel userImageLabel = null;
285 private JLabel userNameLabel = null;
286 private JLabel updateTimeLabel = null;
287 private JLabel followerLabel = null;
288 private JLabel followingLabel = null;
289 private JLabel locationLabel = null;
290 private JEditorPane clientNameLabel = null;
291 private JLabel updateLabel = null;
292 private JEditorPane userIntroBox = null;
293 private JEditorPane userWebBox = null;
295 // 新しく取得したtweetでまだ参照していない数
296 private int uncheckedTimelineTweetCount = 0;
297 private AboutDialog aboutDialog = null;
299 private AccountDialog accountDialog;
301 private List<TweetTabbedTable> tweetTabbedTableList = new ArrayList<TweetTabbedTable>();
302 //ここは一時的に追加している部分 タブにすでに存在しているテーブルの数
303 private int ALREADY_TWEET_TAB_NUM = 4;
308 * @param tweetManager
309 * @param statusBarLabel
310 * @param tweetTableModel
311 * @param mentionTableModel
312 * @param directMessageTableModel
313 * @param sendDirectMessageTableModel
314 * @param mainTweetTable
315 * @param mentionTable
316 * @param directMessageTable
317 * @param sendDirectMessageTable
318 * @param tweetBoxPane
319 * @param tweetBoxScrollPane
320 * @param tweetMessageCountLabel
321 * @param detailInfoPanel
322 * @param tweetMainTab
323 * @param tweetMessageBox
324 * @param userImageLabel
325 * @param userNameLabel
326 * @param updateTimeLabel
327 * @param followerLabel
328 * @param followingLabel
329 * @param locationLabel
330 * @param clientNameLabel
332 * @param userIntroBox
335 public TweetMainAction(JFrame mainFrame,
336 TweetManager tweetManager,
337 JLabel statusBarLabel,
338 TweetTableModel tweetTableModel,
339 TweetTableModel mentionTableModel,
340 TweetTableModel directMessageTableModel,
341 TweetTableModel sendDirectMessageTableModel,
342 JTable mainTweetTable,
344 JTable directMessageTable,
345 JTable sendDirectMessageTable,
346 JTextPane tweetBoxPane,
347 JScrollPane tweetBoxScrollPane,
348 JLabel tweetMessageCountLabel,
349 JPanel detailInfoPanel,
350 JTabbedPane tweetMainTab,
351 JEditorPane tweetMessageBox,
352 JLabel userImageLabel,
353 JLabel userNameLabel,
354 JLabel updateTimeLabel,
355 JLabel followerLabel,
356 JLabel followingLabel,
357 JLabel locationLabel,
358 JEditorPane clientNameLabel,
360 JEditorPane userIntroBox,
361 JEditorPane userWebBox) {
362 this.mainFrame = mainFrame;
363 this.tweetManager = tweetManager;
364 this.statusBarLabel = statusBarLabel;
365 this.tweetTableModel = tweetTableModel;
366 this.mentionTableModel = mentionTableModel;
367 this.directMessageTableModel = directMessageTableModel;
368 this.sendDirectMessageTableModel = sendDirectMessageTableModel;
369 this.mainTweetTable = mainTweetTable;
370 this.mentionTable = mentionTable;
371 this.directMessageTable = directMessageTable;
372 this.sendDirectMessageTable = sendDirectMessageTable;
373 this.tweetBoxPane = tweetBoxPane;
374 this.tweetMessageCountLabel = tweetMessageCountLabel;
375 this.detailInfoPanel = detailInfoPanel;
376 this.tweetMainTab = tweetMainTab;
377 this.tweetMessageBox = tweetMessageBox;
378 this.tweetBoxScrollPane = tweetBoxScrollPane;
381 this.userImageLabel = userImageLabel;
382 this.userNameLabel = userNameLabel;
383 this.updateTimeLabel = updateTimeLabel;
384 this.userIntroBox = userIntroBox;
385 this.followerLabel = followerLabel;
386 this.followingLabel = followingLabel;
387 this.locationLabel = locationLabel;
388 this.userWebBox = userWebBox;
389 this.clientNameLabel = clientNameLabel;
390 this.updateLabel = updateLabel;
395 } catch (FileNotFoundException e) {
397 } catch (IOException e) {
401 updateFontInformationToComponent();
404 mainFrame.setSize(this.mainFrameWidth, this.mainFrameHeight);
405 mainFrame.setPreferredSize(new Dimension(this.mainFrameWidth, this.mainFrameHeight));
409 public void updateFontInformationToComponent() {
412 if (this.tlFontName != null) {
413 tlFont = new Font(this.tlFontName, Font.PLAIN, this.tlFontSize);
415 Font detailFont = null;
416 if (this.detailFontName != null) {
417 detailFont = new Font(this.detailFontName, Font.PLAIN,
418 this.detailFontSize);
420 this.mainTweetTable.setFont(tlFont);
421 this.mentionTable.setFont(tlFont);
422 this.directMessageTable.setFont(tlFont);
423 this.sendDirectMessageTable.setFont(tlFont);
425 // tweetメッセージボックスのフォントはhtmlレベルで変更する必要がある
426 this.tweetMessageBox.setFont(detailFont);
428 HTMLDocument doc = (HTMLDocument) this.tweetMessageBox.getDocument();
429 StyleSheet[] style = doc.getStyleSheet().getStyleSheets();
430 for (int i = style.length - 1; i >= 0; i--) {
431 Style body = style[i].getStyle("body");
433 StyleConstants.setFontFamily(body, detailFont.getFontName());
434 StyleConstants.setFontSize(body, detailFont.getSize());
438 } catch (Exception e) {
444 * ツイート検索結果を表示するタブを新しく追加
447 public void actionAddNewSearchResultTab(String searchWord) {
448 int numOfTab = this.tweetTabbedTableList.size();
450 //TODO:ここはあとで変更する必要がある.なぜなら既に追加されているタブの数は変わる可能性があるから
451 int alreadyExistTabNum = ALREADY_TWEET_TAB_NUM;
452 //指定したワードを検索してくるアクション
453 TweetGetter tweetGetter = new TweetSearchResultGetter(this.tweetManager, searchWord);
454 //検索したワードを表示するテーブルを作成,及びタブにそのテーブルを追加
455 TweetTabbedTable searchTable = new TweetTabbedTable(tweetGetter, searchWord,
456 this.tweetMainTab, numOfTab + alreadyExistTabNum,
457 this.tableElementHeight, this.tweetManager,
458 this, newTableColor, tableElementHeight);
460 this.tweetTabbedTableList.add(searchTable);
461 searchTable.updateTweetTable();
467 public void actionBasicSettingDialog() {
468 // ダイレクトメッセージ送信用ダイアログを開く
469 Point loc = getConfigurationDialog().getLocation();
470 loc.translate(20, 20);
471 ConfigurationDialog dialog = getConfigurationDialog();
472 dialog.setLocation(loc);
473 dialog.setVisible(true);
479 public void actionCopySelectedStatusToTweetBoxPane() {
481 String username = this.currentStatus.getUser().getScreenName();
483 String message = this.currentStatus.getText();
484 this.tweetBoxPane.setText("RT: @" + username + ": " + message);
492 public void actionDetailInfoButton(ActionEvent e) {
493 if (detailInfoPanel.isVisible()) {
494 detailInfoPanel.setVisible(false);
496 detailInfoPanel.setVisible(true);
501 * 書き込みメッセージボックスの表示ONOFFボタンを押した時の動作
504 public void actionShowTweetboxButton(ActionEvent e) {
505 if( this.tweetBoxScrollPane.isVisible() ) {
506 this.tweetBoxScrollPane.setVisible(false);
508 this.tweetBoxScrollPane.setVisible(true);
513 * DirectMessageテーブルの更新
515 public void actionDirectMessageTableUpdate() {
518 int remainingHits = tweetManager.getRateLimitStatus().getRemainingHits();
519 if (remainingHits <= 0) {
520 information("API制限です.リクエストの残数が0となりました.");
527 List<Status> directMessages = tweetManager.getNewDirectMessages();
528 // まだ見ていないdirectMessage数を追加
529 uncheckedDirectMessageCount += directMessages.size();
530 // まだ見ていないmentionの数をタブに表示
531 if (uncheckedDirectMessageCount > 0) {
532 tweetMainTab.setTitleAt(2, TAB_DIRECT_MESSAGE_STRING + "("
533 + uncheckedDirectMessageCount + ")");
535 for (Status t : directMessages) {
536 directMessageTableModel.insertTweet(t);
537 directMessageTable.setRowHeight(0, tableElementHeight);
540 directMessageTableModel.removeOldTweet(TABLE_ELEMENT_MAX_SIZE);
542 directMessageTableModel.refreshTime();
543 } catch (TwitterException e1) {
544 e1.printStackTrace();
545 } catch (Exception e) {
555 public void actionExitButton(ActionEvent e) {
562 public void actionMentionTableUpdate() {
565 int remainingHits = tweetManager.getRateLimitStatus().getRemainingHits();
566 if (remainingHits <= 0) {
567 information("API制限です.リクエストの残数が0となりました.");
574 List<Status> mention = tweetManager.getNewMentionData();
575 // まだ見ていないmention数を追加
576 uncheckedMentionTweetCount += mention.size();
577 // まだ見ていないmentionの数をタブに表示
578 if (uncheckedMentionTweetCount > 0) {
579 tweetMainTab.setTitleAt(1, TAB_MENTION_STRING + "("
580 + uncheckedMentionTweetCount + ")");
582 for (Status t : mention) {
583 mentionTableModel.insertTweet(t);
584 mentionTable.setRowHeight(0, tableElementHeight);
587 TableCellRenderer renderer2 = mentionTable.getCellRenderer(0, 2);
588 if (renderer2 instanceof TweetCommentRenderer) {
589 if (this.uncheckedMentionTweetCount - 1 >= 0) {
590 ((TweetCommentRenderer) renderer2).updateNewCellRow(
591 this.uncheckedMentionTweetCount, newTableColor);
593 ((TweetCommentRenderer) renderer2).updateNewCellRow(-1,
598 mentionTableModel.removeOldTweet(TABLE_ELEMENT_MAX_SIZE);
600 mentionTableModel.refreshTime();
601 } catch (TwitterException e1) {
602 e1.printStackTrace();
609 public void actionOpenStatusURL() {
612 String userName = this.currentStatus.getUser().getScreenName();
614 long statusID = this.currentStatus.getId();
615 Desktop.getDesktop().browse(
616 new URI(TWITTER_URL + userName + "/statuses/" + statusID));
617 } catch (Exception ex) {
618 ex.printStackTrace();
619 JOptionPane.showMessageDialog(null, "エラーによりブラウザを起動できませんでした.",
620 "Error", JOptionPane.ERROR_MESSAGE);
627 public void actionOpenUserURL() {
629 String userName = this.currentStatus.getUser().getScreenName();
630 Desktop.getDesktop().browse(new URI(TWITTER_URL + userName));
631 } catch (Exception ex) {
632 ex.printStackTrace();
633 JOptionPane.showMessageDialog(null, "エラーによりブラウザを起動できませんでした.",
634 "Error", JOptionPane.ERROR_MESSAGE);
641 public void actionRefreshTime() {
642 tweetTableModel.refreshTime();
643 mentionTableModel.refreshTime();
644 directMessageTableModel.refreshTime();
645 sendDirectMessageTableModel.refreshTime();
648 for(TweetTabbedTable t : this.tweetTabbedTableList ) {
649 TweetTableModel model = t.getModel();
650 if( model != null ) {
657 * TweetMessageBox内にある#ハッシュタグ の部分をa hrefリンクに変換
661 public String actionReplaceTweetMessageBoxHashTab(String message) {
663 Pattern userPtn = Pattern.compile("#[0-9A-Z_]+",
664 Pattern.CASE_INSENSITIVE);
665 Matcher matcher = userPtn.matcher(message);
667 * if( matcher.matches() ) { matcher. }
670 Set<String> findList = new TreeSet<String>();
671 while (matcher.find()) {
672 findList.add(matcher.group(0));
675 for (String f : findList) {
677 message = message.replaceAll(f, "<a href=\""
678 + SEARCH_TWITTER_URL + SEARCH_QUERY
679 + URLEncoder.encode(f, DEFAULT_CHARACTER_ENCODING)
680 + "\">" + f + "</a>");
681 } catch (UnsupportedEncodingException e) {
689 * TweetMessageBox内にあるリンクをa hrefリンクに変換
693 public String actionReplaceTweetMessageBoxURLLink(String message) {
694 Matcher matcher = convURLLinkPtn.matcher(message);
695 return matcher.replaceAll("<a href=\"$0\">$0</a>");
699 * @ユーザ名の部分をa hrefリンクに変換
702 public String actionReplaceTweetMessageBoxUserInfo(String message) {
704 Pattern userPtn = Pattern.compile("@[0-9A-Z_]+",
705 Pattern.CASE_INSENSITIVE);
706 Matcher matcher = userPtn.matcher(message);
708 Set<String> findList = new TreeSet<String>();
709 while (matcher.find()) {
710 findList.add(matcher.group(0));
712 // 指定したユーザ名をすべてリンクへ変更
713 for (String f : findList) {
714 message = message.replaceAll(f, "<a href=\"" + TWITTER_URL
715 + f.substring(1) + "\">" + f + "</a>");
721 * まだ見ていないdirectMessage数を0にする
723 public void actionResetUncheckedDirectMessageCount() {
724 uncheckedDirectMessageCount = 0;
725 tweetMainTab.setTitleAt(2, TAB_DIRECT_MESSAGE_STRING);
729 * まだ見ていないmention数を0にする
731 public void actionResetUncheckedMentionTweetCount() {
732 uncheckedMentionTweetCount = 0;
733 tweetMainTab.setTitleAt(1, TAB_MENTION_STRING);
739 public void actionResetUncheckedTimelineTweetCount() {
740 uncheckedTimelineTweetCount = 0;
741 tweetMainTab.setTitleAt(0, TAB_TIMELINE_STRING);
745 * 現在選択しているステータスを公式Retweet
747 public void actionRetweet() {
748 // 選択しているtweetのstatus id
749 long statusID = this.currentStatus.getId();
751 String username = this.currentStatus.getUser().getScreenName();
753 String message = this.currentStatus.getText();
755 if (message.length() > 30) {
756 message = message.substring(0, 30) + " ...(以下略)";
758 // Retweetしていいかどうかの確認
759 int ret = JOptionPane.showConfirmDialog(mainFrame, username + " さんの発言:"
760 + message + "\nをRetweetしますか?", "Retweetの確認",
761 JOptionPane.YES_NO_OPTION);
762 if (ret == JOptionPane.YES_OPTION) {
765 this.tweetManager.retweet(statusID);
766 } catch (TwitterException e) {
767 JOptionPane.showMessageDialog(null, "エラーによりRetweetできませんでした.",
768 "Retweet Error", JOptionPane.ERROR_MESSAGE);
778 public void updateTableHeight(int height) {
779 this.tableElementHeight = height;
780 mainTweetTable.setRowHeight(tableElementHeight);
781 mentionTable.setRowHeight(tableElementHeight);
782 directMessageTable.setRowHeight(tableElementHeight);
783 sendDirectMessageTable.setRowHeight(tableElementHeight);
787 * SendDirectMessageテーブルを更新
789 public void actionSendDirectMessageTableUpdate() {
792 int remainingHits = tweetManager.getRateLimitStatus().getRemainingHits();
793 if (remainingHits <= 0) {
794 information("API制限です.リクエストの残数が0となりました.");
799 List<Status> sendDirectMessages = tweetManager.getNewSendDirectMessages();
800 for (Status t : sendDirectMessages) {
801 sendDirectMessageTableModel.insertTweet(t);
802 sendDirectMessageTable.setRowHeight(0, tableElementHeight);
805 sendDirectMessageTableModel.removeOldTweet(TABLE_ELEMENT_MAX_SIZE);
807 sendDirectMessageTableModel.refreshTime();
808 } catch (TwitterException e1) {
809 e1.printStackTrace();
816 public void actionShowDirectMessageDialog() {
817 // ダイレクトメッセージ送信用ダイアログを開く
818 Point loc = getDirectMessageDialog().getLocation();
819 //loc.translate(20, 20);
820 DirectMessageDialog dialog = getDirectMessageDialog();
821 //dialog.setLocation(loc);
822 dialog.setLocationRelativeTo(null);
823 dialog.setVisible(true);
824 dialog.setUserInformation(this.selectedUsername,
825 this.selectedUserImageURL, this.tweetManager);
831 public void actionShowAboutDialog() {
832 Point loc = getDirectMessageDialog().getLocation();
833 //loc.translate(20, 20);
834 AboutDialog dialog = getAboutDialog();
835 dialog.setLocationRelativeTo(null);
836 //dialog.setLocation(loc);
837 dialog.setVisible(true);
843 public void actionShowAccountDialog() {
844 Point loc = getDirectMessageDialog().getLocation();
845 //loc.translate(20, 20);
846 AccountDialog dialog = getAccountDialog();
847 dialog.setLocationRelativeTo(null);
848 // dialog.setLocation(loc);
849 dialog.setVisible(true);
853 * tweetBoxPaneに書かれた文字をつぶやく
855 public void actionTweet() {
856 tweetManager.tweet(tweetBoxPane.getText());
857 tweetBoxPane.setText(""); // テキストをクリア
863 public void actionTweetTableUpdate() {
866 int remainingHits = tweetManager.getRateLimitStatus().getRemainingHits();
867 if (remainingHits <= 0) {
868 information("API制限です.リクエストの残数が0となりました.");
873 List<Status> tweet = tweetManager.getNewTimelineData();
875 uncheckedTimelineTweetCount += tweet.size();
876 // まだチェックしていないtweetの数をタブにも表示
877 if (uncheckedTimelineTweetCount > 0) {
878 tweetMainTab.setTitleAt(0, TAB_TIMELINE_STRING + "("
879 + uncheckedTimelineTweetCount + ")");
882 for (Status t : tweet) {
883 tweetTableModel.insertTweet(t);
884 mainTweetTable.setRowHeight(0, tableElementHeight);
887 TableCellRenderer renderer = mainTweetTable.getCellRenderer(0, 2);
888 if (renderer instanceof TweetCommentRenderer) {
889 if (this.uncheckedTimelineTweetCount - 1 >= 0) {
890 ((TweetCommentRenderer) renderer).updateNewCellRow(
891 this.uncheckedTimelineTweetCount, newTableColor);
893 ((TweetCommentRenderer) renderer).updateNewCellRow(-1,
898 tweetTableModel.removeOldTweet(TABLE_ELEMENT_MAX_SIZE);
900 // 取得したコメント数をステータスバーに表示
901 information(uncheckedTimelineTweetCount
902 + " 件の新しいツイートを取得しました. (APIリクエスト残数は" + remainingHits
905 tweetTableModel.refreshTime();
906 } catch (TwitterException e1) {
907 e1.printStackTrace();
916 public void actionUpdateButton(java.awt.event.ActionEvent e) {
919 actionTweetTableUpdate();
921 actionMentionTableUpdate();
922 // DirectMessageテーブルの情報を更新
923 actionDirectMessageTableUpdate();
924 // SendDirectMessageテーブルの情報を更新
925 actionSendDirectMessageTableUpdate();
927 //新しく追加したタブ上に存在するテーブルの情報を更新
928 for(TweetTabbedTable t : this.tweetTabbedTableList ) {
929 t.updateTweetTable();
931 } catch (Exception e1) {
932 e1.printStackTrace();
941 public void actionUpdateTweetMessageCount() {
942 int len = 140 - (tweetBoxPane.getText().length());
946 tweetMessageCountLabel.setText(len + "");
954 public ConfigurationDialog getConfigurationDialog() {
955 if (configurationDialog == null) {
956 configurationDialog = new ConfigurationDialog(mainFrame, this);
958 return configurationDialog;
965 public AccountDialog getAccountDialog() {
966 if( accountDialog == null ) {
967 accountDialog = new AccountDialog(mainFrame, true, tweetManager, this);
969 return accountDialog;
973 * ダイレクトメッセージ送信用ダイアログを取得
977 public DirectMessageDialog getDirectMessageDialog() {
978 if (directMessageDialog == null) {
979 directMessageDialog = new DirectMessageDialog(mainFrame);
980 directMessageDialog.setTitle("ダイレクトメッセージを送信");
982 return directMessageDialog;
986 * テーブルで選択したツイートを詳細情報としてセット
989 public void setDetailInformationFromTable(JTable table) {
990 int sc = table.getSelectedRowCount();
991 String infoMessage = "";
994 Status st = getTweetTableInformation(table, table.getModel());
995 infoMessage = st.getText();
996 // tweetMessageBox内のURLをhtmlリンクへ変換
997 infoMessage = actionReplaceTweetMessageBoxURLLink(infoMessage);
999 infoMessage = actionReplaceTweetMessageBoxUserInfo(infoMessage);
1000 // #ハッシュタグ情報をhtmlリンクへ変換
1001 infoMessage = actionReplaceTweetMessageBoxHashTab(infoMessage);
1002 // 詳細情報にテーブルで選択した人のツイート情報を表示
1003 tweetMessageBox.setText(infoMessage);
1005 userImageLabel.setIcon(new ImageIcon(st.getUser().getProfileImageURL()));
1007 userNameLabel.setText(st.getUser().getName()
1008 + " / " + st.getUser().getScreenName());
1010 updateTimeLabel.setText(DateFormat.getInstance().format( st.getCreatedAt() ));
1012 userIntroBox.setText(st.getUser().getDescription());
1014 followerLabel.setText(st.getUser().getFollowersCount()
1017 followingLabel.setText(st.getUser().getFriendsCount()
1020 locationLabel.setText(st.getUser().getLocation());
1022 if (st.getUser().getURL() != null) {
1023 userWebBox.setText("<a href=\""
1024 + st.getUser().getURL() + "\">"
1025 + st.getUser().getScreenName()
1026 + "のWebを開く" + "</a>");
1028 userWebBox.setText("");
1031 clientNameLabel.setText(" via " + st.getSource());
1033 updateLabel.setText(st.getUser().getStatusesCount()
1042 public AboutDialog getAboutDialog() {
1043 if (aboutDialog == null) {
1044 aboutDialog = new AboutDialog(mainFrame, true);
1050 * updatePeriodを取得します。
1052 * @return updatePeriod
1054 public int getUpdatePeriod() {
1055 return updatePeriod;
1059 * updatePeriodを設定します。
1061 * @param updatePeriod
1064 public void setUpdatePeriod(int updatePeriod) {
1065 this.updatePeriod = updatePeriod;
1069 * getDirectMessagePeriodNumを取得します。
1071 * @return getDirectMessagePeriodNum
1073 public int getGetDirectMessagePeriodNum() {
1074 return getDirectMessagePeriodNum;
1078 * getMentionPeriodNumを取得します。
1080 * @return getMentionPeriodNum
1082 public int getGetMentionPeriodNum() {
1083 return getMentionPeriodNum;
1087 * getSendDirectMessagePeriodNumを取得します。
1089 * @return getSendDirectMessagePeriodNum
1091 public int getGetSendDirectMessagePeriodNum() {
1092 return getSendDirectMessagePeriodNum;
1096 * getTimelinePeriodNumを取得します。
1098 * @return getTimelinePeriodNum
1100 public int getGetTimelinePeriodNum() {
1101 return getTimelinePeriodNum;
1105 * テーブルで選択した場所のTweet情報を取得
1109 public Status getTweetTableInformation(JTable table, TableModel model) {
1110 int index = table.convertRowIndexToModel(table.getSelectedRow());
1111 Status status = null;
1112 if (model instanceof TweetTableModel) {
1113 status = ((TweetTableModel) model).getTweetStatus(index);
1114 // 現在選択したセルのユーザ名を保存しておく
1115 this.selectedUsername = status.getUser().getScreenName();
1116 // 現在選択したセルのユーザURLを保存しておく
1117 this.selectedUserImageURL = status.getUser().getProfileImageURL();
1118 // 選択したStatusを保存しておく
1119 this.currentStatus = status;
1129 private void information(String message) {
1130 statusBarLabel.setText(message);
1136 * @throws IOException
1137 * @throws FileNotFoundException
1139 public void loadProperties() throws FileNotFoundException, IOException {
1140 if (property == null) {
1141 this.property = new Properties();
1143 property.load(new FileInputStream("./" + PROPERTIES_DIRECTORY + "/"
1144 + BASIC_SETTING_FILENAME));
1146 String gtpn = this.property.getProperty("getTimelinePeriodNum");
1147 String gmpn = this.property.getProperty("getMentionPeriodNum");
1148 String gdmpn = this.property.getProperty("getDirectMessagePeriodNum");
1149 String gsdmpn = this.property.getProperty("getSendDirectMessagePeriodNum");
1150 String up = this.property.getProperty("updatePeriod");
1151 String ntrgb = this.property.getProperty("newTableColorRGB");
1153 this.tlFontName = this.property.getProperty("tlFontName");
1154 this.detailFontName = this.property.getProperty("detailFontName");
1156 String tfs = this.property.getProperty("tlFontSize");
1157 String dfs = this.property.getProperty("detailFontSize");
1158 String teh = this.property.getProperty("tableElementHeight");
1161 String mfw = this.property.getProperty("mainFrameWidth");
1162 String mfh = this.property.getProperty("mainFrameHeight");
1165 this.getTimelinePeriodNum = Integer.parseInt(gtpn);
1166 this.getMentionPeriodNum = Integer.parseInt(gmpn);
1167 this.getDirectMessagePeriodNum = Integer.parseInt(gdmpn);
1168 this.getSendDirectMessagePeriodNum = Integer.parseInt(gsdmpn);
1169 this.updatePeriod = Integer.parseInt(up);
1170 this.newTableColor = new Color(Integer.parseInt(ntrgb));
1171 this.tlFontSize = Integer.parseInt(tfs);
1172 this.detailFontSize = Integer.parseInt(dfs);
1173 this.tableElementHeight = Integer.parseInt(teh);
1174 this.mainFrameWidth = Integer.parseInt(mfw);
1175 this.mainFrameHeight = Integer.parseInt(mfh);
1176 } catch (NumberFormatException e) {
1177 e.printStackTrace();
1182 * Tweet情報の自動更新のタイムをリセット
1184 public void resetTweetAutoUpdate() {
1185 if (this.autoUpdateTimer != null) {
1186 this.autoUpdateTimer.reset();
1193 * @throws IOException
1195 public void saveProperties() throws IOException {
1197 File logDir = new File("./" + PROPERTIES_DIRECTORY);
1198 if (!logDir.exists()) {
1199 // ディレクトリが存在しないので作成する
1200 if (logDir.mkdir() == false) {
1201 throw new IOException(PROPERTIES_DIRECTORY
1202 + "ディレクトリを作成できませんでした.");
1205 if (property == null) {
1206 this.property = new Properties();
1209 this.property.setProperty("getTimelinePeriodNum",
1210 this.getTimelinePeriodNum + "");
1211 this.property.setProperty("getMentionPeriodNum",
1212 this.getMentionPeriodNum + "");
1213 this.property.setProperty("getDirectMessagePeriodNum",
1214 this.getDirectMessagePeriodNum + "");
1215 this.property.setProperty("getSendDirectMessagePeriodNum",
1216 this.getSendDirectMessagePeriodNum + "");
1217 this.property.setProperty("updatePeriod", this.updatePeriod + "");
1218 this.property.setProperty("newTableColorRGB", newTableColor.getRGB()
1220 this.property.setProperty("tlFontName", this.tlFontName);
1221 this.property.setProperty("tlFontSize", this.tlFontSize + "");
1222 this.property.setProperty("detailFontName", this.detailFontName);
1223 this.property.setProperty("detailFontSize", this.detailFontSize + "");
1224 this.property.setProperty("tableElementHeight", this.tableElementHeight
1228 if( this.mainFrame.getExtendedState() == JFrame.NORMAL ) {
1229 this.mainFrameWidth = this.mainFrame.getWidth();
1230 this.mainFrameHeight = this.mainFrame.getHeight();
1232 this.property.setProperty("mainFrameWidth", this.mainFrameWidth + "");
1233 this.property.setProperty("mainFrameHeight", this.mainFrameHeight + "");
1235 property.store(new FileOutputStream("./" + PROPERTIES_DIRECTORY + "/"
1236 + BASIC_SETTING_FILENAME), null);
1240 * getDirectMessagePeriodNumを設定します。
1242 * @param getDirectMessagePeriodNum
1243 * getDirectMessagePeriodNum
1245 public void setGetDirectMessagePeriodNum(int getDirectMessagePeriodNum) {
1246 this.getDirectMessagePeriodNum = getDirectMessagePeriodNum;
1250 * getMentionPeriodNumを設定します。
1252 * @param getMentionPeriodNum
1253 * getMentionPeriodNum
1255 public void setGetMentionPeriodNum(int getMentionPeriodNum) {
1256 this.getMentionPeriodNum = getMentionPeriodNum;
1260 * getSendDirectMessagePeriodNumを設定します。
1262 * @param getSendDirectMessagePeriodNum
1263 * getSendDirectMessagePeriodNum
1265 public void setGetSendDirectMessagePeriodNum(
1266 int getSendDirectMessagePeriodNum) {
1267 this.getSendDirectMessagePeriodNum = getSendDirectMessagePeriodNum;
1271 * getTimelinePeriodNumを設定します。
1273 * @param getTimelinePeriodNum
1274 * getTimelinePeriodNum
1276 public void setGetTimelinePeriodNum(int getTimelinePeriodNum) {
1277 this.getTimelinePeriodNum = getTimelinePeriodNum;
1285 public void startTweetAutoUpdate() {
1286 if (this.autoUpdateTimer == null) {
1287 this.autoUpdateTimer = new TweetAutoUpdateTimer();
1290 this.autoUpdateTimer.stop();
1292 this.autoUpdateTimer.start(updatePeriod * 60);
1296 * newTableColorを取得します。
1298 * @return newTableColor
1300 public Color getNewTableColor() {
1301 return newTableColor;
1305 * newTableColorを設定します。
1307 * @param newTableColor
1310 public void setNewTableColor(Color newTableColor) {
1311 this.newTableColor = newTableColor;
1317 * @return tlFontName
1319 public String getTlFontName() {
1329 public void setTlFontName(String tlFontName) {
1330 this.tlFontName = tlFontName;
1336 * @return tlFontSize
1338 public int getTlFontSize() {
1348 public void setTlFontSize(int tlFontSize) {
1349 this.tlFontSize = tlFontSize;
1353 * detailFontNameを取得します。
1355 * @return detailFontName
1357 public String getDetailFontName() {
1358 return detailFontName;
1362 * detailFontNameを設定します。
1364 * @param detailFontName
1367 public void setDetailFontName(String detailFontName) {
1368 this.detailFontName = detailFontName;
1372 * detailFontSizeを取得します。
1374 * @return detailFontSize
1376 public int getDetailFontSize() {
1377 return detailFontSize;
1381 * detailFontSizeを設定します。
1383 * @param detailFontSize
1386 public void setDetailFontSize(int detailFontSize) {
1387 this.detailFontSize = detailFontSize;
1391 * tableElementHeightを取得します。
1393 * @return tableElementHeight
1395 public int getTableElementHeight() {
1396 return tableElementHeight;
1400 * tableElementHeightを設定します。
1402 * @param tableElementHeight
1403 * tableElementHeight
1405 public void setTableElementHeight(int tableElementHeight) {
1406 this.tableElementHeight = tableElementHeight;