4

以下に示すように、CustomCellRendererを使用してJTreeのノードを表示し、ノードで画像を表示しています:-

class CustomTreeCellRenderer extends DefaultTreeCellRenderer{

    public Component getTreeCellRendererComponent(JTree tree,
        Object value, boolean selected, boolean expanded,
        boolean leaf, int row, boolean hasFocus){

        super.getTreeCellRendererComponent(tree, value,
        selected, expanded, leaf, row, hasFocus);

        JLabel label = (JLabel) this ;

        label.setIcon( new ImageIcon("white.png") ) ;

        return this;
    }
}

私の要件は、何らかの外部アクションでノードのイメージを変更することです。JTree のモデルをリロードしようとしていますが、以下に示すように機能しません:-

public void actionPerformed(ActionEvent ae) {

        DefaultTreeModel model = (DefaultTreeModel) tree.getModel() ;

        JLabel label = (JLabel) tree.getCellRenderer() ;
        System.out.println(label.getIcon()); //displaying white.png

        label.setIcon( new ImageIcon("black.gif") ) ;


        model.reload() ;
    }

どこが間違っているのですか??????

4

2 に答える 2

1

アイコンをレンダラー クラスにフィールドとして追加します。

このフィールドの値を変更して、JTree を再描画します。

class CustomTreeCellRenderer extends DefaultTreeCellRenderer{


    ImageIcon rendererIcon;


    public void setRendererIcon(ImageIcon myIcon){
         this.rendererIcon = myIcon;
    };


    public Component getTreeCellRendererComponent(JTree tree,
        Object value, boolean selected, boolean expanded,
        boolean leaf, int row, boolean hasFocus){

        super.getTreeCellRendererComponent(tree, value,
        selected, expanded, leaf, row, hasFocus);

        JLabel label = (JLabel) this ;

        label.setIcon( rendererIcon ) ;

        return this;
    }
}

編集:説明

あなたの場合、モデルを変更しても無駄です。各ノードの表示に使用されるアイコンは、レンダラーの一部です。

JTree のレンダラー オブジェクトは、強制的にJComponent. JComponentコードが を呼び出すときにを提供するオブジェクトである必要がありますgetTreeCellRendererComponent

DefaultTreeCellRendererあなたの場合、 getCellRenderer() の JLabel へのキャストは、のデフォルトの実装がの拡張であるため、単なる運ですJLabel

実際、レンダラーがそれ自体で setIcon を呼び出したので、 getIcon メソッドがレンダラーに配置した最後のアイコンを提供するのは正常です。

完全なコードの動作:

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultTreeCellRenderer;

public class TestJTree {

    private static ImageIcon iconWhite = new ImageIcon("white.jpg");

    private static ImageIcon iconBlack = new ImageIcon("black.jpg");;

    public static void main(String[] args) {
        TestJTree me = new TestJTree();
        me.process();
    }

    private void process() {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                initGui();

            }

        });

    }

    protected void initGui() {
        JFrame frame = new JFrame("Test JTree");
        frame.setContentPane(new JPanel(new BorderLayout()));

        final JTree tree = new JTree();
        frame.getContentPane().add(tree);

        final CustomTreeCellRenderer renderer = new CustomTreeCellRenderer();
        renderer.setRendererIcon(iconWhite);
        tree.setCellRenderer(renderer);

        JPanel panelButtons = new JPanel();

        JButton buttonWhite = new JButton("");
        buttonWhite.setIcon(iconWhite);
        JButton buttonBlack = new JButton("");
        buttonBlack.setIcon(iconBlack);

        buttonBlack.addActionListener(new ActionListener(){

            public void actionPerformed(ActionEvent e) {
                renderer.setRendererIcon(iconBlack);
                tree.repaint();
            }

        });

        panelButtons.add(buttonBlack);
        panelButtons.add(buttonWhite);
        frame.getContentPane().add(panelButtons,BorderLayout.SOUTH);

        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(500,500);
        frame.setVisible(true);


    }

    @SuppressWarnings("serial")
    private static class CustomTreeCellRenderer extends DefaultTreeCellRenderer{


        ImageIcon rendererIcon;


        public void setRendererIcon(ImageIcon myIcon){
             this.rendererIcon = myIcon;
        };


        public Component getTreeCellRendererComponent(JTree tree,
            Object value, boolean selected, boolean expanded,
            boolean leaf, int row, boolean hasFocus){

            Component ret = super.getTreeCellRendererComponent(tree, value,
            selected, expanded, leaf, row, hasFocus);

            JLabel label = (JLabel) ret ;

            label.setIcon( rendererIcon ) ;

            return ret;
        }
    }
}
于 2010-02-04T13:56:17.293 に答える
1

いくつかのポイント:

  1. のようなメソッドでテーブルからレンダラーを取得してactionPerformed変更することは一般的ではありません。レンダラーは共有されているため、そのレンダラーを使用する列内のすべてのセルに影響することに注意してください。
  2. 中にレンダラーIconインスタンスで画面。actionPerformedgetTreeCellRendererComponent

あなたが持っているオプションは、actionPerformedメソッドでモデルの状態を設定することです。次に、その中からgetTreeCellRendererComponentアイコンを表示するためにモデルをクエリできます。

例えば:

public void actionPerformed(ActionEvent ae) {

    MyCustomTreeModel model = (MyCustomTreeModel) tree.getModel() ;
    ...
    model.setMyState(state); //set the state based on the action
}

レンダラーで:

public Component getTreeCellRendererComponent(JTree tree,
    Object value, boolean selected, boolean expanded,
    boolean leaf, int row, boolean hasFocus)
{
     MyCustomTreeModel model = (MyCustomTreeModel) tree.getModel();
     ....
     setIcon(model.getMyIconBasedOnTheStateISetInActionPerformed());
     return this;    
}
于 2010-02-04T14:18:52.727 に答える