Twitter のグラフィカルクライアントの作成
このチュートリアルでは、NetBeans IDE を使用して、Twitter の友達のタイムラインのメッセージを表示し、Twitter のステータスを確認、更新できる REST ベースの簡単なグラフィカルクライアントを作成します。このアプリケーションでは、Swing と NetBeans IDE での Twitter の SaaS 操作のサポートを使用します。
Twitter のアカウントがない場合は、twitter.com でアカウントを作成してから、このチュートリアルの手順に従ってください。
このアプリケーションの完全なサンプルをダウンロードできます。サンプルをダウンロードするには、ここ をクリックしてください。
目次
このチュートリアルを完了するには、次のソフトウェアとリソースが必要です。
JFrame のデザイン
ここでは、Twitter の友達のタイムライン、ユーザーアイコン、およびステータスを確認および更新する場所を表示する GUI 要素を作成します。GUI 要素はすべて JFrame にラップします。GUI 要素は、ここに示すとおりに配置しなくてもかまいません。このレイアウトは一例です。たとえば、さらに機能を追加することもできます。ただし、少なくともこのチュートリアルで説明している要素はすべて作成してください。
JFrame をデザインするには、次の手順に従います。
「ファイル」>「新規プロジェクト」を選択します。「新規プロジェクト」ウィザードが開きます。「Java」カテゴリ、「Java アプリケーション」プロジェクトの順に選択します。「次へ」をクリックします。
プロジェクトに TwitterSwingClient という名前を付けます。プロジェクトの場所を選択します。「主クラスを作成」の選択を解除します (JFrame が主クラスになる)。「完了」をクリックします。
IDE によって TwitterSwingClient プロジェクトが作成され、「プロジェクト」ウィンドウに表示されます。「TwitterSwingClient」プロジェクトノードを右クリックし、「新規」>「JFrame フォーム」(または「新規」>「その他」>「Swing GUI フォーム」>「JFrame フォーム」) を選択します。「新規 JFrame フォーム」ウィザードが開きます。
フォーム名を TwitterJFrame にし、twitterclient というパッケージを作成します。「完了」をクリックします。
エディタのデザインビューで TwitterJFrame が開きます。ここには、JFrame にドラッグ&ドロップできるすべての Swing コンポーネントのパレットがあります。
パレットの「Swing コントロール」の下にある「ボタン」アイコンをクリックします。これを JFrame の右下隅にドラッグ&ドロップします。ボタンに jButton1 と表示されます。これが、この JButton オブジェクトの名前です。
jButton1 を右クリックし、コンテキストメニューから「テキストを編集」を選択します。表示テキストを「Update」に変更します。
「ラベル」(jLabel1) を JFrame の左下隅にドラッグ&ドロップします。表示テキストを「Icon」に変更します。このラベルにはユーザーアイコンを表示します。
「テキストフィールド」(jTextField1) をラベルとボタンの間にドラッグ&ドロップします。表示テキストを「Status」に変更します。テキストフィールドの右端をクリックし、ボタンの方向に伸ばします。ボタンからの推奨の距離を示す青いガイドラインが表示されます。
jLabel1 を右クリックし、コンテキストメニューから「プロパティー」を選択します。「jLabel1 プロパティー」ダイアログが開きます。labelFor プロパティーを jTextField1 に設定します (これでアクセシビリティーが向上)。
「maximumSize」、「minimumSize」、および「preferredSize」の各プロパティーを探します。Twitter のアイコンのサイズ (48px X 48px) に合わせてこれらの各プロパティーを [48,48] に設定します。
JFrame の上部に「スクロール区画」をドラッグ&ドロップします。そのボーダーをドラッグして、テキストフィールドとボタンの上のスペースをほとんど、またはすべて占めるように区画を拡大します (サンプル のメニューのように、あとで機能を追加する場合は余白を残しておくことも可能)。
スクロール区画内に「リスト」をドラッグ&ドロップします。項目リストのサンプルが表示されます。TwitterJFrame を保存します。JFrame は次の図のようになります。
これで、Swing クライアントの基本的な GUI コンポーネントが揃いました。次に、最初の Twitter SaaS (Software as a Service) 操作を追加します。
ユーザーステータスの表示
ここでは、新しいメソッドを作成し、そのメソッドに Twitter の getUserTimeline 操作を追加します。getUserTimeline 操作は、ユーザーアイコンと現在のステータスを取得します。次に、アイコンとステータスをそれぞれ jLabel1 と jTextField に表示するコードをメソッドに追加します。最後に、JFrame のコンストラクタに、メソッドを初期化する行を追加します。
ユーザーステータスを表示するには、次の手順に従います。
TwitterJFrame のソースビューに切り替えます。
Alt-Insert を押すか、右クリックしてコンテキストメニューから「コードを挿入」を選択します。挿入するコードのメニューが開きます。
「REST クライアントを生成」をクリックします。「使用可能な REST リソース」ダイアログが開きます。
「IDE 登録済み」ラジオボタンを選択して「参照」をクリックします。「Twitter」>「Twitter OAuth」>「[statuses]」>「[user_timeline.{format}]」に移動します。「了解」をクリックします。
これで、「使用可能な REST リソース」ダイアログに、選択された Twitter OAuth user_timeline リソース、対応するクラス名、および OAuth 認証タイプが表示されるようになります。「了解」をクリックします。
WADL の XML スキーマ参照から Java オブジェクトを生成するかどうかを尋ねるダイアログが開きます。「はい」をクリックします。
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 ) を呼び出します。
「ナビゲータ」ウィンドウに表示されるクラス構造は次のとおりです。
TwitterJFrame で、内部 Twitter_OAuth_user_timeline__format_JerseyClient クラスのすぐ上に次のコード行を挿入します。このコードは、内部クラスのインスタンスを表す client という変数を作成します。
private Twitter_OAuth_user_timeline__format_JerseyClient client;
TwitterJFrame の main メソッドを見つけます。このメソッドの上に、MalformedURLException および IOException をスローする initUserInfo という新しいメソッドを作成します。
private void initUserInfo() throws MalformedURLException, IOException {
}
initUserInfo のメソッド本体に次のコードを挿入します。コードのコメントは、コードの処理について説明しています。
private void initUserInfo() throws MalformedURLException, IOException {
//内部サービスクラスのインスタンスを作成
client = new Twitter_OAuth_user_timeline__format_JerseyClient("xml");
//ログインし、トークンを取得し、consumer および secret key に
//トークンを追加
client.login();
client.initOAuth();
//getUserTimeline を呼び出し、ステータスの一覧を取得し、
//StatusType オブジェクトとして最新のステータスを渡し、
//そのオブジェクトのテキストを JTextField で表示
Statuses statuses = client.getUserTimeline(Statuses.class, null, null, null, "1");
StatusType st = statuses.getStatus().get(0);
jTextField1.setText(st.getText().trim());
//StatusType オブジェクトから UserType オブジェクトを取得し、そのユーザーアイコンの
//URL を取得し、そのアイコンを JLabel で表示
UserType user = st.getUser();
String iconSrc = user.getProfileImageUrl();
URL iconUrl = new URL(iconSrc);
ImageIcon icon = new ImageIcon(iconUrl, user.getScreenName());
jLabel1.setIcon(icon);
}
(Ctrl-Shift-I、またはコンテキストメニューから)「すべてのインポートを修正」ダイアログを開きます。ダイアログで、デフォルトの Java StatusType ではなく、twitter.twitteroauth.twitterresponse.StatusType を選択します。
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 キーを取得するには:
ブラウザを開きます。「Twitter」>「アプリケーション」 ページに移動し、「新しいアプリケーションを追加 » 」をクリックします。Twitter アカウントにログインしている必要があります。複数のアカウントを持っている場合は、正しいアカウントにログインしていることを確認してください。
「アプリケーション名 」テキストフィールドに「NB User Timeline Application 」と入力します。
「アプリケーションの説明 」フィールドに説明を入力します。これは必須です。「user_timeline 処理を呼び出す、NetBeans IDE で作成された Java アプリケーション」などのように入力できます。
「アプリケーションのウェブサイトURL 」フィールドに任意の URL を入力します。
「アプリケーションの種類 」オプションで「クライアントアプリケーション」ラジオボタンを選択します。
「標準のアクセスタイプ 」セクションで「Read & Write」ボタンを選択します。
注: 必ず「Read & Write」を選択するようにしてください。あとで戻って設定を編集できますが、これがアプリケーションのアクセス権に影響を与えることはないようです。
ほかのオプションをデフォルトのままにして「保存する」を押します。登録したアプリケーションの詳細が記載されたブラウザページが開きます。重要な詳細情報は Consumer key および Consumer secret です。
ブラウザから Consumer key をコピーします。IDE で、CONSUMER_KEY が設定されている行を見つけます。引用符の間に Consumer key の値をペーストします。
Consumer secret key をブラウザから TwitterSwingClient にコピー&ペーストします。変更を保存します。
プロジェクトの実行
これで Consumer key および Consumer secret key を入手したので、プロジェクトを実行できます。アプリケーションが Twitter を呼び出すと、このアプリケーションによるデータアクセスを許可するためのブラウザウィンドウが開きます。
プロジェクトを実行する
TwitterSwingClient が主プロジェクトである場合は F6 を押します。そうでない場合は、「TwitterSwingClient」プロジェクトノードを右クリックし、コンテキストメニューから「実行」を選択します。
ブラウザウィンドウが開き、登録したアプリケーションが Twitter のデータにアクセスすることを許可するかどうかが確認されます。「許可する」をクリックします。
ブラウザウィンドウが更新され、新しいウィンドウに PIN が表示されます。この PIN をコピーします。
IDE の「出力」ウィンドウに、oauth_verifier 文字列の入力を要求するメッセージが表示されます。コロン (:) のあとに PIN をペーストし、Enter を押します。
デスクトップクライアントが開き、最新の Twitter ステータスメッセージが表示されます。
複数のサービスの呼び出し
アプリケーションの最終的な設計には、user_timeline{format} (すでに呼び出し済み)、update{format}、および friends_timeline{format} の 3 つの Twitter サービスの呼び出しが必要です。これらのサービスの呼び出しは、1 つのログインを共有する必要があります。呼び出しが同じログインを共有するには、それらが同じクライアントクラスの中になければいけません。1 つのクライアントから複数のサービスを呼び出すには、次の 2 つの手順が必要です。
複数のサービスを 1 つのクライアントクラスに追加する
クライアントクラスのリソースパスを変更する
1 つのクラスへの複数サービスの追加と複数呼び出しの結合
この節では、まずほかのサービスごとにクライアントを追加してから、それらを 1 つの汎用クライアントにマージします。
複数のサービスを追加するには:
Alt-Insert を押して「REST クライアントを生成」を選択します。
「ユーザーステータスの表示 」の節で REST クライアントを生成したときと同じ手順を実行します。ただし、「[statuses]」>「[update.{format}]」サービスを選択します。IDE は、Twitter_OAuth_user_timeline__format_JerseyClient クラスと類似した内部クラス Twitter_OAuth_update__format_JerseyClient を生成します。
上記の手順 1 および 2 を繰り返します。ただし、「[friends_timeline.{format}]」サービスのクライアントを追加します。
元の Twitter_OAuth_user_timeline__format_JerseyClient クラスの名前を変更します。これを、3 つすべてのサービスを呼び出す汎用クライアントクラスとして使用します。Twitter_OAuth_user_timeline__format_JerseyClient という名前のインスタンスを選択し、Ctrl-R を押すか、右クリックして「リファクタリング」>「名前を変更」を選択します。「名前を変更 クラス」ダイアログが開きます。新しい名前「TwitterClient」を入力します。
「リファクタリング」をクリックします。IDE はクラス名のすべての使用箇所を置き換えます。
「ナビゲータ」ウィンドウで、「Twitter_Oauth_friends_timeline__format_JerseyClient」クラスを見つけます。このクラスで、「getFriendsTimeline 」メソッドを見つけてダブルクリックします。
エディタのカーソルが 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);
}
getFriendsTimeline メソッドを、TwitterClient 内部クラスの getUserTimeline メソッドの下にペーストします。
Twitter_OAuth_update__format_JerseyClient の updateStatus メソッドを、TwitterClient の getFriendsTimeline メソッドの下にカット&ペーストします。
リソースパスの変更
すべての Twitter サービス呼び出しが、1 つのクライアントクラスに存在するようになりました。しかし、このクライアントクラスのリソースパスは正しく構成されていません。IDE が当初クラスを生成したとき、user_timeline サービスに特有のリソースパスを生成しました。クラスレベルでリソースパスが汎用的になり、特定のパスがサービス呼び出しメソッドによって割り当てられるようにクラスを変更する必要があります。
リソースパスを変更するには:
TwitterClient コンストラクタを見つけて、String format パラメータを削除します。
赤いエラーバーが右のマージンに表示されます。これをクリックすると、TwitterClient クラスをインスタンス化する initUserInfo の行に移動します。この行は client = new TwitterClient("xml"); です。TwitterClient コンストラクタは「xml」のパラメータを取得しなくなったため、「xml」のパラメータを削除します。この時点で、この行は「client = new TwitterClient(); 」になっています。エラーアイコンが消えます。
TwitterClient コンストラクタに戻ります (「ナビゲータ」ウィンドウを使用すると便利)。次の行を探します。
String resourcePath = java.text.MessageFormat.format("statuses/user_timeline.{0}", new Object[]{format});
この行は、クラス全体の resourcePath を設定します。resourcePath が親の statuses ディレクトリを指すように、この行を変更します。この時点で、この行は次のようになっています。
String resourcePath = "statuses";
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);
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);
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));
TwitterClient の setResourcePath メソッドを見つけてコメントにします。これが呼び出されることはありませんが、予防策です。
Twitter_OAuth_update__format_JerseyClient および Twitter_Oauth_friends_timeline__format_JerseyClient のクラスを削除します。
これで、3 つすべてのサービスが JerseyClient クラスから使用できるようになりました。
重要: 上記の手順では、3 つのメソッドで 3 つの return 文を変更します。必ず 3 つすべてを変更するようにしてください。
ステータスの更新アクションの追加
TwitterJFrame のデザインビューに戻ります。JFrame 内の「Update」ボタンをダブルクリックします。エディタがソースビューに戻り、IDE によって作成された jButton1ActionPerformed メソッド内にカーソルが置かれます。
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 への呼び出しに注目してください。コードがこのメソッドを呼び出すのは、アプリケーションが初期化したときに、initUserInfo の login および initOAuth への呼び出しによってアプリケーションがすでにログインして認証されているためです。makeOAuthRequestUnique メソッドは、既存の OAuth ノンスおよびタイムスタンプパラメータを増やし、各要求を一意にします。
注: ここで makeOAuthRequestUnique または initOAuth を呼び出す方がよいのかどうか、完全には明らかになっていません。認証の問題が発生した場合は、両方の方法で検証してください。
また、updateStatus への呼び出しを try/catch ブロックでラップしています。これは、updateStatus を呼び出すときに起こる可能性のある問題のデバッグに役立ちます。
JFrame でのユーザー名とステータスの表示
これで、Twitter の友達のユーザー名とステータスを表示するアプリケーションを設定しました。
ユーザー名とステータスを Twitter から取得するには、アプリケーションの実行時に Twitter の getFriendsTimeline 操作を呼び出します。これを設定するには、main の run メソッドをオーバーライドする新しい 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 を作成するには、次の手順に従います。
TwitterJFrame をエディタのソースビューで開きます。
クラス宣言とコンストラクタを探します。
public class TwitterJFrame extends javax.swing.JFrame {
/** 新しいフォーム TwitterJFrame を作成 */
public TwitterJFrame() {
initComponents();
try {
initUserInfo();
} catch (IOException ex) {
Logger.getLogger(TwitterJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
コンストラクタのメソッド本体の initComponents(); の前で java.util.Timer クラスをインスタンス化します。パラメータで、Timer スレッドを「Twitter Updater」という名前にし、デーモンとして実行できないことを指定します。
public class TwitterJFrame extends javax.swing.JFrame {
/** 新しいフォーム 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);
}
}
エディタ内の任意の場所を右クリックしてコンテキストメニューから「インポートを修正」を選択するか、Ctrl-Shift-I キーを押します。ダイアログが開き、インポートできるクラスが表示されます。java.util.Timer のインポート文を追加します。
Timer のインスタンス化の下で、新しい Timer.scheduleAtFixedRate メソッドを作成します。メソッドのパラメータは、TimerTask オブジェクト、最初にタスクを実行するまでの遅延、およびタスクを実行する間隔です。初回実行前に 30 秒待機してから、75 秒ごとに再実行するようにメソッドを設定します (最初に長い遅延があるのは、ログインする時間を作るため)。コードは次のボールド部分のようになります。実行コードを挿入する部分は空になっています。java.util.TimerTask のインポート文を追加する必要があります。
public class TwitterJFrame extends javax.swing.JFrame {
/** 新しいフォーム 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 メソッドを追加するには:
TwitterJFrame コンストラクタの上に、statusesListModel という DefaultListModel オブジェクトを作成します。
public class TwitterJFrame extends javax.swing.JFrame {
private DefaultListModel statusesListModel = new DefaultListModel();
/** 新しいフォーム TwitterJFrame を作成 */
public TwitterJFrame() {
エディタ内の任意の場所を右クリックしてコンテキストメニューから「インポートを修正」を選択するか、Ctrl-Shift-I キーを押します。この操作で、DefaultListModel のインポート文が追加されます。
TimerTask オブジェクトの本体で、新しい run メソッドを作成します。@Override 注釈を使用して、main 内の run メソッドをオーバーライドします。
public class TwitterJFrame extends javax.swing.JFrame {
private DefaultListModel statuses = new DefaultListModel();
/** 新しいフォーム 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);
}
次のコード を 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");
// 最後に実行された statusesListModel.clear(); による内容を複製しないようにリストモデルを消去
statusesListModel.clear();
// Status リストのすべてのステータスの Status Type オブジェクトを作成し、
// すべての Status Type オブジェクトを保持するリストモデルに要素を追加
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 の外観はカスタマイズできます。
リストセル描画コンポーネントを追加するには、次の手順に従います。
プロジェクトのノードを右クリックし、「新規」>「JPanel フォーム」を選択します。「新規 JPanel フォーム」ウィザードが開きます。
JPanel の名前を「Item 」にし、twitterclient パッケージに入れます。
「完了」をクリックします。エディタのデザインビューで Item.java が開きます。
「ラベル」と「テキスト区画」を JPanel 内にドラッグ&ドロップします。「ラベル」にはユーザー名を、「テキスト区画」にはそのユーザーのステータスメッセージを表示します。
データを表示する方法に合わせて「ラベル」と「テキスト区画」を配置します。次の図では、ユーザー名を左上に表示し、ステータステキストをその下に少しインデントして表示しています。サンプル プロジェクトでは、データが左上、ユーザー名が右下になっています。テキスト区画のテキストが長いときに区画を拡張できるように、JPanel 内でテキスト区画の下に十分なスペースを残しておきます。
JLabel 要素を右クリックし、コンテキストメニューから「プロパティー」を選択します。「プロパティー」で、フォント、色、位置揃え、およびその他の属性を変更できます。labelFor プロパティーを jTextPane1 に設定します。これでアクセシビリティーが向上します。好みの外観になるまで、ラベルのプロパティーをいろいろ試してみます。次の図では、「前景」プロパティーでフォントの色を青に設定しています。
JTextPane のプロパティーダイアログを開き、その外観を調整します。
Item.java のソースビューに切り替えます。生成されたコードブロックを探し、展開します。JLabel と JTextPane のプロパティーを設定したときに、IDE によって生成されたコードが表示されます。
次の図で、JLabel1 の色が青に設定されていることがわかります。JTextPane に設定されているプロパティーも確認してください。
クラス宣言を探し、コード implements ListCellRenderer を追加します。
public class Item extends javax.swing.JPanel implements ListCellRenderer {
Ctrl-Shift-I キーを押します。この操作で、javax.swing.ListCellRenderer のインポート文が追加されます。すべての抽象メソッドを実装する必要があることを示す警告が表示されます。
生成されたコードブロックと、変数の宣言の間に空の行を数行追加します。このスペースに次のコードを追加します。このコードは、抽象メソッド 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;
}
Ctrl-Shift-I キーを押します。この操作で、StatusType クラスと Component クラスのインポート文が追加されます。StatusType の twitteroauth バージョンを選択します。Item.java を保存します。
これで、ユーザー名とステータスを JLabel と JTextPane に表示する Component オブジェクトを返す Item クラスが完成しました。次に、この Component を使用するように TwitterJFrame を変更します。
TwitterJFrame での Component の表示
Item.java で作成される Component オブジェクトを表示するには、TwitterJFrame 内の JList で、セルのレンダリングに Item.java を使用する必要があります。
TwitterJFrame に戻ります。デザインビューで JList を選択します。右クリックしてプロパティーを開きます。
model プロパティーを選択します。Ctrl-スペースキーを押します。カスタムプロパティーエディタが開き、デフォルトのテキストがリストに表示されます。
「jList1 の model プロパティーを設定」ドロップダウンメニューで「カスタムコード」を選択します。jLabel1.setModel のプロパティーを入力するテキストフィールドが表示されます。フィールドに「statusesListModel 」と入力し、「了解」をクリックします。
プロパティーダイアログで、「cellRenderer」を選択し、Ctrl- スペースキーを押します。カスタムプロパティーエディタが開きます。
「jList1 の cellRenderer プロパティーを設定」ドロップダウンメニューで「カスタムコード」を選択します。jList1.cellRenderer のプロパティーを入力するテキストフィールドが表示されます。「new Item() 」と入力し、「了解」をクリックします。
これで、クライアントアプリケーションは完成です。すべてのファイルを保存し、アプリケーションを実行します (プロジェクトノードを右クリックして「実行」を選択)。アプリケーションが開き、タイムラインのメッセージリストと、自分のステータスを示すフィールドが表示されます。
プロキシを経由した接続;
プロキシを経由してインターネットに接続している場合は、プロキシ設定を使用することを IDE と TwitterSwingClient プロジェクトの両方で設定する必要があります。
IDE を設定するには、「ツール」>「オプション」>「一般」を開きます。「プロキシ設定」セクションを探します。プロキシ設定を使用しない、システムのプロキシ設定を使用する、または手動でプロキシを設定することを選択できます。システムのプロキシ設定は、デフォルトのシステム Web ブラウザから取得されます。
TwitterSwingClient プロジェクトでは、HTTP プロトコルハンドラで使用されているプロキシを指定する必要があります。この方法は Java SE 6 のマニュアル で説明しています。プロキシは、仮想マシンに渡すオプションで指定します。NetBeans IDE では、「プロパティー」ダイアログでこれらのオプションを設定します。
TwitterSwingClient プロジェクトのプロキシを指定するには、次の手順に従います。
「プロジェクト」ウィンドウで TwitterSwingClient プロジェクトノードを右クリックし、「プロパティー」を選択します。「プロパティー」ダイアログが開きます。
「カテゴリ」ツリーで「実行」を選択します。実行のプロパティーが表示されます。
「VM オプション」フィールドに「-Dhttp.proxyHost=server -Dhttp.proxyPort=port 」と入力します。「server」と「port」は、実際のプロキシサーバーのホスト名とポートに置き換えます。
その他の課題
有益なアイデアをいくつか紹介します。
Twitter のユーザーアイコン (ブラウザ内) を変更し、もう一度クライアントを実行します。新しいアイコンは表示されましたか。
いくつかの機能を持つツールバーを JFrame に追加します。
関連項目
NetBeans IDE を使用した Web サービスの作成および使用、また GUI のデザインの詳細については、次のリソースを参照してください。
nbj2ee
@
netbeans.org
メーリングリスト に登録することによって、NetBeans IDE Java EE 開発機能に関するご意見やご提案を送信したり、サポートを受けたり、最新の開発情報を入手したりできます。