Динамическое изменение образа узла JTree - PullRequest
4 голосов
/ 04 февраля 2010

Я использую 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() ;
    }

Где я делаю неправильно ??????

Ответы [ 2 ]

1 голос
/ 04 февраля 2010

пара баллов:

  1. захват метода визуализации из таблицы методом, подобным actionPerformed, и изменение его не является обычной практикой. Обратите внимание, что средство визуализации является общим, поэтому вы будете влиять на все ячейки в столбце, которые используют это средство визуализации
  2. , даже если вы установили Icon на экземпляре средства визуализации во время actionPerformed, к средству визуализации всегда обращаются для рисования с помощью метода getTreeCellRendererComponent, и в этом случае вы всегда устанавливаете значок «white.png», так что вы никогда не получите "black.gif" для отображения.

У вас есть возможность установить состояние модели в вашем методе 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;    
}
1 голос
/ 04 февраля 2010

Добавьте свой Icon в класс визуализации в виде поля.

Измените значение этого поля и перекрасьте 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.

В вашем случае приведение getCellRenderer () к JLabel - просто удача, потому что реализация по умолчанию DefaultTreeCellRenderer является расширением 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;
        }
    }
}
...