<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-33953139</id><updated>2011-11-28T08:43:40.607+09:00</updated><title type='text'>java畑</title><subtitle type='html'>javaプログラミングで試したことです。</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://javabatake.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33953139/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://javabatake.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>ugo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>3</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-33953139.post-116566426146426746</id><published>2006-12-09T20:37:00.000+09:00</published><updated>2006-12-10T01:34:34.216+09:00</updated><title type='text'>findComponet + Cashed Component</title><content type='html'>&lt;h3 class="my"&gt;はじめに&lt;/h3&gt;&lt;br /&gt;前回の記事では、findComponentをみてみました。&lt;br /&gt;GUI上のコンポーネントのアクセスを、検索し使用するという方法がfindComponentでした。&lt;br /&gt;ビルダーツールでコンポーネントで配置し、コンポーネントのプロパティに名前を設定します。検索する条件は名前のついたコンポーネントです。《意味のあるコンポーネントには名前がついている》というルールにしたがい、findComponentは対象となるコンポーネントをみつけだします。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/x/blogger/5724/2198/1600/605261/f-c1.png"&gt;図1 find foo&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/x/blogger/5724/2198/320/851135/f-c1.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;その際のGUI上のコンポーネントのアクセスをfindComponentで統一させしまうと、使用するたびに検索してしまうことです。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3 class="my"&gt;解決方法&lt;/h3&gt;&lt;br /&gt;単純な解決方法は、見つけ出したコンポーネントを連想配列(Map)に格納してしまうことです。&lt;br /&gt;Mapには、キーに《コンポーネントの名前》、値にコンポーネントを格納します。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/x/blogger/5724/2198/1600/763960/f-c2.png"&gt;図２&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/x/blogger/5724/2198/320/312790/f-c2.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;下記はユーテリティメソッドの実装です。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;toMapメソッド&lt;/div&gt;&lt;pre class="src"&gt;    public static Map&amp;lt;String, Component&amp;gt; toMap(Component[] components) {&lt;br /&gt;       Map&amp;lt;String, Component&amp;gt; map = new HashMap&amp;lt;String, Component&amp;gt;();&lt;br /&gt;       for (Component component : components) {&lt;br /&gt;           map.put(component.getName(), component);&lt;br /&gt;       }&lt;br /&gt;       return map;&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;この実装ですと、同じ名前を設定しているコンポーネントが複数ある場合は、正しく動作しません。&lt;br /&gt;つぎに、単純にキーを複数もてるMapを採用してみます。ひとつのキーで複数の値を扱うためにorg.apache.commons.collections.map.MultiValueMap(&lt;a href="#ref-20061208"&gt;参考文献&lt;/a&gt;)を採用してみます。MultiValueMapは値が一つでもListに値を格納してから返すので若干使いづらいかもしれません。&lt;br /&gt;&lt;div class="caption"&gt;MultiValueMap採用版&lt;/div&gt;&lt;pre class="src"&gt;//&lt;span style="color: rgb(0, 153, 0);"&gt;import org.apache.commons.collections.map.MultiValueMap&lt;/span&gt;;&lt;br /&gt;   public static &amp;lt;T extends Component&amp;gt; Map&amp;lt;String, List&amp;lt;T&amp;gt;&amp;gt; toMap(&lt;br /&gt;           Component[] components) {&lt;br /&gt;       Map&amp;lt;String, List&amp;lt;T&amp;gt;&amp;gt; map = new HashMap&amp;lt;String, List&amp;lt;T&amp;gt;&amp;gt;();&lt;br /&gt;       MultiValueMap multiValueMap = MultiValueMap.decorate(map);&lt;br /&gt;       for (Component component : components) {&lt;br /&gt;           multiValueMap.put(component.getName(), component);&lt;br /&gt;       }&lt;br /&gt;       return multiValueMap;&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;a name="ref-20061208"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3 class="my"&gt;参考文献(書籍、ハイパーリンク)&lt;/h3&gt;&lt;ul class="ref-all"&gt;&lt;br /&gt;&lt;li class="ref-all/"&gt;MultiValueMapは&lt;a href="http://jakarta.apache.org/commons/collections/"&gt;jakarta commons&lt;/a&gt;のコレクション操作のためのライブラリに含まれています。&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33953139-116566426146426746?l=javabatake.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabatake.blogspot.com/feeds/116566426146426746/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33953139&amp;postID=116566426146426746&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33953139/posts/default/116566426146426746'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33953139/posts/default/116566426146426746'/><link rel='alternate' type='text/html' href='http://javabatake.blogspot.com/2006/12/findcomponet-cashed-component.html' title='findComponet + Cashed Component'/><author><name>ugo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33953139.post-116015466704148421</id><published>2006-10-07T02:08:00.000+09:00</published><updated>2006-10-12T01:11:08.006+09:00</updated><title type='text'>findComponent</title><content type='html'>&lt;h3 class="my"&gt;はじめに&lt;/h3&gt;&lt;br /&gt;好みの問題かもしれませんが、ドラッグアンドドロップでGUIを作成するツールで生成できるソースコードにイベントを受信して動作するxxxListenerを記述したくありません。もしくは、生成されたソースコードの中に、外部のオブジェクトにバインドさせるコードを記述したくありません。ひょっとして、筆者がGUIビルダー(&lt;a href="#ref-20061007"&gt;参考文献&lt;/a&gt;)が期待している習熟度に達していないのかもしれません。&lt;br /&gt;&lt;br /&gt;何故そう思うのか、理由を考えてみました。まず、第一にGUIビルダーで部品を配置しながら、振る舞いの記述を意識するのは結構辛いということ。もうひとつの理由 は、UIオブジェクトに他のオブジェクトへの関心を埋め込みたくないからだということでした。ようするにマウスの操作だけでうまくできたソースコードに直接手でロジックを記述したくなく、UIオブジェクトにどうやって他のオブジェクトの参照を渡すか、もしくは他のオブジェクトの参照を取得するかをUIオブジェクトを作成中に考えたくないという訳です。&lt;br /&gt;&lt;br /&gt;&lt;blockquote class="my-comment"&gt;UIオブジェクトの再利用性を高めるためには、オブジェクト同士の関心の矢印を一方向に保つのがよいと思います。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5724/2198/1600/%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F.0.png"&gt;図1 関心の方向&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/5724/2198/320/%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F%3F.0.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3 class="my"&gt;最初の解決方法&lt;/h3&gt;&lt;br /&gt;では関心の方向を一方向で保つためには、どういった方法があるでしょうか。&lt;br /&gt;デザインされたUIには手でロジックを記述しないという方法をとることに注力してみます。&lt;br /&gt;Eclipse プラグインのVisual Editorでは配置したオブジェクトはgetterメソッドが自動生成されます。&lt;br /&gt;例えば下記のようにです。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;生成されたgetterメソッド&lt;/div&gt;&lt;pre class="src"&gt;    private JButton getJButton() {&lt;br /&gt;       if (jButton == null) {&lt;br /&gt;           jButton = new JButton();&lt;br /&gt;       }&lt;br /&gt;       return jButton;&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;デフォルトではアクセス修飾子がprivateなので外部からアクセスできませんので、これをpublicにすると定義したUIクラスの外部から配置したオブジェクトにアクセスできるようになります。&lt;br /&gt;&lt;br /&gt;この方法の欠点は部品(bean)を作成して他の部品の上に配置していくような作りにした場合、目的となるオブジェクトにアクセスするためのコード記述が長くなります(例 a.getB().getC().getD();)。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5724/2198/1600/%3F%3F%3F%3F%3F%3F.0.png"&gt;図２ beanのうえにbeanを配置&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/5724/2198/320/%3F%3F%3F%3F%3F%3F.0.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3 class="my"&gt;別の解決方法&lt;/h3&gt;&lt;br /&gt;ところで、javaでは、GUIオブジェクトはjava.awt.Componentから成り立っています。Componentはjava.awt.Container上に配置されることによって利用されます。&lt;br /&gt;Container上に配置されたComponentにアクセスする方法は、findComponentAt、getComponent、getComponents等のメソッドを使用してアクセスすることが可能です。Containerは配置された全てのComponentにComponent[] getComponents()を使用してアクセスできます。このデフォルトで用意された機能を利用して目的のオブジェクトにアクセスする方法を考えてみましょう。Componentはnameをフィールドとしてもちますが、このプロパティをオブジェクトを特定するために使用できそうです。&lt;br /&gt;&lt;br /&gt;アクセスしたいUIオブジェクト(Component)には、名前を付けるというのはルール（契約）とします。&lt;br /&gt;&lt;br /&gt;下記のようなユーティリティメソッドを用意します。&lt;br /&gt;&lt;div class="caption"&gt;ユーティリティメソッド:getAllComponentsIfNamePrepared&lt;/div&gt;&lt;pre class="src"&gt;    public static Component[] getAllComponentsIfNamePrepared(Container container) {&lt;br /&gt;       List&amp;lt;Component&amp;gt; arrayList = new ArrayList&amp;lt;Component&amp;gt;();&lt;br /&gt;&lt;br /&gt;       Component[] components = container.getComponents();&lt;br /&gt;       for (Component component : components) {&lt;br /&gt; &lt;br /&gt;           if (component instanceof Container) {&lt;br /&gt;               List&amp;lt;Component&amp;gt; list = Arrays&lt;br /&gt;                       .asList(getAllComponentsIfNamePrepared((Container) component));&lt;br /&gt;&lt;br /&gt;               if (!list.isEmpty()) {&lt;br /&gt;                   arrayList.addAll(list);&lt;br /&gt;               }&lt;br /&gt;&lt;br /&gt;           }&lt;br /&gt;&lt;br /&gt;           if (component.getName() != null &amp;amp;&amp; 0 &amp;lt; component.getName().length())&lt;br /&gt;               arrayList.add(component);&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       Object[] objects = arrayList.toArray();&lt;br /&gt;       int size = objects.length;&lt;br /&gt;       Component[] returnComponents = new Component[size];&lt;br /&gt;       System.arraycopy(objects, 0, returnComponents, 0, size);&lt;br /&gt;       return returnComponents;&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;このユーティリティメソッドは、Containerに含まれるをComponentを調べ、名前をもつComponentを配列にして返します。含まれるComponentがContainerであった場合には再帰的にgetAllComponentsIfNamePreparedを呼び出します。&lt;br /&gt;&lt;br /&gt;次に特定の名前をもつComponentを探すユーティリティメソッドです。&lt;br /&gt;&lt;div class="caption"&gt;ユーティリティメソッド:findComponent&lt;/div&gt;&lt;pre class="src"&gt;&lt;br /&gt;public static Component findComponent(String name, Container container) {&lt;br /&gt;       Component[] components = getAllComponentsIfNamePrepared(container);&lt;br /&gt;       for (Component component : components) {&lt;br /&gt;           if (component.getName() != null&lt;br /&gt;                   &amp;amp;&amp; component.getName().equals(name)) {&lt;br /&gt;               return component;&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       return null;&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;指定された名前と合致したComponentを返します。&lt;br /&gt;&lt;br /&gt;実際に使用してみます。UI部分をNetBeansで作成してみます。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/5724/2198/1600/jbtn_name.png"&gt;図３ NetBeans画面 nameの設定&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/5724/2198/320/jbtn_name.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;作成した画面のJButton,JTextFieldに名前を設定します。&lt;br /&gt;&lt;br /&gt;UI部分を呼び出すコードです。このサンプルコードは、ボタンをクリックしたら所定のテキストフィールドをの文字を書き換えるというものです。&lt;br /&gt;&lt;div class="caption"&gt;テストクラス:Main&lt;/div&gt;&lt;pre class="src"&gt;&lt;br /&gt;import java.awt.Component;&lt;br /&gt;import java.awt.Container;&lt;br /&gt;import java.awt.event.ActionEvent;&lt;br /&gt;import java.awt.event.ActionListener;&lt;br /&gt;import java.util.ArrayList;&lt;br /&gt;import java.util.Arrays;&lt;br /&gt;import java.util.List;&lt;br /&gt;&lt;br /&gt;import javax.swing.JButton;&lt;br /&gt;import javax.swing.JFrame;&lt;br /&gt;import javax.swing.JTextField;&lt;br /&gt;&lt;br /&gt;public class Main {&lt;br /&gt;&lt;br /&gt;   public static void main(String[] args) {&lt;br /&gt;       java.awt.EventQueue.invokeLater(new Runnable() {&lt;br /&gt;           public void run() {&lt;br /&gt;               final JFrame frame = new NewJFrame();&lt;br /&gt;               // JButtonを探しだす&lt;br /&gt;               &lt;span style="color: rgb(0, 153, 0);"&gt;JButton button = (JButton) findComponent("my.button", frame);&lt;/span&gt;&lt;br /&gt;               button.addActionListener(new ActionListener() {&lt;br /&gt;&lt;br /&gt;                   public void actionPerformed(ActionEvent e) {&lt;br /&gt;                       // JTextFieldを探しだす&lt;br /&gt;                       &lt;span style="color: rgb(0, 153, 0);"&gt;JTextField textField = (JTextField)findComponent("my.text7", frame);&lt;/span&gt;&lt;br /&gt;                       textField.setText("success");&lt;br /&gt;                   }&lt;br /&gt;&lt;br /&gt;               });&lt;br /&gt;               frame.setVisible(true);&lt;br /&gt;           }&lt;br /&gt;       });&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public static Component[] getAllComponentsIfNamePrepared(Container container) {&lt;br /&gt;       List&amp;lt;Component&amp;gt; arrayList = new ArrayList&amp;lt;Component&amp;gt;();&lt;br /&gt;&lt;br /&gt;       Component[] components = container.getComponents();&lt;br /&gt;       for (Component component : components) {&lt;br /&gt;           if (component instanceof Container) {&lt;br /&gt;               List&amp;lt;Component&amp;gt; list = Arrays&lt;br /&gt;                       .asList(getAllComponentsIfNamePrepared((Container) component));&lt;br /&gt;               if (!list.isEmpty()) {&lt;br /&gt;                   arrayList.addAll(list);&lt;br /&gt;               }&lt;br /&gt;           }&lt;br /&gt;           if (component.getName() != null &amp;amp;&amp; 0 &amp;lt; component.getName().length())&lt;br /&gt;               arrayList.add(component);&lt;br /&gt;       }&lt;br /&gt;       Object[] objects = arrayList.toArray();&lt;br /&gt;       int size = objects.length;&lt;br /&gt;       Component[] returnComponents = new Component[size];&lt;br /&gt;       System.arraycopy(objects, 0, returnComponents, 0, size);&lt;br /&gt;       return returnComponents;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   public static Component findComponent(String name, Container container) {&lt;br /&gt;       Component[] components = getAllComponentsIfNamePrepared(container);&lt;br /&gt;       for (Component component : components) {&lt;br /&gt;           if (component.getName() != null &amp;amp;&amp; component.getName().equals(name)) {&lt;br /&gt;               return component;&lt;br /&gt;           }&lt;br /&gt;       }&lt;br /&gt;       return null;&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=Z3J_ePZQwdc"&gt;動画１:一連の実行までの流れ、NetBeansでデザインし、コーディングはeclipseで行っている&lt;/a&gt;&lt;br /&gt;&lt;object width="425" height="350"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Z3J_ePZQwdc"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/Z3J_ePZQwdc" type="application/x-shockwave-flash" width="425" height="350"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3 class="my"&gt;まとめ&lt;/h3&gt;&lt;br /&gt;別の解決方法でしめした方法は、工夫次第ではいろいろな発展のさせ方があります。Componentの名前に名前規則をもたせることによって、正規表現等を利用して、取得したオブジェクトを選別することができます。またComponentの型によって選別する方法とあわせて使用すると手軽にComponentを絞り込むことができます。この方法は既にやられているオープンソースプロジェクトもあります(&lt;a href="#ref-20061007"&gt;参考文献&lt;/a&gt;)。こういった方法は特に、ライブラリ、フレームワークを使用せずとも実装できます。&lt;br /&gt;&lt;br /&gt;他のアイデアとしては、XPathのようなパス定義してみる。例えば、Containerから配置されたComponentを取得する場合container[@name='mycomponent']のような記述を利用する。Jakarta projectにあるJXPath(&lt;a href="#ref-20061007"&gt;参考文献&lt;/a&gt;)はXPathの記述をXMLだけでなく、beanの取得に適用しています。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a name="ref-20061007"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3 class="my"&gt;参考文献(書籍、ハイパーリンク)&lt;/h3&gt;&lt;ul class="ref-all"&gt;&lt;br /&gt;&lt;li class="ref-all/"&gt;&lt;a href="http://www.eclipse.org"&gt;elipse&lt;/a&gt;のVEプラグインはコンパクトなGUIビルダーではないでしょうか。&lt;/li&gt;&lt;li class="ref-all/"&gt;&lt;a href="http://www.netbeans.org/index.html"&gt;NetBeans&lt;/a&gt;標準搭載されているLayoutManagerは今後のjdkに標準になるようです。swingのGUIビルダーとして使いやすいです。&lt;/li&gt;&lt;li class="ref-all/"&gt;&lt;a href="http://jakarta.apache.org/commons/jxpath/users-guide.html#JavaBean%20Property%20Access"&gt;jakarta project JXPath&lt;/a&gt;XPath記述でXML以外の他のモデル(Java beans)にアクセスする方法を提供しています。&lt;br /&gt;&lt;/li&gt;&lt;li class="ref-all/"&gt;&lt;a href="http://www.programmers-friend.org/"&gt;Programmer's Friend&lt;/a&gt;javaプログラマのための使いやすいクラスを提供しています。&lt;a href="http://www.programmers-friend.org/apidoc/org/pf/swing/SwingUtil.html#findComponent(java.awt.Container,%20java.lang.Class,%20java.lang.String)"&gt;org.pf.swing.SwintgUtilのfindComponent&lt;/a&gt;は今回の記事と同じ発想です。&lt;br /&gt;&lt;/li&gt;&lt;li class="ref-all/"&gt;&lt;a href="http://code.google.com/p/quicklunch/"&gt;quicklunch goodies&lt;/a&gt;使用されているサンプルコードの一部を入手できます。subversionで管理されています。&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33953139-116015466704148421?l=javabatake.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabatake.blogspot.com/feeds/116015466704148421/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33953139&amp;postID=116015466704148421&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33953139/posts/default/116015466704148421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33953139/posts/default/116015466704148421'/><link rel='alternate' type='text/html' href='http://javabatake.blogspot.com/2006/10/findcomponent.html' title='findComponent'/><author><name>ugo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33953139.post-115834163166257715</id><published>2006-09-16T02:32:00.000+09:00</published><updated>2006-10-12T01:06:26.993+09:00</updated><title type='text'>ResourceInjector</title><content type='html'>Fuse(&lt;a href="#ref-all"&gt;参考文献&lt;/a&gt;)というオープンソースプロジェクトで開発されているResourceInjectorを使用して、JDK1.5で導入されたアノテーションと、UIコンポーネントでの設定情報の外部にだす方法をみていきたいと思います。&lt;br /&gt;&lt;br /&gt;&lt;h3 class="my"&gt;アノテーションについて&lt;/h3&gt;&lt;br /&gt;JDK1.5以降とそれ以前のjavaのバージョンとの間には深い溝があるようにみえます。&lt;br /&gt;JDK1.5から導入されたアノテーションの機能は、それ以前のJavaの開発と大きくスタイルが変わっていることをあわらしています。現在のたいていのjava開発はアプリケーションサーバ、フレームワークありきで進められますが、アノテーションはそれらの外部のツールによって読み取られ処理が行われます。&lt;br /&gt;&lt;br /&gt;&lt;blockquote class="my-comment"&gt;JDK1.5から導入されたジェネリックは正直面食らいました。というのも、javaソースをみた場合に、C++で書かれたコードなのか？と一瞬区別がつかなかったからです。JDK1.5の導入は開発者に学習を強制するように思えます。単に、APIが増えたというレベルではなく、言語仕様、文法レベルでの変更があるからです。それ以前と同じコーディングスタイルで、開発は可能ですが、苦痛を感じます。&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3 class="my"&gt;FuseのResourceInjectorとは&lt;/h3&gt;&lt;br /&gt;FuseはGUIプログラミングのための依存性の注入を使用した軽量なラブラリです。&lt;br /&gt;javaのGUIプログラミングでは、一般的に、コンポーネントの内部で各種リソースをロードするコードを記述していましたが、ResourceInjectorを使用することによって、その記述を省略することができます。&lt;br /&gt;&lt;br /&gt;&lt;blockquote class="my-comment"&gt;何故、ResourceInjector？かといいますと、SwingLabsのデモプロジェクトAerith(&lt;a href="#ref-all"&gt;参考文献&lt;/a&gt;)をハックしていて、ResourceInjectorが使用されているのに気がついたことからです。Aerithは今的なデモプロジェクトです。Web2.0時代にマッチしています。Flickr API(&lt;a href="#ref-all"&gt;参考文献&lt;/a&gt;)を利用してWebサービスからのデータの取得を行い、フェードイン、フェードアウトなどのエフェクトを使用していたり、リッチなクライアントを表現しています。内部ではjogl(参考文献)を使用していたりとこれからくるJavaクライアントの方向性をしめしていると思います。&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3 class="my"&gt;ResourceInjectorとアノテーションを組み合わせたコード&lt;/h3&gt;&lt;br /&gt;具体的にResourceInjectorとアノテーションを組み合わせたコードをみていきます。&lt;br /&gt;ここでは、UIコンポーネント使用せずに単純なデータクラスを使用します。&lt;br /&gt;&lt;br /&gt;プロパティファイルに定義した値をResourceInjectorを使用して適用します。&lt;br /&gt;&lt;br /&gt;&lt;div class="caption"&gt;data.properties&lt;/div&gt;&lt;pre class="src"&gt;&lt;br /&gt;Data.string1=just test&lt;br /&gt;Data.color1=#777777&lt;br /&gt;Data.font1=Default-BOLD-14&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;フィールド変数に@InjectedResourceというアノテーションをつけます。&lt;br /&gt;&lt;div class="caption"&gt;Data.java&lt;/div&gt;&lt;pre class="src"&gt;&lt;br /&gt;package sample_using_fuse;&lt;br /&gt;&lt;br /&gt;import java.awt.Color;&lt;br /&gt;import java.awt.Font;&lt;br /&gt;&lt;br /&gt;import org.apache.commons.lang.builder.ReflectionToStringBuilder;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;import org.jdesktop.fuse.InjectedResource;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;public class Data {&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;@InjectedResource&lt;/span&gt;&lt;br /&gt;Color color1;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;@InjectedResource&lt;/span&gt;&lt;br /&gt;Font font1;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;@InjectedResource&lt;/span&gt;&lt;br /&gt;String string1;&lt;br /&gt;&lt;br /&gt;public String toString() {&lt;br /&gt; return ReflectionToStringBuilder.toString(this);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;テスト実行クラスです。&lt;br /&gt;実行するとプロパティファイルに定義した内容がDataクラスに適用されていることがわかります。ResourceIndectorにSwingModlueを渡すことによって、Color、Fontが変換されています。&lt;br /&gt;&lt;div class="caption"&gt;TestMainForData.java&lt;/div&gt;&lt;pre class="src"&gt;&lt;br /&gt;package sample_using_fuse;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;import org.jdesktop.fuse.ResourceInjector;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 102, 0); font-weight: bold;"&gt;import org.jdesktop.fuse.swing.SwingModule;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;public abstract class TestMainForData {&lt;br /&gt;&lt;br /&gt;public static void main(String[] args) {&lt;br /&gt; &lt;br /&gt; Data data = new Data();&lt;br /&gt; ResourceInjector.addModule(new SwingModule());&lt;br /&gt;        ResourceInjector.get().load(Data.class,&lt;br /&gt;                "/sample_using_fuse/data.properties");&lt;br /&gt;        ResourceInjector.get().inject(data);&lt;br /&gt;       &lt;br /&gt;        System.out.println(data);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;h3 class="my"&gt;まとめ&lt;/h3&gt;&lt;br /&gt;実際にはResourceInjectorをUIコンポーネントに使用する際には、工夫が必要となるでしょう。JDK1.5から導入されたアノテーションをクライアントサイドに適用するという試みは、もっとなされてよいでしょう。&lt;br /&gt;&lt;a name="ref-all"&gt;&lt;/a&gt;&lt;br /&gt;&lt;h3 class="my"&gt;参考文献(書籍、ハイパーリンク)&lt;/h3&gt;&lt;br /&gt;&lt;ul class="ref-all"&gt;&lt;li class="ref-all/"&gt;&lt;a href="http://swinglabs.org/index.jsp"&gt;SwingLabs&lt;/a&gt;プロジェクトホームページ&lt;br /&gt;&lt;/li&gt;&lt;li class="ref-all/"&gt;&lt;a href="https://aerith.dev.java.net/"&gt;aerith&lt;/a&gt;java.netに開設されているプロジェクトページ&lt;br /&gt;&lt;/li&gt;&lt;li class="ref-all/"&gt;&lt;a href="https://fuse.dev.java.net/"&gt;Fuse&lt;/a&gt;java.netに開設されているプロジェクトページ&lt;br /&gt;&lt;/li&gt;&lt;li class="ref-all/"&gt;&lt;a href="https://fuse.dev.java.net/api/org/jdesktop/fuse/ResourceInjector.html"&gt;API&lt;/a&gt;FuseのResourceInjectorのjavadocです。&lt;br /&gt;&lt;/li&gt;&lt;li class="ref-all/"&gt;&lt;a href="http://journal.mycom.co.jp/news/2006/03/14/345.html"&gt;ResouceInjectorの紹介記事&lt;/a&gt;簡潔に説明されています。&lt;br /&gt;&lt;/li&gt;&lt;li class="ref-all/"&gt;&lt;a href="http://www.flickr.com//"&gt;flickr&lt;/a&gt;海外で運営されている写真アップロードサイト、yahoo.comのアカウントが必要です。&lt;br /&gt;&lt;/li&gt;&lt;li class="ref-all/"&gt;&lt;a href="http://www.amazon.co.jp/gp/redirect.html?ie=UTF8&amp;location=http%3A%2F%2Fwww.amazon.co.jp%2Fgp%2Fproduct%2F4894716879%2Fref%3Dsr%5F11%5F1%3Fie%3DUTF8&amp;amp;tag=ugougo0d-22&amp;linkCode=ur2&amp;amp;camp=247&amp;creative=1211"&gt;Java2 Standard Edition 5.0 Tiger&lt;/a&gt;&lt;img src="http://www.assoc-amazon.jp/e/ir?t=ugougo0d-22&amp;amp;amp;l=ur2&amp;o=9" alt="" style="border: medium none  ! important; margin: 0px ! important;" border="0" height="1" width="1" /&gt;書籍、簡潔にJDK1.5から導入された機能等をまとめられています。&lt;br /&gt;&lt;/li&gt;&lt;li class="ref-all/"&gt;&lt;a href="http://code.google.com/p/quicklunch/"&gt;quicklunch goodies&lt;/a&gt;使用されている&lt;a href="http://quicklunch.googlecode.com/svn/trunk/quicklunch_alpha/src/javabatake/java/sample_using_fuse/"&gt;サンプルコード&lt;/a&gt;を入手できます。subversionで管理されています。&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/33953139-115834163166257715?l=javabatake.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javabatake.blogspot.com/feeds/115834163166257715/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=33953139&amp;postID=115834163166257715&amp;isPopup=true' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33953139/posts/default/115834163166257715'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33953139/posts/default/115834163166257715'/><link rel='alternate' type='text/html' href='http://javabatake.blogspot.com/2006/09/resourceinjector.html' title='ResourceInjector'/><author><name>ugo</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
