Twitterのグラフィカル・クライアントの作成

このチュートリアルでは、NetBeans IDEを使用して、Twitterの友達のタイムラインのメッセージを表示し、Twitterのステータスを確認、更新できるRESTベースの簡易なグラフィカル・クライアントを作成します。このアプリケーションでは、SwingとNetBeans IDEでのTwitterのSaaS操作のサポートを使用します。

Twitterメッセージが表示された実行中のクライアント

Twitterのアカウントがない場合は、twitter.comに移動してアカウントを作成してから、このチュートリアルの手順に従ってください。

このアプリケーションの完全なサンプルをダウンロードできます。サンプルをダウンロードするには、ここをクリックしてください。

目次

このページの内容は、NetBeans IDE 6.9から7.1に適用されます

このチュートリアルを完了するには、次のソフトウェアとリソースが必要です。

ソフトウェアまたはリソース 必須バージョン
NetBeans IDE Java EEダウンロード・バンドル
Java Development Kit (JDK) バージョン6またはバージョン7
Twitterアカウントのユーザー名とパスワード

JFrameのデザイン

このステップでは、Twitterの友達のタイムライン、ユーザー・アイコン、およびステータスを確認および更新する場所を表示するGUI要素を作成します。GUI要素はすべてJFrameにラップします。GUI要素は、この項に示すとおりに配置する必要はありません。このレイアウトは一例です。たとえば、さらに機能を追加することもできます。ただし、少なくともこのチュートリアルで説明している要素はすべて作成する必要があります。

JFrameをデザインするには:

  1. 「ファイル」>「新規プロジェクト」を選択します。新規プロジェクト・ウィザードが開きます。「Java」カテゴリ、「Javaアプリケーション」プロジェクトの順に選択します。「次」をクリックします。
  2. プロジェクトにTwitterSwingClientという名前を付けます。プロジェクトの場所を選択します。「メイン・クラスの作成」の選択を解除します。(JFrameがメイン・クラスになる。)「終了」をクリックします。
    TwitterSwingClientプロジェクトを作成するためのフィールドが表示された新規プロジェクト・ウィザード
  3. IDEによってTwitterSwingClientプロジェクトが作成され、「プロジェクト」ウィンドウに表示されます。「TwitterSwingClient」プロジェクト・ノードを右クリックし、「新規」>「JFrameフォーム」(または「新規」>「その他」>「Swing GUIフォーム」>「JFrameフォーム」)を選択します。新規JFrameフォーム・ウィザードが開きます。
  4. フォーム名をTwitterJFrameにし、twitterclientというパッケージを作成します。「終了」をクリックします。
    TwitterJFrameを作成するためのフィールドが表示された新規JFrameフォーム・ウィザード
  5. エディタのデザイン・ビューでTwitterJFrameが開きます。ここには、JFrameにドラッグ・アンド・ドロップできるすべてのSwingコンポーネントのパレットがあります。
    エディタのデザイン・ビューのTwitterJFrame
  6. パレットの「Swingコントロール」の下にある「ボタン」アイコンをクリックします。これをJFrameの右下隅にドラッグ・アンド・ドロップします。ボタンにjButton1と表示されることに注意してください。これが、このJButtonオブジェクトの名前です。
    新規に追加したjButton1が表示されたJFrame
  7. jButton1を右クリックし、コンテキスト・メニューから「テキストを編集」を選択します。表示テキストを「Update」に変更します。
  8. 「ラベル」(jLabel1)をJFrameの左下隅にドラッグ・アンド・ドロップします。表示テキストを「Icon」に変更します。このラベルにはユーザー・アイコンを表示します。
  9. 「テキスト・フィールド」(jTextField1)をラベルとボタンの間にドラッグ・アンド・ドロップします。表示テキストを「Status」に変更します。テキスト・フィールドの右の境界線をクリックし、ボタンの方向に伸ばします。ボタンからの提案距離を示す青いガイドラインが表示されます。
  10. jLabel1を右クリックし、コンテキスト・メニューから「プロパティ」を選択します。「jLabel1プロパティ」ダイアログが開きます。labelForプロパティをjTextField1に設定します。(これでアクセシビリティが向上。)
  11. 「maximumSize」、「minimumSize」および「preferredSize」の各プロパティを探します。Twitterのアイコンのサイズ(48px X 48px)にあわせてこれらの各プロパティを[48,48]に設定します。
    TwitterJFrame内のjLabel1のプロパティで、maximumSize、minimumSizeおよびpreferredSizeを48, 48に設定
  12. JFrameの上部に「スクロール・ペイン」をドラッグ・アンド・ドロップします。その境界線をドラッグして、テキスト・フィールドとボタンの上のスペースをほとんど、またはすべて占めるように拡大します。(サンプルのメニューのように、後で機能を追加する場合は余白を残しておくことも可能。)
  13. スクロール・ペイン内に「リスト」をドラッグ・アンド・ドロップします。項目リストのサンプルが表示されます。TwitterJFrameを保存します。JFrameは次のイメージのようになります。
    デザイン・ビューのTwitterJFrameに基本的なGUI要素がすべて表示された状態

これで、Swingクライアントの基本的なGUIコンポーネントが揃いました。次に、最初のTwitter SaaS (Software as a Service)操作を追加します。

ユーザー・ステータスの表示

この項では、新しいメソッドを作成し、そのメソッドにTwitterのgetUserTimeline操作を追加します。getUserTimeline操作は、ユーザー・アイコンと現在のステータスを取得します。次に、アイコンとステータスをそれぞれjLabel1とjTextFieldに表示するコードをメソッドに追加します。最後に、JFrameのコンストラクタに、メソッドを初期化する行を追加します。

ユーザー・ステータスを表示するには:

  1. TwitterJFrameのソース・ビューに切り替えます。
  2. [Alt]-[Insert]を押すか、右クリックしてコンテキスト・メニューから「コードを挿入」を選択します。挿入するコードのメニューが開きます。
    initUserInfoメソッドに挿入するコードのメニュー
  3. 「RESTクライアントを生成」をクリックします。「使用可能なRESTリソース」ダイアログが開きます。
    「使用可能なRESTリソース」ダイアログ
  4. 「IDE登録済み」ラジオ・ボタンを選択して「参照」をクリックします。「Twitter」>「Twitter OAuth」>「[statuses]」>「[user_timeline.{format}]」に移動します。「OK」をクリックします。
    「サービス」ウィンドウの「Webサービス」ツリーでTwitterのgetUserTimelineById操作を選択した状態
  5. これで、「使用可能なRESTリソース」ダイアログに、選択されたTwitter OAuth user_timelineリソース、対応するクラス名およびOAuth認証タイプが表示されるようになります。「OK」をクリックします。
    入力された「使用可能なRESTリソース」ダイアログ
  6. WADLのXMLスキーマ参照からJavaオブジェクトを生成するかどうかを質問するダイアログが開きます。「はい」をクリックします。
  7. TwitterJFrameクラスの最後に、IDEはTwitter_OAuth_user_timeline__format_JerseyClientという内部クラスを生成します。

    この内部クラスは複雑で、次のフィールド、メソッド、および内部クラスを含んでいます。

    • CONSUMER_KEY: Consumer Key文字列
    • CONSUMER_SECRET: Consumer Secret文字列
    • initOAuth(): OAuh初期化のメソッド
    • getUserTimeline(): HTTPメソッドに対応するメソッド: getUserTimeline (RESTリソースから)
    • makeOAuthRequestUnique(): 1つのセッションでの複数のAPIコールに有用
    • login: Twitterアプリケーションへのログインに使用(認証を強制)。このメソッドは、もう2つの生成されたメソッド(getOAuthAccessTokenおよびgetOAuthRequestToken)をコールします。

    「ナビゲータ」ウィンドウに表示されるクラス構造は次のとおりです。

    Twitter_OAuth_user_timeline__format_JerseyClientクラスを示す「ナビゲータ」ウィンドウ
  8. TwitterJFrameで、内部Twitter_OAuth_user_timeline__format_JerseyClientクラスのすぐ上に次のコード行を挿入します。このコードは、内部クラスのインスタンスを表すclientという変数を作成します。
    private Twitter_OAuth_user_timeline__format_JerseyClient client;
    内部クラスの直前のクライアント変数を示すコード・スニペット
  9. TwitterJFrameのmainメソッドを見つけます。このメソッドの上に、MalformedURLExceptionおよびIOExceptionをスローするinitUserInfoという新しいメソッドを作成します。
    private void initUserInfo() throws MalformedURLException, IOException {
    
    
    
    }
  10. initUserInfoのメソッド本体に次のコードを挿入します。コードのコメントは、コードの処理について説明しています。
    private void initUserInfo() throws MalformedURLException, IOException {
    
    //Create an instance of the internal service class client = new Twitter_OAuth_user_timeline__format_JerseyClient("xml");
    //Log in, get tokens, and append the tokens to the consumer and secret //keys client.login(); client.initOAuth();
    //Call getUserTimeline, get a list of statuses, pass the most recent //status as a StatusType object, and display the text of that object //in the JTextField Statuses statuses = client.getUserTimeline(Statuses.class, null, null, null, "1"); StatusType st = statuses.getStatus().get(0); jTextField1.setText(st.getText().trim());
    //Get a UserType object from the StatusType object, get the URL of that //user's icon, and display that icon in the JLabel UserType user = st.getUser(); String iconSrc = user.getProfileImageUrl(); URL iconUrl = new URL(iconSrc); ImageIcon icon = new ImageIcon(iconUrl, user.getScreenName()); jLabel1.setIcon(icon); }
  11. ([Ctrl]/[⌘]-[Shift]-[I]、またはコンテキスト・メニューから)「すべてのインポートを修正」ダイアログを開きます。ダイアログで、デフォルトのJava StatusTypeではなく、twitter.twitteroauth.twitterresponse.StatusTypeを選択します。
    initUserInfoメソッド完了後の「インポートを修正」ダイアログ
  12. TwitterJFormコンストラクタにtry/catchブロックを追加し、アプリケーション実行時にinitUserInfoをコールするようにします。try/catchブロックの追加後インポートを修正します。
    public TwitterJFrame() {
        initComponents();
    
        try {
            initUserInfo();
        } catch (IOException ex) {
            Logger.getLogger(TwitterJFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
     }

TwitterからOAuthキーを取得した後、プロジェクトを実行できます。プロジェクト・ノードを右クリックし、コンテキスト・メニューから「実行」を選択します。アプリケーションが開き、ユーザー・アイコンとステータスが表示されます。

TwitterからのOAuthキーの取得

JavaアプリケーションがTwitterデータにアクセスできるようにするには、確認文字列に加えてCUSTOMERおよびCUSTOMER_SECRETキーをTwitterから取得する必要があります。Twitterは、これらのキーを必要とするOAuth認証を使用しています。しかし、OAuthはサーバー上のWebアプリケーションによってコールされる前提で設定されています。認証キーを取得するために、「仮の」Webアプリケーションを登録します。

TwitterからOAuthキーを取得するには:

  1. ブラウザを開きます。「Twitter」>「アプリケーション」ページに移動し、「新しいアプリケーションを追加」をクリックします。Twitterアカウントにログインしている必要があります。複数のアカウントがある場合は、正しいアカウントにログインしていることを確認してください。
  2. アプリケーション名」テキスト・フィールドに「NB User Timeline Application」と入力します。
  3. アプリケーションの説明」フィールドに説明を入力します。これは必須です。「user_timeline処理をコールする、NetBeans IDEで作成されたJavaアプリケーション」などのように入力できます。
  4. アプリケーションのウェブ・サイトURL」フィールドに任意のURLを入力します。
  5. アプリケーションの種類」オプションで「クライアント・アプリケーション」ラジオ・ボタンを選択します。
  6. 標準のアクセス・タイプ」セクションで「Read & Write」ボタンを選択します。

    注意: 必ず「Read & Write」を選択するようにしてください。後で戻って設定を編集できますが、これがアプリケーションのアクセス権に影響を与えることはないようです。

  7. 他のオプションをデフォルトのままにして「保存する」を押します。登録したアプリケーションの詳細が記載されたブラウザ・ページが開きます。重要な詳細情報はConsumer keyおよびConsumer secretです。
  8. ブラウザからConsumer keyをコピーします。IDEで、CONSUMER_KEYが設定されている行を見つけます。引用符の間にConsumer keyの値を貼り付けます。
    CONSUMER_KEYおよびCONSUMER_SECRETの場所を示すTwitterClient
  9. Consumer secret keyをブラウザからTwitterSwingClientにコピーして貼り付けます。変更を保存します。

プロジェクトの実行

これでConsumer keyおよびConsumer secret keyを入手したので、プロジェクトを実行できます。アプリケーションがTwitterをコールすると、このアプリケーションによるデータ・アクセスを許可するためのブラウザ・ウィンドウが開きます。

プロジェクトを実行するするには:

  1. TwitterSwingClientがメイン・プロジェクトである場合は[F6]を押します。そうでない場合は、「TwitterSwingClient」プロジェクト・ノードを右クリックし、コンテキスト・メニューから「実行」を選択します。
  2. ブラウザ・ウィンドウが開き、登録したアプリケーションがTwitterのデータにアクセスすることを許可するかどうか質問されます。「許可する」をクリックします。
  3. ブラウザ・ウィンドウが更新され、新しいウィンドウにPINが表示されます。このPINをコピーします。
  4. IDEの「出力」ウィンドウに、oauth_verifier文字列の入力をリクエストするメッセージが表示されます。コロン(:)の後にPINを貼り付け、[Enter]を押します。
    まだ貼り付けられていないベリファイア文字列を要求するIDEの「出力」ウィンドウ
  5. デスクトップ・クライアントが開き、最新のTwitterステータス・メッセージが表示されます。
    ユーザー・アイコンとステータスが表示された実行中のアプリケーション

複数のサービスのコール

アプリケーションの最終的な設計には、user_timeline{format} (すでにコール済)、update{format}およびfriends_timeline{format}の3つのTwitterサービスのコールが必要です。これらのサービスのコールは、1つのログインを共有する必要があります。コールが同じログインを共有するには、それらが同じクライアント・クラスの中に存在する必要があります。1つのクライアントから複数のサービスをコールするには、次の2つのステップが必要です。

  • 複数のサービスを1つのクライアント・クラスに追加する
  • クライアント・クラスのリソース・パスを変更する

1つのクラスへの複数サービスの追加と複数コールの結合

この項では、まず他のサービスごとにクライアントを追加し、それらを1つの汎用クライアントにマージします。

複数のサービスを追加するには:

  1. [Alt]-[Insert]を押して「RESTクライアントを生成」を選択します。
    initUserInfoメソッドに挿入するコードのメニュー
  2. ユーザー・ステータスの表示の項でRESTクライアントを生成したときと同じ手順を実行します。ただし、「[statuses]」>「[update.{format}]」サービスを選択します。IDEは、Twitter_OAuth_user_timeline__format_JerseyClientクラスと類似した内部クラスTwitter_OAuth_update__format_JerseyClientを生成します。
    更新フォーマット・サービスを表示する「使用可能なRESTリソース」ダイアログ
  3. 上記のステップ1および2を繰り返します。ただし、「[friends_timeline.{format}]」サービスのクライアントを追加します。
  4. 元のTwitter_OAuth_user_timeline__format_JerseyClientクラスの名前を変更します。これを、3つすべてのサービスをコールする汎用クライアント・クラスとして使用します。Twitter_OAuth_user_timeline__format_JerseyClientという名前のインスタンスを選択し、[Ctrl]-[R]を押すか、右クリックして「リファクタリング」>「名前変更」を選択します。「クラス名を変更」ダイアログが開きます。新しい名前「TwitterClient」を入力します。
    新しい名前TwitterClientが入力された「クラス名を変更」ダイアログ
  5. 「リファクタリング」をクリックします。IDEはクラス名のすべての使用箇所を置き換えます。
    複数の場所で変更されたクラス名
  6. 「ナビゲータ」ウィンドウで、「Twitter_Oauth_friends_timeline__format_JerseyClient」クラスを見つけます。このクラスで、「getFriendsTimeline」メソッドを見つけてダブルクリックします。
    getPublicTimelineメソッドを示す「ナビゲータ」ウィンドウ
  7. エディタのカーソルがgetFriendsTimelineメソッドに移動します。次に示すそのメソッドを切り取ります。
    public <T> T getFriendsTimeline(Class<T> responseType, String since, String since_id, String page, String count) throws UniformInterfaceException {
          String[] queryParamNames = new String[]{"since", "since_id", "page", "count"};
          String[] queryParamValues = new String[]{since, since_id, page, count};
          return webResource.queryParams(getQueryOrFormParams(queryParamNames, queryParamValues)).accept(javax.ws.rs.core.MediaType.TEXT_XML).get(responseType);
    }
  8. getFriendsTimelineメソッドを、TwitterClient内部クラスのgetUserTimelineメソッドの下に貼り付けます。
  9. Twitter_OAuth_update__format_JerseyClientのupdateStatusメソッドを、TwitterClientのgetFriendsTimelineメソッドの下に切り取って貼り付けます。

リソース・パスの変更

すべてのTwitterサービス・コールが、1つのクライアント・クラスに存在するようになりました。しかし、このクライアント・クラスのリソース・パスは正しく構成されていません。IDEが当初クラスを生成したとき、user_timelineサービスに特有のリソース・パスを生成しました。クラス・レベルでリソース・パスが汎用的になり、特定のパスがサービス・コール・メソッドによって割り当てられるようにクラスを変更する必要があります。

リソース・パスを変更するには:

  1. TwitterClientコンストラクタを見つけて、String formatパラメータを除去します。
    コンストラクタからパラメータを除去する前後の表示
  2. 赤いエラー・バーが右のマージンに表示されます。これをクリックすると、TwitterClientクラスをインスタンス化するinitUserInfoの行に移動します。この行はclient=new TwitterClient("xml");です。TwitterClientコンストラクタは「xml」のパラメータを取得しなくなったため、「xml」のパラメータを削除します。この時点で、この行は「client=new TwitterClient();」になっています。エラー・アイコンが消えます。
  3. TwitterClientコンストラクタに戻ります。(「ナビゲータ」ウィンドウを使用すると便利。)次の行を探します。
    String resourcePath = java.text.MessageFormat.format("statuses/user_timeline.{0}", new Object[]{format}); 

    この行は、クラス全体のresourcePathを設定します。resourcePathが親のstatusesディレクトリを指すように、この行を変更します。この時点で、この行は次のようになっています。

    String resourcePath = "statuses";
  4. getUserTimelineメソッドに移動します。return行を見つけます。
    return webResource.queryParams(getQueryOrFormParams(queryParamNames, queryParamValues))...;

    コールの最初に、パス情報(次で太字で表示)を追加します。

    return webResource.path("user_timeline.xml").queryParams(getQueryOrFormParams(queryParamNames, queryParamValues)).accept(javax.ws.rs.core.MediaType.TEXT_XML).get(responseType);
  5. getFriendsTimelineメソッドに移動します。return行を見つけます。
    return webResource.queryParams(getQueryOrFormParams(queryParamNames, queryParamValues)).accept(javax.ws.rs.core.MediaType.TEXT_XML).get(responseType);

    コールの最初に、パス情報を追加します。

    return webResource.path("friends_timeline.xml").queryParams(getQueryOrFormParams(queryParamNames, queryParamValues)).accept(javax.ws.rs.core.MediaType.TEXT_XML).get(responseType);
  6. updateStatusメソッドに移動します。return行を見つけます。
    return webResource.type(javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED)...

    コールの最初に、パス情報を追加します。

    return webResource.path("update.xml").type(javax.ws.rs.core.MediaType.APPLICATION_FORM_URLENCODED).post(responseType, getQueryOrFormParams(formParamNames, formParamValues));
  7. TwitterClientのsetResourcePathメソッドを見つけてコメントにします。これがコールされることはありませんが、予防策です。
  8. Twitter_OAuth_update__format_JerseyClientおよびTwitter_Oauth_friends_timeline__format_JerseyClientのクラスを削除します。

これで、3つすべてのサービスがJerseyClientクラスから使用できるようになりました。

重要: 上記の手順では、3つのメソッドで3つのreturn文を変更します。必ず3つすべてを変更するようにしてください。

ステータスの更新アクションの追加

  1. TwitterJFrameのデザイン・ビューに戻ります。JFrame内の「Update」ボタンをダブルクリックします。エディタがソース・ビュー内の、IDEによって作成されたjButton1ActionPerformedメソッドの本体に戻ります。
    「ソース」ビューのTwitterJFrameで、新規に作成したjButton1ActionPerformedメソッドの中央にカーソルが置かれた状態
  2. jButton1ActionPerformedメソッドの本体に次のように入力します。

    注意: ステータスを更新すると、ステータスはUTF-8エンコードで表示されます。たとえば、スペースが+記号または%21記号で表示されます。ただし、テキスト・フィールドの内容をUTF-8に変換しないと、ステータス・メッセージになんらかのスペースを入力したときに、アプリケーションが「Invalid signature」で失敗します。この回避法を見つけた方は、チュートリアルの下部にある「フィード・バック」リンクを使用してご連絡ください。

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
        String rawStatus = jTextField1.getText().trim();
        String status = URLEncoder.encode(rawStatus, "UTF-8");
        client.makeOAuthRequestUnique();
        try {
        client.updateStatus(String.class, status, null);
        } catch(UniformInterfaceException ex) {
            System.out.println("Exception when calling updateStatus = " + ex.getResponse().getEntity(String.class));
        }
    
    }    

このコードは、テキスト・フィールドからテキストを取得して、それをupdateStatusクラスに渡します。makeOAuthRequestUniqueへのコールに注意してください。コードがこのメソッドをコールするのは、アプリケーションが初期化したときに、initUserInfologinおよびinitOAuthへのコールによってアプリケーションがすでにログインして認証されているためです。makeOAuthRequestUniqueメソッドは、既存のOAuthノンスおよびタイムスタンプ・パラメータを増やし、各リクエストを一意にします。

注意: ここでmakeOAuthRequestUniqueまたはinitOAuthをコールする方がよいのかどうか、完全には明らかになっていません。認証の問題が発生した場合は、両方の方法で検証してください。

また、updateStatusへのコールをtry/catchブロックでラップしていることに注意してください。これは、updateStatusをコールするときに起こる可能性のある問題のデバッグに役立ちます。

JFrameでのユーザー名とステータスの表示

これで、Twitterの友達のユーザー名とステータスを表示するアプリケーションを設定しました。

  • ユーザー名とステータスをTwitterから取得するには、アプリケーションの実行時にTwitterのgetFriendsTimeline操作をコールします。これを設定するには、mainrunメソッドをオーバーライドする新しいrunメソッドを作成します。このメソッドにgetFriendsTimelineへのコールを挿入します。
  • 表示を自動的に更新するには、getFriendsTimeline操作が含まれるrunメソッドを、75秒間隔でrunメソッドを実行するjava.util.TimerTaskラップします。
  • アプリケーションでは、データをリスト内のセルに表示します。リスト内のセルとしてレンダリングできるGUIコンポーネントにデータを渡す必要があります。また、データの表示書式を設定します。そのためには、javax.swing.ListCellRendererを実装する新しいJPanelを作成します。このJPanelは、ユーザー名とステータスをJLabelで渡すjava.awt.Componentオブジェクトを返します。JPanelの形式を調整します。
  • TwitterJFrameで、JPanelから返されるコンポーネント・オブジェクトを表示するようにJListを設定します。

TimerTaskの作成

Twitterの友達のタイムラインの表示を自動的に更新するには、実行コードをTimerTaskでラップします。先にTimerTaskラッパーを作成してから、実行コードを挿入します。このようにしないと、コードがエラー警告だらけになります。

TimerTaskを作成するには:

  1. TwitterJFrameをエディタのソース・ビューで開きます。
  2. クラス宣言とコンストラクタを探します。
    public class TwitterJFrame extends javax.swing.JFrame {
    
        /** Creates new form TwitterJFrame */
        public TwitterJFrame() {
            initComponents();
            try {
                initUserInfo();
            } catch (IOException ex) {
                Logger.getLogger(TwitterJFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
  3. コンストラクタのメソッド本体のinitComponents();の前でjava.util.Timerクラスをインスタンス化します。パラメータで、Timerスレッドを「Twitter Updater」という名前にし、デーモンとして実行できないことを指定します。
    public class TwitterJFrame extends javax.swing.JFrame {
    
        /** Creates new form TwitterJFrame */
        public TwitterJFrame() {
            Timer t = new Timer("Twitter Updater`", false);
            initComponents();
            try {
                initUserInfo();
            } catch (IOException ex) {
                Logger.getLogger(TwitterJFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
                        
  4. エディタ内の任意の場所を右クリックしてコンテキスト・メニューから「インポートを修正」を選択するか、または[Ctrl]/[⌘]-[Shift]-[I]を押します。ダイアログが開き、インポートするクラスの選択肢が表示されます。java.util.Timerのインポート文を追加します。
  5. Timerのインスタンス化の下で、新しいTimer.scheduleAtFixedRateメソッドを作成します。メソッドのパラメータは、TimerTaskオブジェクト、最初にタスクを実行するまでの遅延、およびタスクを実行する間隔です。初回実行前に30秒待機してから、75秒ごとに再実行するようにメソッドを設定します。(最初に長い遅延があるのは、ログインする時間を考慮するため。)コードは次の太字部分のようになります。実行コードを挿入する部分は空の行のままです。java.util.TimerTaskのインポート文を追加する必要があることに注意してください。
    public class TwitterJFrame extends javax.swing.JFrame {
    
        /** Creates new form TwitterJFrame */
        public TwitterJFrame() {
            Timer t = new Timer("Twitter Updater`", false);
            t.scheduleAtFixedRate(new TimerTask() {

    }, 30000, 75000);
    initComponents(); try { initUserInfo(); } catch (IOException ex) { Logger.getLogger(TwitterJFrame.class.getName()).log(Level.SEVERE, null, ex); } }

これでTimerTaskラッパー・コードは完成です。次に、実行コードを追加します。

getFriendsTimeline操作を含むrunメソッドの追加

ユーザー名とステータスを表示するには、最初にアプリケーションでこのデータをTwitterから取得します。Twitter SaaSには、ユーザー名とステータスを取得するためのgetFriendsTimeline操作があります。アプリケーションの実行時にgetFriendsTimeline操作を実行するには、操作がrunメソッド内にある必要があります。アプリケーションはユーザー名とステータスをJListに表示するため、最後にgetFriendsTimelineの結果を、DefaultListModelオブジェクトの要素として追加する必要があります。

getFriendsTimeline操作を含むrunメソッドを追加するには:

  1. TwitterJFrameコンストラクタの上に、statusesListModelというDefaultListModelオブジェクトを作成します。
    public class TwitterJFrame extends javax.swing.JFrame {
    
        private DefaultListModel statusesListModel = new DefaultListModel();
    
    /** Creates new form TwitterJFrame */ public TwitterJFrame() {
  2. エディタ内の任意の場所を右クリックしてコンテキスト・メニューから「インポートを修正」を選択するか、または[Ctrl]/[⌘]-[Shift]-[I]を押します。このアクションで、jDefaultListModelのインポート文が追加されます。
  3. TimerTaskオブジェクトの本体で、新しいrunメソッドを作成します。@Override注釈を使用して、main内のrunメソッドをオーバーライドします。
    public class TwitterJFrame extends javax.swing.JFrame {
    
        private DefaultListModel statuses = new DefaultListModel();

    /** Creates new form TwitterJFrame */ public TwitterJFrame() { Timer t = new Timer("Twitter Updater`", false);
    t.scheduleAtFixedRate(new TimerTask() {
    @Override
    public void run(){

    }

    }, 1500, 75000);
    initComponents(); try { initUserInfo(); } catch (IOException ex) { Logger.getLogger(TwitterJFrame.class.getName()).log(Level.SEVERE, null, ex); }
  4. 次のコードrunメソッドの本体に挿入します。
    @Override
    public void run() {
        System.out.println("Timer Task is running");
        try {
            client.initOAuth();
            Statuses response = client.getFriendsTimeline(Statuses.class, null, null, null, "10");
            // Clear the list model so it does not replicate the contents from the last run
            statusesListModel.clear();
            // Create a Status Type object for every status in the Status list, and add an element
            // to the list model for every status type object
            for (final StatusType st : response.getStatus()) {
                SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        statusesListModel.addElement(st);
                    }
                });
            }
        } catch (UniformInterfaceException ex) {
        System.out.println("Exception when calling getFriendsTimeline = " + ex.getResponse().getEntity(String.class));
        }
    }

これで、Twitterの友達のタイムラインからステータスを取得するコードが完成しました。次に、リスト要素をGUIコンポーネント内にレンダリングするComponentを返す新しいクラスを作成します。

リスト・セル・レンダリング・コンポーネントの作成

Twitterの友達のタイムラインからStatusオブジェクトを取得し、各ステータスのリスト要素を作成するコードが完成しました。しかし、これらのリスト要素をそのままJListに表示することはできません。データをGUIコンポーネントに渡す必要があります。そのためには、javax.swing.ListCellRendererを実装する新しいJPanelを作成します。このJPanelは、ユーザー名とステータスをJLabelで渡すjava.awt.Componentオブジェクトを返します。JPanel内のJLabelの外観はカスタマイズできます。

リスト・セル・レンダリング・コンポーネントを追加するには:

  1. プロジェクトのノードを右クリックし、「新規」>「JPanelフォーム」を選択します。新規JPanelフォーム・ウィザードが開きます。
  2. JPanelの名前を「Item」にし、twitterclientパッケージに入れます。
    Itemというパネルとパッケージtwitterclientを示す新規JPanelフォーム・ウィザード
  3. 「終了」をクリックします。エディタのデザイン・ビューでItem.javaが開きます。
  4. 「ラベル」と「テキスト・ペイン」をJPanel内にドラッグ・アンド・ドロップします。「ラベル」にはユーザー名を、「テキスト・ペイン」にはそのユーザーのステータス・メッセージを表示します。
  5. データを表示する方法にあわせて「ラベル」と「テキスト・ペイン」を配置します。次のイメージでは、ユーザー名を左上に表示し、ステータス・テキストをその下に少しインデントして表示しています。サンプル・プロジェクトでは、データが左上、ユーザー名が右下になっています。テキスト・ペインのテキストが長いときにペインを拡張できるように、JPanel内でテキスト・ペインの下に十分なスペースを残しておきます。
    ユーザー名とステータス・テキストを表示するJLabelのレイアウト
  6. JLabel要素を右クリックし、コンテキスト・メニューから「プロパティ」を選択します。「プロパティ」で、フォント、色、位置揃え、およびその他の属性を変更できます。labelForプロパティをjTextPane1に設定します。これでアクセシビリティが向上します。好みの外観になるまで、ラベルのプロパティをいろいろ試してみます。次のイメージでは、「前景」プロパティでフォントの色を青に設定しています。
    「前景」が青に設定されたJLabelのプロパティ・ダイアログ
  7. JTextPaneのプロパティ・ダイアログを開き、その外観を調整します。
  8. Item.javaのソース・ビューに切り替えます。生成されたコード・ブロックを探し、展開します。JLabelとJTextPaneのプロパティを設定したときに、IDEによって生成されたコードが表示されます。

    次のイメージで、JLabel1の色が青に設定されていることに注意してください。JTextPaneに設定されているプロパティも確認してください。

    デザイン・ビューでJLabelのプロパティを設定することによってItem.javaに生成されたコード
  9. クラス宣言を探し、コードimplements ListCellRendererを追加します。
    public class Item extends javax.swing.JPanel implements ListCellRenderer {
  10. [Ctrl]-[Shift]-[I] (MacOSの場合は[⌘]-[Shift]-[I])を押します。このアクションで、javax.swing.ListCellRendererのインポート文が追加されます。すべての抽象メソッドを実装する必要があることを示す警告が表示されます。
  11. 生成されたコード・ブロックと、変数の宣言の間に空の行を数行追加します。このスペースに、抽象メソッドgetListCellRendererComponentを実装する次のコードを追加します。(コードは、コピーして貼り付けるか、コード補完を使用して再現可能。)このコードは、デフォルトのラベル・テキストusernameとtextを、twitteroauthのStatusTypeクラスで取得するText、UserおよびScreenNameの各オブジェクトに置き換えます。そして、これらの新しいJLabelのテキスト値を含むComponentのインスタンスを返します。
    public Component getListCellRendererComponent(JList list, Object value, int index, boolean sel, boolean focus) {
            StatusType st = (StatusType) value;
            jTextPane1.setText(st.getText());
            jLabel1.setText("<html>" + st.getUser().getScreenName() + "</html>");
            return this;
    }
  12. [Ctrl]-[Shift]-[I] (MacOSの場合は[⌘]-[Shift]-[I])を押します。このアクションで、StatusTypeクラスとComponentクラスのインポート文が追加されます。StatusTypeのtwitteroauthバージョンを選択します。Item.javaを保存します。

これで、ユーザー名とステータスをJLabelとJTextPaneに表示するComponentオブジェクトを返すItemクラスが完成しました。次に、このComponentを使用するようにTwitterJFrameを変更します。

TwitterJFrameでのコンポーネントの表示

Item.javaで作成されるComponentオブジェクトを表示するには、TwitterJFrame内のJListで、セルのレンダラにItem.javaを使用する必要があります。

  1. TwitterJFrameに戻ります。デザイン・ビューでJListを選択します。右クリックしてプロパティを開きます。
    TwitterJFrameのJList要素の「プロパティ」ダイアログ
  2. modelプロパティを選択します。[Ctrl]-[Space]を押します。カスタム・プロパティ・エディタが開き、デフォルトのテキストがリストに表示されます。
    JListのカスタム・プロパティ・エディタ
  3. 「jList1のmodelプロパティを設定」ドロップダウン・メニューで「カスタム・コード」を選択します。jLabel1.setModelのプロパティを入力するテキスト・フィールドが表示されます。フィールドに「statusesListModel」と入力し、「OK」をクリックします。
    jListのカスタム・プロパティ・エディタのカスタム・コード・エディタでsetModel(statuses)を選択した状態
  4. プロパティ・ダイアログで、「cellRenderer」を選択し、[Ctrl]-[Space]を押します。カスタム・プロパティ・エディタが開きます。
  5. 「jList1のcellRendererプロパティを設定」ドロップダウン・メニューで「カスタム・コード」を選択します。jList1.cellRendererのプロパティを入力するテキスト・フィールドが表示されます。「new Item()」と入力し、「OK」をクリックします。
    JListのカスタム・セル・レンダラ・プロパティ・エディタで新規項目が選択された状態

これで、クライアント・アプリケーションは完成です。すべてのファイルを保存し、アプリケーションを実行します。(プロジェクト・ノードを右クリックして「実行」を選択。)アプリケーションが開き、タイムラインのメッセージ・リストと、自分のステータスを示すフィールドが表示されます。

Twitterメッセージが表示された実行中のクライアント

プロキシを経由した接続;

プロキシを経由してインターネットに接続している場合は、プロキシ設定を使用することをIDEとTwitterSwingClientプロジェクトの両方で構成する必要があります。

IDEを構成するには、「ツール」>「オプション」>「一般」を開きます。「プロキシ設定」セクションを探します。プロキシ設定を使用しない、システムのプロキシ設定を使用する、または手動でプロキシを設定することを選択できます。システムのプロキシ設定は、デフォルトのシステムWebブラウザから取得されます。

TwitterSwingClientプロジェクトでは、HTTPプロトコル・ハンドラで使用されているプロキシを指定する必要があります。この方法はJava SE 6のドキュメントで説明しています。プロキシは、仮想マシンに渡すオプションで指定します。NetBeans IDEでは、「プロパティ」ダイアログでこれらのオプションを設定します。

TwitterSwingClientプロジェクトのプロキシを指定するには:

  1. 「プロジェクト」ウィンドウでTwitterSwingClientプロジェクト・ノードを右クリックし、「プロパティ」を選択します。「プロパティ」ダイアログが開きます。
  2. 「カテゴリ」ツリーで「実行」を選択します。実行のプロパティが表示されます。
  3. 「VMオプション」フィールドに「-Dhttp.proxyHost=server -Dhttp.proxyPort=port」と入力します。「server」と「port」は、実際のプロキシ・サーバーのホスト名とポートに置き換えます。
    「プロジェクト・プロパティ」ダイアログの「VMオプション」のプロキシ設定

その他の課題

有益なアイデアをいくつか紹介します。

  • Twitterのユーザー・アイコン(ブラウザ内)を変更し、再度クライアントを実行します。新しいアイコンは表示されましたか。
  • いくつかの機能があるツールバーをJFrameに追加します。

関連項目

NetBeans IDEを使用したWebサービスの作成および使用、またGUIのデザインの詳細は、次のリソースを参照してください。

メーリング・リストに登録することによって、NetBeans IDE Java EE開発機能に関するご意見やご提案を送信したり、サポートを受けたり、最新の開発情報を入手したりできます。

get support for the NetBeans

Support


By use of this website, you agree to the NetBeans Policies and Terms of Use. © 2013, Oracle Corporation and/or its affiliates. Sponsored by Oracle logo