1

複数のルート ノードがあっても JTree を作成し (これは初めての JTree だったので、これは非常に困難でした)、さらに一歩先に進む準備ができていました (と思っていました)。セルレンダラー。

すべてのノードに 1 つのアイコンを設定しようとしましたが、うまくいきました。今、私はそれがどのような種類のノードであるか (葉と枝だけでなく) を確認しようとしており、必要な画像のファイル名の文字列を作成しています。isKlas()現在のところ、常に true を返すため、klas_fold.png または klas_unfold.png である必要があります。しかし、getTreeCellRendererComponent()ファイルパスが印刷されず、アイコンも変更されないため、部分的にしか実行されません。常にデフォルトです!

これが私のコードです:

import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;

public class RATree extends JTree {

    private static final long serialVersionUID = -3855798479619346917L;

    public RATree(Object[] top) {
        super(top);
        MyRenderer renderer = new MyRenderer();
        this.setCellRenderer(renderer);

        setBorder(BorderFactory.createRaisedBevelBorder());
    }

    protected ImageIcon createImageIcon(String path) {

        java.net.URL imgURL = getClass().getResource(path);
        if (imgURL != null) {
            return new ImageIcon(imgURL);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }

    class MyRenderer extends DefaultTreeCellRenderer {

        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            TreeItem node;
            String fileName = "";
            super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
            try {
                node = (TreeItem) value;
            }
            catch (ClassCastException ex)
            {
                ex.printStackTrace();
                return this;
            }

            if(node.isKlas()) {
                fileName += "klas_";
            }

            if(expanded) {
                fileName += "unfold.png";
                this.setIcon(createImageIcon("../bin/" + fileName));
            }
            else {
                fileName += "fold.png";
                this.setIcon(createImageIcon("../bin/" + fileName));
            }

            System.out.println("fileName: " + fileName); //Doesn't get executed, or at least, I can't see it.
            return this;
        }

    }
    public static void main(String[] args) {
        JFrame f = new JFrame("Short, Self Contained, Correct (Compilable), Example");
        Object[] root = {new TreeItem("name", "someURL"), new TreeItem("name", "someUrl")};
        f.add(new RATree(root));
        f.setSize(100,100);
        f.setVisible(true);
    }
}

はい、それは内部クラスです。

ありがとう!

編集:

物事を台無しにしたのは ClassCastException であることがわかりました。しかし、これは奇妙です。なぜなら、次のように Tree を初期化するからです: new JTree({new TreeItem("params"), new TreeItem("params")});. だから私はオブジェクトからツリーアイテムにそれらをキャストすることができるはずですか? (TreeItem は私のクラスの 1 つです。DefaultMutableTreeNode を拡張します)。

4

3 に答える 3

4

TreeModel.nodeChanged(node);1)値が変更されたことを TreeModel に通知しようとしましたか?

2)Icon(s)内部で再作成するのではなく、TreeModel に直接配置するTreeCellRenderer

3) JTree( JTableJListおよびJListfrom ) は、Renderer for JTableJComboBoxと同じ概念を共有します。

4)ツリーの表示のカスタマイズをお読みください。

5)ここここに例

于 2012-05-08T21:07:47.030 に答える
4

私はそれを自分で解決しました!Object valueJTree に配置した TreeItemだと思っていましたが、別のものでした。これを行うことで TreeItem を取得しました (mKorbel が提供するツリーの表示リンクのカスタマイズのように):

TreeItem node = (TreeItem) ((DefaultMutableTreeNode)value).getUserObject();
于 2012-05-08T21:17:16.323 に答える
2

try-catchの部分を理解してくれてうれしいです。この問題を解決するには、DefaultTreeModel に TreeItem のインスタンス以外のものを提供していないことを確認してください。この行System.out.println(value.getClass())を catch ブロックに入れる必要があります。

また、ツリー ノードが展開または折りたたまれるたびに新しいアイコンを作成するのではなく、アイコンの単一のインスタンスを作成することを検討する必要があります。

于 2012-05-08T21:09:10.790 に答える