OSDN Git Service

a74c0b13ae8581385ae2813a377f4bae047a78e3
[nt-manager/nt-manager.git] / src / twitter / gui / component / TweetTabbedTable.java
1 /*
2  * To change this template, choose Tools | Templates
3  * and open the template in the editor.
4  */
5
6 package twitter.gui.component;
7
8 import java.awt.Color;
9 import java.awt.Component;
10 import java.awt.Point;
11 import java.awt.event.KeyAdapter;
12 import java.awt.event.KeyEvent;
13 import java.awt.event.MouseAdapter;
14 import java.awt.event.MouseEvent;
15 import java.util.List;
16 import javax.swing.JMenuItem;
17 import javax.swing.JPopupMenu;
18 import javax.swing.JScrollPane;
19 import javax.swing.JTabbedPane;
20 import javax.swing.JTable;
21 import javax.swing.event.ListSelectionEvent;
22 import javax.swing.event.ListSelectionListener;
23 import javax.swing.table.TableCellRenderer;
24 import javax.swing.table.TableColumn;
25 import javax.swing.table.TableColumnModel;
26 import twitter.action.TweetGetter;
27 import twitter.action.list.ListGetterSelection;
28 import twitter.gui.action.TweetMainAction;
29 import twitter.manage.TweetManager;
30 import twitter4j.Status;
31 import twitter4j.TwitterException;
32
33 /**
34  * ツイートを表示するテーブルを扱うクラス
35  * 
36  * @author nishio
37  */
38 public class TweetTabbedTable {
39         // ツイートを表示するテーブル
40         private JTable table;
41         // ツイートを表示するテーブルのモデル
42         private TweetTableModel model;
43         // 未読のツイート数
44         private int uncheckedTweet;
45         // ツイートを取得する時に行うアクション
46         private TweetGetter tweetGetter;
47         // タブに表示される名前
48         private String title;
49         // タブ
50         private JTabbedPane tabbedPane;
51         // スクロールペーン
52         private JScrollPane scrollPane;
53         // ツイートを管理するクラス
54         private TweetManager tweetManager;
55         // メインアクション
56         private TweetMainAction mainAction;
57         // テーブルの高さ
58         private int tableElementHeight;
59         // 新しく取得した部分のテーブルの色
60         private Color newTableColor = null;
61         // テーブルに追加できる要素の最大数
62         private int tableElementMaxSize = 200;
63         // 自動更新に使うタイマーのID
64         private String timerID;
65
66         /**
67          * 
68          * @param tweetGetter
69          *            tweet取得時に行うアクション
70          * @param title
71          *             タブに表示するタイトル
72          * @param tabbedPane
73          *             テーブルを追加するタブ
74          * @param tableElementHeight
75          *            テーブルの高さ
76          * @param tweetManager
77          *             ツイート管理クラス
78          * @param mainAction
79          *            メインアクション
80          * @param newTableColor
81          *            新しく取得した部分の色
82          * @param tableElementMaxSize
83          *            テーブルに格納できる要素の最大数
84          * @param timerID
85          *            自動更新につかうタイマーのID
86          */
87         public TweetTabbedTable(TweetGetter tweetGetter, String title,
88                         JTabbedPane tabbedPane, int tableElementHeight,
89                         TweetManager tweetManager, TweetMainAction mainAction,
90                         Color newTableColor, int tableElementMaxSize, String timerID) {
91                 this.tweetGetter = tweetGetter;
92                 this.title = title;
93                 this.tabbedPane = tabbedPane;
94                 this.tweetManager = tweetManager;
95                 this.mainAction = mainAction;
96                 this.tableElementHeight = tableElementHeight;
97                 this.newTableColor = newTableColor;
98                 this.tableElementMaxSize = tableElementMaxSize;
99                 this.timerID = timerID;
100
101                 table = new JTable();
102                 model = new TweetTableModel();
103                 uncheckedTweet = 0;
104                 scrollPane = new JScrollPane();
105         }
106
107         /**
108          * Tweet情報を表示するテーブルをタブに追加
109          */
110         public void addTableToTab() {
111                 // テーブルをタブに追加
112                 getTable().setModel(model);
113                 getTable().getTableHeader().setReorderingAllowed(false);
114                 getTable().addMouseListener(new java.awt.event.MouseAdapter() {
115                         @Override
116                         public void mousePressed(java.awt.event.MouseEvent evt) {
117                                 jTableMousePressed(evt);
118                         }
119
120                         @Override
121                         public void mouseReleased(java.awt.event.MouseEvent evt) {
122                                 jTableMouseReleased(evt);
123                         }
124                 });
125
126                 // tweetを表示するテーブルを作成
127                 createTweetTable(getTable());
128
129                 // スクロールペーン追加
130                 scrollPane.setViewportView(getTable());
131                 // タブにテーブル追加
132                 tabbedPane.addTab(this.title, scrollPane);
133         }
134
135         /**
136          * Tweetを表示するテーブルを作成
137          * 
138          * @param model
139          * @return
140          */
141         private void createTweetTable(final JTable table) {
142
143                 table.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
144                 table.setShowVerticalLines(false);
145                 table.setShowHorizontalLines(true);
146
147                 // Comment部分のColumnを複数行コメントが表示できるようにする
148                 TableColumnModel mdl = table.getColumnModel();
149                 TableColumn col = mdl.getColumn(1);
150                 TweetCommentRenderer commentRenderer = new TweetCommentRenderer();
151                 col.setCellRenderer(commentRenderer);
152                 // INfo部分のColumnを複数行表示できるように
153                 TweetCommentRenderer infoRenderer = new TweetCommentRenderer();
154                 col = mdl.getColumn(2);
155                 col.setCellRenderer(infoRenderer);
156                 col.setMaxWidth(200);
157                 col.setMinWidth(150);
158                 // TODO:とりあえず幅指定した部分
159                 // あとでファイルに幅情報などを保存しておき,それを読み込んで設定するような仕様に変更する
160                 // ユーザImageを表示する部分
161                 col = mdl.getColumn(0);
162                 col.setCellRenderer(new UserImageRenderer());
163                 col.setMinWidth(50);
164                 col.setMaxWidth(50);
165                 // 選択したセルの情報をDetailInfoへと表示
166                 // JTableを右クリックでも選択できるようにする
167                 // また,同じ行を2回クリックできるようにする
168                 table.addMouseListener(new MouseAdapter() {
169
170                         @Override
171                         public void mousePressed(MouseEvent e) {
172                                 // いったんSelectしていた情報を削除
173                                 table.clearSelection();
174                                 // if (e.getButton() == MouseEvent.BUTTON3) {
175                                 Point p = e.getPoint();
176                                 int col = table.columnAtPoint(p);
177                                 int row = table.rowAtPoint(p);
178                                 table.changeSelection(row, col, false, false);
179
180                                 // テーブルで選択した要素を詳細情報として表示
181                                 mainAction.setDetailInformationFromTable(table);
182                                 // }
183                         }
184                 });
185                 // キー受付
186                 table.addKeyListener(new KeyAdapter() {
187
188                         @Override
189                         public void keyReleased(KeyEvent ke) {
190                                 mainAction.setDetailInformationFromTable(table);
191                         }
192
193                 });
194                 // MouseEventを追加
195                 table.addMouseListener(commentRenderer);
196                 // table.addMouseMotionListener(commentRenderer);
197                 table.addMouseListener(infoRenderer);
198                 // table.addMouseMotionListener(infoRenderer);
199         }
200
201         /**
202          * テーブル情報更新
203          */
204         public void updateTweetTable() {
205                 try {
206                         // API残り回数を取得
207                         int remainingHits = tweetManager.getRateLimitStatus()
208                                         .getRemainingHits();
209                         if (remainingHits <= 0) {
210                                 return;
211                         }
212                         // ツイート情報
213                         List<Status> tweet = tweetGetter.getNewTweetData();
214                         // まだ見ていないtweet数を追加
215                         this.setUncheckedTweet(this.getUncheckedTweet() + tweet.size());
216
217                         // まだチェックしていないtweetの数をタブにも表示
218                         if (this.getUncheckedTweet() > 0) {
219                                 tabbedPane.setTitleAt(this.getTabSetNum(), this.title + "("
220                                                 + this.getUncheckedTweet() + ")");
221                         }
222                         // ツイートをテーブルに追加
223                         this.getModel().insertTweet(tweet);
224                         //テーブルの高さを整える
225                         int tableHeight = getTableElementHeight();
226                         for(int i=0; i < tweet.size(); i++) {
227                                 this.getTable().setRowHeight(i, tableHeight);
228                         }
229                         /*
230                         for (Status t : tweet) {
231                                 this.getModel().insertTweet(t);
232                                 this.getTable().setRowHeight(0, getTableElementHeight());
233                         }*/
234                         // 新規した部分の背景色を変更
235                         TableCellRenderer renderer = getTable().getCellRenderer(0, 2);
236                         if (renderer instanceof TweetCommentRenderer) {
237                                 if (this.getUncheckedTweet() - 1 >= 0) {
238                                         ((TweetCommentRenderer) renderer).updateNewCellRow(this
239                                                         .getUncheckedTweet(), newTableColor);
240                                 } else {
241                                         ((TweetCommentRenderer) renderer).updateNewCellRow(-1,
242                                                         newTableColor);
243                                 }
244                         }
245                         // 古いデータを削除
246                         getModel().removeOldTweet(getTableElementMaxSize());
247                         // 時間情報リフレッシュ
248                         getModel().refreshTime();
249                         // 新しい情報
250                         int newNum = 0;
251                         if (tweet != null) {
252                                 newNum = tweet.size();
253                         }
254                         // 情報を取得したことをステータスバーに表示
255                         mainAction.information(this.getTitle() + "タブのツイートを" + newNum
256                                         + "件取得しました. (APIリクエスト残数は" + remainingHits + "回です)");
257
258                         // 情報間隔毎に設定を保存
259                         this.mainAction.saveProperties();
260                 } catch (TwitterException e1) {
261                         e1.printStackTrace();
262                 } catch (Exception e) {
263                         e.printStackTrace();
264                 }
265         }
266
267         /**
268          * マウスクリック時の動作
269          * 
270          * @param evt
271          */
272         private void jTableMousePressed(java.awt.event.MouseEvent evt) {
273                 // 右クリックメニュー表示
274                 showPopup(evt);
275                 // 未読ツイート分を0にする
276                 this.setUncheckedTweet(0);
277                 this.setTitle(this.getTitle());
278         }
279
280         /**
281          * マウスリリース時の動作
282          * 
283          * @param evt
284          */
285         private void jTableMouseReleased(java.awt.event.MouseEvent evt) {
286                 // 右クリックメニュー表示
287                 showPopup(evt);
288         }
289
290         /**
291          * ポップアップメニューを作成
292          * 
293          * @param e
294          */
295         private void showPopup(MouseEvent e) {
296                 if (e.isPopupTrigger()) {
297                         // 右クリックのメニューを表示
298                         getRightClickPopup().show(e.getComponent(), e.getX(), e.getY());
299                 }
300         }
301
302         /**
303          * 右クリックを押した時のポップアップメニューを取得
304          * 
305          * @return
306          */
307         private JPopupMenu getRightClickPopup() {
308                 // if (rightClickPopup == null) {
309                 JPopupMenu rightClickPopup = new JPopupMenu();
310
311                 JMenuItem replyMenuItem = new JMenuItem("この発言に返信(Reply)");
312                 replyMenuItem.setMnemonic('R');
313                 replyMenuItem.addActionListener(new java.awt.event.ActionListener() {
314
315                         public void actionPerformed(java.awt.event.ActionEvent e) {
316                                 // 選択したセルのステータスにreply
317                                 mainAction.actionSetReplyStatusToTweetBoxPane();
318                         }
319                 });
320
321                 JMenuItem replyAllMenuItem = new JMenuItem("この発言に返信(Reply All)");
322                 replyAllMenuItem.setMnemonic('A');
323                 replyAllMenuItem.addActionListener(new java.awt.event.ActionListener() {
324
325                         public void actionPerformed(java.awt.event.ActionEvent e) {
326                                 // 選択したセルのステータスにreply all
327                                 mainAction.actionSetReplyAllStatusToTweetBoxPane();
328                         }
329                 });
330
331                 JMenuItem retweetMenuItem = new JMenuItem("発言を公式リツイート(RT)");
332                 retweetMenuItem.setMnemonic('R');
333                 retweetMenuItem.addActionListener(new java.awt.event.ActionListener() {
334
335                         @Override
336                         public void actionPerformed(java.awt.event.ActionEvent e) {
337                                 // 選択したセルのステータスをRetweet
338                                 mainAction.actionRetweet();
339                         }
340                 });
341
342                 JMenuItem quoteMenuItem = new JMenuItem("発言を引用ツイート(QT)");
343                 quoteMenuItem.setMnemonic('Q');
344                 quoteMenuItem.addActionListener(new java.awt.event.ActionListener() {
345
346                         @Override
347                         public void actionPerformed(java.awt.event.ActionEvent e) {
348                                 // 選択したセルのステータスをQT
349                                 mainAction.actionSetQuoteStatusToTweetBoxPane();
350                         }
351                 });
352
353                 JMenuItem unofficialRetweetMenuItem = new JMenuItem(
354                                 "発言をコメント付きリツイート(非公式RT)");
355                 unofficialRetweetMenuItem.setMnemonic('T');
356                 unofficialRetweetMenuItem
357                                 .addActionListener(new java.awt.event.ActionListener() {
358
359                                         @Override
360                                         public void actionPerformed(java.awt.event.ActionEvent e) {
361                                                 // 選択したセルのステータスをコメント付Retweet
362                                                 mainAction.actionCopySelectedStatusToTweetBoxPane();
363                                         }
364                                 });
365
366                 JMenuItem directMessageMenuItem = new JMenuItem("ダイレクトメッセージを送信(D)");
367                 directMessageMenuItem.setMnemonic('D');
368                 directMessageMenuItem
369                                 .addActionListener(new java.awt.event.ActionListener() {
370
371                                         @Override
372                                         public void actionPerformed(java.awt.event.ActionEvent e) {
373                                                 // ダイレクトメッセージ送信ダイアログを表示
374                                                 mainAction.actionShowDirectMessageDialog();
375                                         }
376                                 });
377
378                 JMenuItem statusBrowserMenuItem = new JMenuItem("この発言をブラウザで開く(O)");
379                 statusBrowserMenuItem.setMnemonic('O');
380                 statusBrowserMenuItem
381                                 .addActionListener(new java.awt.event.ActionListener() {
382
383                                         @Override
384                                         public void actionPerformed(java.awt.event.ActionEvent e) {
385                                                 // 選択したセルのステータスをブラウザで開く
386                                                 mainAction.actionOpenStatusURL();
387                                         }
388                                 });
389
390                 JMenuItem userMenuItem = new JMenuItem("この人の発言を別タブで開く(U)");
391                 userMenuItem.setMnemonic('U');
392                 userMenuItem.addActionListener(new java.awt.event.ActionListener() {
393
394                         @Override
395                         public void actionPerformed(java.awt.event.ActionEvent e) {
396                                 // 指定した人の発言を開く
397                                 mainAction.actionSelectedUserTimeline();
398                         }
399                 });
400
401                 JMenuItem createFavMenuItem = new JMenuItem("この発言をお気に入りに追加(F)");
402                 createFavMenuItem.setMnemonic('F');
403                 createFavMenuItem
404                                 .addActionListener(new java.awt.event.ActionListener() {
405
406                                         @Override
407                                         public void actionPerformed(java.awt.event.ActionEvent e) {
408                                                 // 選択したセルのユーザ情報をブラウザで開く
409                                                 mainAction.actionCreateFavorite();
410                                         }
411                                 });
412
413                 JMenuItem destroyFavMenuItem = new JMenuItem("この発言をお気に入りから削除");
414                 destroyFavMenuItem
415                                 .addActionListener(new java.awt.event.ActionListener() {
416
417                                         @Override
418                                         public void actionPerformed(java.awt.event.ActionEvent e) {
419                                                 // 選択したセルのユーザ情報をブラウザで開く
420                                                 mainAction.actionDestroyFavorite();
421                                         }
422                                 });
423
424                 JMenuItem createdListMenuItem = new JMenuItem("このユーザが作成したリスト一覧");
425                 createdListMenuItem
426                                 .addActionListener(new java.awt.event.ActionListener() {
427
428                                         @Override
429                                         public void actionPerformed(java.awt.event.ActionEvent e) {
430                                                 // 選択したセルのユーザ情報をブラウザで開く
431                                                 mainAction
432                                                                 .actionShowSelectedUserList(ListGetterSelection.CREATED);
433                                         }
434                                 });
435
436                 JMenuItem subscriptionListMenuItem = new JMenuItem("このユーザが購読しているリスト一覧");
437                 subscriptionListMenuItem
438                                 .addActionListener(new java.awt.event.ActionListener() {
439
440                                         @Override
441                                         public void actionPerformed(java.awt.event.ActionEvent e) {
442                                                 // 選択したセルのユーザ情報をブラウザで開く
443                                                 mainAction
444                                                                 .actionShowSelectedUserList(ListGetterSelection.SUBSCRIPTION);
445                                         }
446                                 });
447
448                 JMenuItem membershipsListMenuItem = new JMenuItem(
449                                 "このユーザがフォローされているリスト一覧");
450                 membershipsListMenuItem
451                                 .addActionListener(new java.awt.event.ActionListener() {
452
453                                         @Override
454                                         public void actionPerformed(java.awt.event.ActionEvent e) {
455                                                 // 選択したセルのユーザ情報をブラウザで開く
456                                                 mainAction
457                                                                 .actionShowSelectedUserList(ListGetterSelection.MEMBERSHIPS);
458                                         }
459                                 });
460
461                 // 指定した発言がRTかどうか判定
462                 int sc = table.getSelectedRowCount();
463                 if (sc == 1 && table != null) {
464                         Status st = mainAction.getTweetTableInformation(table, table
465                                         .getModel());
466
467                         JMenuItem openBrowserUserInformationMenuItem = new JMenuItem(
468                                         "この人の発言をブラウザで開く(B)");
469                         openBrowserUserInformationMenuItem.setMnemonic('B');
470                         openBrowserUserInformationMenuItem
471                                         .addActionListener(new java.awt.event.ActionListener() {
472
473                                                 @Override
474                                                 public void actionPerformed(java.awt.event.ActionEvent e) {
475                                                         // 選択したセルのユーザ情報をブラウザで開く
476                                                         mainAction.actionOpenUserURL();
477                                                 }
478                                         });
479
480                         JMenuItem openFavMenuItem = new JMenuItem("この人のお気に入りを開く");
481                         openFavMenuItem
482                                         .addActionListener(new java.awt.event.ActionListener() {
483
484                                                 @Override
485                                                 public void actionPerformed(java.awt.event.ActionEvent e) {
486                                                         // 選択したセルのユーザ情報をブラウザで開く
487                                                         mainAction.actionOpenUserFav();
488                                                 }
489                                         });
490
491                         // メニューアイテムを追加
492                         // 返信
493                         rightClickPopup.add(replyMenuItem);
494                         // 返信all
495                         rightClickPopup.add(replyAllMenuItem);
496                         // 公式RT
497                         rightClickPopup.add(retweetMenuItem);
498                         // 非公式RT
499                         rightClickPopup.add(unofficialRetweetMenuItem);
500                         // QT
501                         rightClickPopup.add(quoteMenuItem);
502                         // ダイレクトメッセージ
503                         rightClickPopup.add(directMessageMenuItem);
504                         // 発言をブラウザで開く
505                         rightClickPopup.add(statusBrowserMenuItem);
506                         // この人の発言を別タブで開く
507                         rightClickPopup.add(userMenuItem);
508                         // この人のtimelineを開く
509                         rightClickPopup.add(openBrowserUserInformationMenuItem);
510                         // この人のfavを開く
511                         rightClickPopup.add(openFavMenuItem);
512                         // この人が作成したリスト
513                         rightClickPopup.add(createdListMenuItem);
514                         // この人が購読しているリスト
515                         rightClickPopup.add(subscriptionListMenuItem);
516                         // この人がフォローされているリスト一覧
517                         rightClickPopup.add(membershipsListMenuItem);
518
519                         try {
520                                 if (st.isRetweet()) {
521                                         // Retweetのときのみ表示するメニュー
522                                 }
523                                 if (st.isFavorited()) {
524                                         // お気に入りに追加されている時のみ表示するメニュー
525                                         // お気に入り追加
526                                         rightClickPopup.add(destroyFavMenuItem);
527                                 } else {
528                                         rightClickPopup.add(createFavMenuItem);
529                                 }
530                         } catch (Exception e) {
531                                 // TODO:ここの無視部分をなんとかする
532                                 // DMのときはisFavoritedができない
533                         }
534                 }
535                 // }
536                 return rightClickPopup;
537         }
538
539         /**
540          * @return the title
541          */
542         public String getTitle() {
543                 return title;
544         }
545
546         /**
547          * @param title
548          *            the title to set
549          */
550         public void setTitle(String title) {
551                 this.title = title;
552                 this.tabbedPane.setTitleAt(this.getTabSetNum(), title);
553         }
554
555         /**
556          * 自分自信がタブのどの場所に位置しているのかを取得
557          * 
558          * @return
559          */
560         public int getTabSetNum() {
561                 int tabCount = this.tabbedPane.getTabCount();
562                 for (int i = 0; i < tabCount; i++) {
563                         Component c = this.tabbedPane.getComponentAt(i);
564                         if (c instanceof JScrollPane) {
565                                 if (c == this.scrollPane) {
566                                         return i;
567                                 }
568                         }
569                 }
570                 return 0;
571         }
572
573         /**
574          * @return the tableElementHeight
575          */
576         public int getTableElementHeight() {
577                 return tableElementHeight;
578         }
579
580         /**
581          * @param tableElementHeight
582          *            the tableElementHeight to set
583          */
584         public void setTableElementHeight(int tableElementHeight) {
585                 this.tableElementHeight = tableElementHeight;
586         }
587
588         /**
589          * @return the tableElementMaxSize
590          */
591         public int getTableElementMaxSize() {
592                 return tableElementMaxSize;
593         }
594
595         /**
596          * @param tableElementMaxSize
597          *            the tableElementMaxSize to set
598          */
599         public void setTableElementMaxSize(int tableElementMaxSize) {
600                 this.tableElementMaxSize = tableElementMaxSize;
601         }
602
603         /**
604          * @return the model
605          */
606         public TweetTableModel getModel() {
607                 return model;
608         }
609
610         /**
611          * @param model
612          *            the model to set
613          */
614         public void setModel(TweetTableModel model) {
615                 this.model = model;
616         }
617
618         /**
619          * @return the uncheckedTweet
620          */
621         public int getUncheckedTweet() {
622                 return uncheckedTweet;
623         }
624
625         /**
626          * @param uncheckedTweet
627          *            the uncheckedTweet to set
628          */
629         public void setUncheckedTweet(int uncheckedTweet) {
630                 this.uncheckedTweet = uncheckedTweet;
631         }
632
633         /**
634          * @return the timerID
635          */
636         public String getTimerID() {
637                 return timerID;
638         }
639
640         /**
641          * @return the table
642          */
643         public JTable getTable() {
644                 return table;
645         }
646
647 }