Проблема с ListCellRenderer
От: Zelgadis Россия  
Дата: 19.03.07 21:35
Оценка:
Здравствуйте возникла такая проблема с работой списка с переопределённым рендерером:
Первоначально рендерер был определён таким образом:

public class PhotoListCellRenderer  implements ListCellRenderer{
    public PhotoListCellRenderer(){

    }
    
    public Component getListCellRendererComponent(
            JList list,
            Object value,
            int index,
            boolean isSelected,
            boolean cellHasFocus) {
        PhotoPanel panel = new PhotoPanel();
//        Установка цветов: фона и переднего плана в элементе
        if (isSelected) {
            panel.setBackground(list.getSelectionBackground());
            panel.setForeground(list.getSelectionForeground());
        } else {
            panel.setBackground(list.getBackground());
            panel.setForeground(list.getForeground());
        }

        /*
        *    Помещение thumbnail'a на компонент. После этого происходит возврат компонента
        *   для его отображения
        */
        ProgressImageWrapper wrapper = (ProgressImageWrapper) value;

        Image thumbnail = wrapper.getImage();
        panel.setImage(thumbnail);
        return panel;
    }


где класс PhotoPanel такой:

public class PhotoPanel extends javax.swing.JPanel {

    Logger log = Logger.getLogger(PhotoPanel.class);
    //Типы отрисовки изображений.
    public static final int FULL_SIZE = 0;
    public static final int FIT_SIZE = 1;

    /**
     * Creates new form MyPhotoPanel
     */
    public PhotoPanel() {
        initComponents();
        fitToPanel();
        imagePositionX = xOffset;
        imagePositionY = yOffset;
    }
    
    private void initComponents() {
        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
                layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                        .add(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
                layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                        .add(0, 300, Short.MAX_VALUE)
        );
    }// </editor-fold>//GEN-END:initComponents


    // Variables declaration - do not modify//GEN-BEGIN:variables
    // End of variables declaration//GEN-END:variables
    public void setImage(Image image) {
        this.image = image;
        this.repaint();
    }


    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;      
        fitToPanel();
        calculatePosition();

        //g2.setColor(new Color(r%250,0,0));
        //g2.fillRect(0,0,this.getWidth(),this.getHeight());
        g2.drawImage(image, getImagePositionX(), getImagePositionY(),
                getImageWidth(), getImageHeight(),
                null);
        //r+=50;

    }
    //int r=0;

    /**
     * Метод устанавливающий размеры под размер панели
     */
    private void fitToPanel() {
        //....
    }


    ;

    private void calculatePosition() {
        //...
    }
    //Реализация геттеров....
    //Переменные....
}

Но недавно возникла необходимость в расширении функциональности и добавлении прогресс бара.
Был создан класс (близкий к декоратору) следующего содержания:

public class PhotoProgressPanel extends JPanel{
    PhotoPanel panel;
    JProgressBar bar;

    public PhotoProgressPanel() {
        initComponents();
    }   

    public void setProgressBar(JProgressBar progressBar) {
        this.remove(bar);
        bar = progressBar;
        bar.setPreferredSize(new Dimension(this.getWidth() - 20, 6));
        addBar();
    }

    private void initComponents(int zoomType) {
        this.setLayout(new GridBagLayout());
        panel = new PhotoPanel(zoomType);
        bar = new JProgressBar();
        this.add(panel, new GBC(0, 0).setWeight(20, 20).
                setFill(GBC.BOTH));
        addBar();
    }

    private void addBar() {
        this.add(bar, new GBC(0, 1).setWeight(0, 20).setFill(GBC.HORIZONTAL));
    }

     //Делегирующие методы...
}

(GBC — класс унаследованный от GridBagConstraints, взятый из книги Хорстмана CoreJava том 1)

и в классе PhotoListCellRenderer строчка

PhotoPanel panel = new PhotoPanel();

была заменена на
PhotoProgressPanel panel = new PhotoProgressPanel();

В результате в JList'e отображаются пустые ячейки, и нет никакого намека на изображение или прогресс бар.

Хотелось бы узнать в чём может быть проблема, может быть я что то не переопределил или проблемы с компоновкой панели?.....
P.S. при тестовых испытаниях PhotoProgressPanel была перемещена проста на панельку но также никакого эффекта.
Re: Проблема с ListCellRenderer
От: JSerge Россия  
Дата: 22.03.07 16:50
Оценка: 1 (1)
Здравствуйте, Zelgadis, Вы писали:

Z>Первоначально рендерер был определён таким образом:


Z>[java]

Z>public class PhotoListCellRenderer implements ListCellRenderer{
Z>
Z> public Component getListCellRendererComponent(
Z> JList list,
Z> Object value,
Z> int index,
Z> boolean isSelected,
Z> boolean cellHasFocus) {
Z> PhotoPanel panel = new PhotoPanel();
Z> ......
Z> return panel;
Z> }


Так нельзя renderer'ы писать. Предполагается, что renderer'ы вызываются ОЧЕНЬ часто. и их надо переиспользовать. А у вас для отрисовки каждой ячейки создается новый instance класса. Так нельзя.
Re[2]: Проблема с ListCellRenderer
От: Zelgadis Россия  
Дата: 22.03.07 19:11
Оценка:
Здравствуйте, JSerge, Вы писали:

JS>Так нельзя renderer'ы писать. Предполагается, что renderer'ы вызываются ОЧЕНЬ часто. и их надо переиспользовать. А у вас для отрисовки каждой ячейки создается новый instance класса. Так нельзя.


Я понимаю. Изначально у меня было как положено: наследование нужного компонента, и возвращение себя. Просто послушался не вполне в данном вопросе компетентных людей и решил попробовать так. Но не в этом проблема. Даже при помощи нормального способа компоненты в списке не отображаются. Точнее не совсем:
При замене GridBagLayout'a на BorderLayout элементы в списке начали появляться, но только при смене LookAndFeel'a и при сворачивании и разворачивании компонента. Но этож никуда не годится... Самое плохое то что я никак не могу понять в чём проблема. Быть может из-за того что прогресс бар обновляется слишком часто (а их примерно 3-4 штуки отображается) и всё это не может разом отрисоваться?...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.