Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

JTreeに追加した項目となぜか一致しないのですが。

少しの間やっていませんでしたが、ソースからクラスやメソッドなどの定義を取り出したいと言っていた人です。

自分が解析したいソースたちに対してクラスやメソッドの定義を抽出することはできたので、それをJTreeに追加してツリー表示させています。
それと同時にその定義と位置をセットでHashTable<String,Integer>に保存していて、JTreeがクリックされたらその定義の位置へソースを表示しているTextAreaのキャレットを移動させようとしています。
ですが、クリックしたときにNullPointerと言われてしまいます。

以下はKannsuuNodeクラスにzikkouメソッドとhyouziメソッドがある時にJTreeのhyouziメソッドのところをクリックしたときの例です。
JTreeから取得した文字列とHashTableにキーとして登録されている文字列とを比較してみたのですが、同じはずのところでも違うと言われてしまいます。

JTreeもHashTableも同じ文字列を登録しているはずなのですが、なぜでしょうか?

public void hyouzi(String t)
public class KansuuNode extends Hashtable<String,ProgramNode>
public void hyouzi(String t)!=public class KansuuNode extends Hashtable<String,ProgramNode>
public void hyouzi(String t)
public void hyouzi(String t)!=public void hyouzi(String t)
public void zikkou(String name)
public void hyouzi(String t)!=public void zikkou(String name)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at compiler_editor.EditorList$MouseAdp.mouseClicked(EditorList.java:155)
    at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:270)
    at java.awt.Component.processMouseEvent(Component.java:6530)
    at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
    at java.awt.Component.processEvent(Component.java:6292)
    at java.awt.Container.processEvent(Container.java:2234)
    at java.awt.Component.dispatchEventImpl(Component.java:4883)
    at java.awt.Container.dispatchEventImpl(Container.java:2292)
    at java.awt.Component.dispatchEvent(Component.java:4705)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4898)
    at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4542)
    at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4462)
    at java.awt.Container.dispatchEventImpl(Container.java:2278)
    at java.awt.Window.dispatchEventImpl(Window.java:2739)
    at java.awt.Component.dispatchEvent(Component.java:4705)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)
    at java.awt.EventQueue.access$400(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:697)
    at java.awt.EventQueue$3.run(EventQueue.java:691)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue$4.run(EventQueue.java:719)
    at java.awt.EventQueue$4.run(EventQueue.java:717)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

4

回答

94114

閲覧

4件の回答

評価

0

「同じはず」とおっしゃっていますが、「〜のはず」は
大抵落とし穴です。実際にequalsで比較した結果をデバ
ッグプリントされているのでしたら、「同じではない」
のが事実でしょう。もし同じでないことがプログラムの
意図したことではないならequalsがなぜfalseを返すの
かを具体的に調べれば解決につながるかと思います。
(余計な空白文字がどちらか一方に入っていたといった
落ちのような予感はしますが・・・)

いずれにせよ、他人が開発したライブラリの中で例外が
発生しているなら別ですが、上のスタックトレースでは
あなた自身が作成したメソッドの具体的な行番号までで
ていますので少なくともそのコードを提示すべきです。
また、質問する前にその行(EditorList.java:155)をば
らばらに分解してでも具体的にどのメソッドのreturn値
なり、どの計算式の結果が意図したものと違うのかを調
べて質問すればより答えが早く見つかると思います。

評価

0

155行目というのは下のほうのclass MouseAdp extends MouseAdapterにあるsorce.setCaretPosition(list.get(path.getLastPathComponent()));です。

JTreeとHashTableへの追加は以下のようにやっています。
DefaultMutableTreeNode subtree = new DefaultMutableTreeNode(codes.get(n).substring(codes.get(n).lastIndexOf("\t")+1, codes.get(n).indexOf("{")));
list.put(codes.get(n).substring(codes.get(n).lastIndexOf("\t")+1, codes.get(n).indexOf("{")), n);
私が見る限り同じ文字列だと思うのですが、    何が違うんでしょう?

以下抽出・追加・クリック処理に関係するメソッドだけ抜き出してみました。
void nodeList(){
    String[] str=sorce.getText().split("\n");
    Vector<String> codes=new Vector<String>();
    for(int n=0;n<str.length;n++){
        codes.add(str[n]);
    }
    Vector<Integer> tab=new Vector<Integer>();
    DefaultMutableTreeNode top=null;
    for(int n=0;n<codes.size();n++){
        if(codes.get(n).indexOf("class")!=-1){
            tab.add(codes.get(n).lastIndexOf("\t"));
            top = new DefaultMutableTreeNode(codes.get(n).substring(0, codes.get(n).indexOf("{")));
            list.put(codes.get(n).substring(0, codes.get(n).indexOf("{")), n);
            codes.remove(n);
            n--;
            createNodes(tab, top, codes);
            break;
        }
        else{
            codes.remove(n);
            n--;
        }
    }
    tree=new JTree(top);
    tree.addMouseListener(new MouseAdp());
}

private Vector<String> createNodes(Vector<Integer> tab,DefaultMutableTreeNode tree, Vector<String> codes) {
    for(int n=0;n<codes.size();n++){
        if(codes.get(n).indexOf("class")!=-1){
            tab.add(codes.get(n).lastIndexOf("\t"));
            DefaultMutableTreeNode subtree = new DefaultMutableTreeNode(codes.get(n).substring(codes.get(n).lastIndexOf("\t")+1, codes.get(n).indexOf("{")));
            list.put(codes.get(n).substring(codes.get(n).lastIndexOf("\t")+1, codes.get(n).indexOf("{")), n);
            codes.remove(n);
            n--;
            codes=createNodes(tab, subtree, codes);
            tree.add(subtree);
        }
        else if(codes.get(n).indexOf("{")!=-1 && codes.get(n).indexOf("else")==-1 &&
                codes.get(n).substring(codes.get(n).lastIndexOf("\t"), codes.get(n).indexOf("(")).indexOf(" ")!=-1){
            tab.add(codes.get(n).lastIndexOf("\t"));
            DefaultMutableTreeNode subtree = new DefaultMutableTreeNode(codes.get(n).substring(codes.get(n).lastIndexOf("\t")+1, codes.get(n).indexOf("{")));
            list.put(codes.get(n).substring(codes.get(n).lastIndexOf("\t")+1, codes.get(n).indexOf("{")), n);
            codes.remove(n);
            n--;
            codes=createNodes(tab, subtree, codes);
            tree.add(subtree);
        }
        else if(tab.size()>0 && (codes.get(n).lastIndexOf("}")-1)==tab.get(tab.size()-1)){
            tab.remove(tab.size()-1);
            codes.remove(n);
            n--;
            return codes;
        }
        else{
            codes.remove(n);
            n--;
        }
    }
    return null;
}

class MouseAdp extends MouseAdapter{
    TreePath path;

    @Override
    public void mouseClicked(MouseEvent e) {
        path=tree.getPathForLocation(e.getX(), e.getY());
        if (SwingUtilities.isLeftMouseButton(e)) {
            System.out.println(path.getLastPathComponent());
            Enumeration en = list.keys();
            while(en.hasMoreElements()){
                Object k = en.nextElement();
                System.out.println(k);
                if(path.getLastPathComponent().equals(k)){
                    System.out.println(path.getLastPathComponent()+"=="+k);
                }
                else{
                    System.out.println(path.getLastPathComponent()+"!="+k);
                }
            }
            sorce.setCaretPosition(list.get(path.getLastPathComponent()));
            sorce.requestFocusInWindow();
        }
    }
}

評価

0

なるほど一致していないのは確かですね。
getLastPathComponent()の結果はStringではなく、この
場合はDefaultMutableTreeNodeです。だから一致しませ
ん。

単にデバッグプリントしてみても型の違いはわからない
のです。Javaはどんな型であってもString型と加算する
とコンパイラが自動的にtoString()で文字列に変換して
から連結してしまいますのでメソッドの戻り値の型が期
待どおりのものなのかはきちんと把握していないと罠に
落ちることがありますね。

閑話休題・・・

蛇足ですが、折角equalsで一致を確認するところまでは
やっておられたので、さらになぜ一致しないのかを、調
べることを一文字ずつ確認するデバッグコードを入れる
なりしていれば気づけたかと思います。ただ、ひたすら
標準出力へのデバッグ出力に頼るデバッグは限界がある
と思えるのでIDEなりコンソールでも使えるデバッガな
りを活用することをお勧めします。(多分お使いでない
ように思ったので)

評価

0

eclipseを使っていて付属のデバッグ機能を使ってデバッグをすることもありますが、必要な情報だけ見るには標準出力を使う方が楽だと考えることもあります。
4.3時代に以下の不具合(?)に合ったこともありますし。

Javaの道>掲示板(eclipseを用いたデバッグでの再開とステップインについて)
http://www.javaroad.jp/bbs/answer.jsp?q_id=20140528162828940

今は4.4を使っていて、今のところそのようなことにはなっていません。
今回についてはeclipseのデバッグを使うということをすっかり考えていませんでした。

eclipseでもgetLastPathComponent()の戻り値はObjectって書いてありましたね。
そこを調べるのを忘れてました。
出力のときはObjectは勝手にStringにされるから違うように見えないけれど、本体はObjectだからHashTableのStringとは一致しないわけですよね。
getLastPathComponent()にtoString()を付けて比較したらちゃんと一致しました。
ありがとうございました。

今度オブジェクト型を使った比較するときはきちんと型について調べることにします。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。